Safeguard
Developer Tools•

How does a git dependency in Cargo.lock show up in an SBOM?

Cargo.lock pins a git dependency to an exact commit. How to carry that commit into an SBOM, and what to check when a crate does not come from a registry.

Safeguard Security Team
7 min read

Cargo.lock records the exact revision of a git dependency in its source field, even when Cargo.toml names just the repository. Your SBOM should carry that commit as the component's version evidence and mark the source as a git repository, not a registry, so readers know no release was published.

What the lockfile says

The Cargo documentation explains that Cargo.toml describes dependencies in a broad sense and is written by you, while Cargo.lock contains exact information about them and is maintained by Cargo. Its example shows a package entry for regex with a version and a source value that begins with git+ followed by the repository URL and a hash after a pound sign. The docs say the file includes the exact revision used to build, which lets someone else build with the same SHA even though Cargo.toml did not specify it.

The docs also say that when in doubt you should check Cargo.lock into version control, and that cargo update refreshes dependencies, either all or one named crate.

Why this matters for an SBOM

A crate from a registry has a name and a released version, and advisories are matched on those. A git dependency has a version string in the lockfile too, but the source is a repository at a commit. That commit may be ahead of, behind or unrelated to any release.

Source typeIdentityAdvisory matching
Registry crateName and versionDirect
Git dependencyName, version string, commitNeeds a human check

If your SBOM just lists name and version, a reader cannot tell the difference, and may match advisories to the wrong code or to none.

Steps

  1. Search the lockfile for source values that start with git+.
  2. For each, record the repository URL and the full commit hash.
  3. Record the package version string from the same entry.
  4. Put the commit in an external reference or a note field, and say the component is not from a registry.
  5. Check upstream: is this commit on a tagged release, or a branch tip? Write that down.
  6. Decide whether the dependency should be moved to a released version.

Policy ideas

Some teams allow git dependencies just with a ticket, because they bypass release processes and can disappear if a repository is deleted or rewritten. Others require an owner and an expiry date. A short review at each lockfile change keeps the list honest.

Because Cargo.lock is machine maintained, do not hand edit it. If a commit needs to change, update through Cargo and review the diff.

A note on libraries

The Cargo page does not cover libraries versus applications. Check its FAQ entry on why to keep the lockfile in version control before deciding for a library. For SBOM purposes, an application you ship should have its lockfile committed so the inventory is reproducible.

A worked example

A team's Rust service depends on 40 crates, 39 from the public registry and one pulled from a git repository because a bug fix was merged but not yet released. In Cargo.lock, the git entry has a source field beginning with git+ and ending with a commit hash. This example is invented.

Here is how a reviewer handles it:

StepActionResult
1Search the lockfile for git+ sourcesOne entry found
2Record repository URL and full hashEvidence of exact code
3Check whether the commit is on a tagIt is a branch commit, ahead of the last release
4Add an SBOM note: not from a registryReaders know advisories may not map cleanly
5Create a ticket to move to a releaseReduces future risk

The SBOM now says more than name and version. It says which code and where it came from.

Updating deliberately

The Cargo documentation describes how to update. Running cargo update with no arguments updates all dependencies to the latest versions allowed. Naming a package performs a conservative update: solely that dependency is updated, its transitive dependencies change solely if needed, and everything else stays locked. The precise option sets a specific version, and for a git dependency it can be a revision such as a SHA or tag. A dry run option shows what would change without writing the lockfile.

For a git dependency, the usual routine is to use the precise option to move to a newer commit, review the lockfile diff, and regenerate the SBOM. The diff shows the old and new hashes, which you can compare upstream.

Why conservative updates help

A broad update changes many packages at once, which makes SBOM diffs noisy and reviews hard. A conservative update of one crate keeps the diff small. Use the dry run first to see the plan, then run it for real. Small steps make it easier to spot a surprise, such as an unexpected transitive bump.

Guarding CI

The docs describe a locked flag that asserts the exact same dependencies and versions are used as when the lockfile was generated, and exits with an error if the lock file is missing or Cargo tries to change it. Use it in CI so that builds fail when the lockfile is out of date, instead of silently resolving new versions. Generate the SBOM after such a build so the file describes what was built.

Git dependencies and policy

Git dependencies bypass the release process of a registry. A tag can be moved and a repository can disappear. Consider a short policy: each git dependency needs an owner, a reason and a review date. Prefer a released version once one exists. Mirror critical repositories so that a deleted upstream does not stop your build.

Reading the diff

When a lockfile changes in a pull request, ask four questions. Which packages changed? Did any come from a different source? Did any transitive package appear or vanish? Is the change consistent with what the author intended? An SBOM diff, produced from before and after, answers these in a form that non Rust reviewers can read.

Where Safeguard fits

Safeguard scans dependencies and SBOMs, and the free scan at gold.safeguard.sh/scan can show how a Rust project's components appear.

Try it yourself

Click through it at your own pace, or open it full screen.

Click into a few components and note how direct and transitive packages are separated.

Quick check

Where is the exact commit of a git dependency recorded?

In the source field of the package entry in Cargo.lock, after the repository URL.

Can I edit Cargo.lock by hand?

The docs say it is maintained by Cargo and should not be manually edited. Use cargo update instead.

How do I move a git dependency to a newer commit?

Use cargo update with the package name and the precise option set to a revision. Review the lockfile diff afterwards.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.