Repository navigation
feat(detector): inventory Rust packages and audit Cargo configuration - #234
Merged
Merged
Conversation
Add cargo_inventory and cargo_config_audit (schema_version 1) to enterprise telemetry in a new cargo_scan phase after go_scan. The inventory reads Cargo.toml declarations with workspace inheritance, Cargo.lock formats 3 and 4, the registry cache, Git checkouts, vendored sources and local registries, and cargo install receipts. The audit reads .cargo/config(.toml) files, their includes and an allowlisted process environment per invocation context, with findings cargo-001..cargo-004. Everything is static: no cargo, rustc or git command, shell or network call. Reads go through guarded, bounded executor file methods, URL credentials are redacted on the device, credentials files are checked for presence only, and any refusal, failure or limit marks the affected source partial. Bumps go-toml/v2 to v2.4.3.
There was a problem hiding this comment.
🟡 Changes recommended
Workspace exclusions, incomplete-status propagation, deterministic serialization, and the unenforced golden contract need correction.
4 open findings
What changed in this PR
Adds bounded, static Rust/Cargo inventory and configuration auditing to enterprise telemetry.
Changes:
- Inventories Cargo projects, workspaces, lockfiles, caches, vendored packages, Git checkouts, and installed tools.
- Adds redacted Cargo configuration auditing, wire models, and a new telemetry phase.
- Updates documentation, tests, Go scanner fixes, and the TOML dependency.
| File | Description |
|---|---|
SCAN_COVERAGE.md |
Documents Cargo scan coverage and safeguards. |
README.md |
Adds Rust inventory and configuration support. |
go.mod |
Upgrades go-toml. |
go.sum |
Updates go-toml checksums. |
internal/telemetry/telemetry.go |
Runs and serializes the Cargo phase. |
internal/model/model.go |
Defines Cargo wire models and vocabulary. |
internal/model/testdata/cargo_inventory_v1_golden.json |
Adds the Cargo contract fixture. |
internal/detector/cargoscan.go |
Implements bounded Cargo inventory collection. |
internal/detector/cargoscan_test.go |
Tests major inventory behavior and limits. |
internal/detector/cargometadata.go |
Parses Cargo metadata and archives. |
internal/detector/configaudit/cargoconfig.go |
Implements Cargo configuration auditing. |
internal/detector/configaudit/cargoconfig_test.go |
Tests redaction and partial selection. |
internal/detector/goscan.go |
Corrects fallback-root status handling. |
internal/detector/goscan_test.go |
Covers unknown Go root redirects. |
internal/detector/configaudit/goenv.go |
Refines Go proxy fallback detection. |
internal/detector/configaudit/goenv_test.go |
Tests Go proxy fallback cases. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+689
to
+695
| func (g *cargoScan) excludes(root, s *cargoManifestState) bool { | ||
| under := func(entries []string) bool { | ||
| return slices.ContainsFunc(entries, func(e string) bool { | ||
| return cargoInside(g.goos, s.dir, filepath.Join(root.dir, filepath.FromSlash(e))) | ||
| }) | ||
| } | ||
| return under(root.m.workspace.exclude) && !under(root.m.workspace.members) |
Comment on lines
+1764
to
+1766
| default: | ||
| b.Presence = model.CargoBinUnreadable | ||
| } |
| for _, inc := range includes { | ||
| b.add("include", inc.path, false) | ||
| } | ||
| slices.SortStableFunc(b.out, func(x, y cargoSetting) int { return strings.Compare(x.Key, y.Key) }) |
| @@ -0,0 +1,1344 @@ | |||
| { | |||
ashishkurmi
approved these changes
Oct 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


What does this PR do?
Adds Rust/Cargo evidence to enterprise telemetry as two optional sections,
cargo_inventoryandcargo_config_audit(eachschema_version: 1), in a newcargo_scanphase right aftergo_scan. Both are full bounded snapshots sent on every run. The shape mirrors the Go scanner and reuses its guards, source IDs and budgets.cargo_inventory(static, no Rust toolchain needed)Cargo.toml: normal, dev, build and target-specific tables; aliases, features, optional and explicitdefault-features; registry, Git and path selectors. Workspace inheritance is applied; onlyworkspace.dependenciesentries that members inherit are followed.exclude, in-root path dependencies and explicitpackage.workspace. Membership that can't be established isworkspace_unresolved.Cargo.lockformats 3 and 4, once per workspace root, honoringresolver.lockfile-path. Other formats areunsupported_format.registry/cache+registry/src), Git checkouts (full commit only from a 40/64-hex.git/HEAD), vendored directories, local registries and.crates.toml/.crates2.jsoninstall receipts with bin presence.Cargo.lockand.cargo-checksum.json, alwaysnot_verified.cargo_config_audit.cargo/configand.cargo/config.tomlper project and ancestor inside the search roots, the Cargo home config, includes (depth and count bounded, cycles flagged), and an allowlisted process environment, all resolved per invocation context in precedence order (config_source_ids).cargo-001..cargo-004: HTTP registry/source index, insecure Git source, plaintext token in config,http.check-revoke = false.Safety properties
cargo,rustcorgitcommand, shell, network call, PATH search orUserAwareExecutor. Every read goes through guarded, bounded executor file methods;.cratearchives are read in memory with header, size and path-traversal bounds.include_tcc_protected; there is no Cargo TCC exception.[patch."https://…"]), tokens show only as configured, and custom credential providers becomecustomwith arguments dropped.partialwith a reason code. The record budget is charged during collection, and every owner left unfinished is markedrecord_limit. The combined output is capped at 16 MiB with a status envelope.Other:
github.com/pelletier/go-toml/v2v2.3.1 → v2.4.3. Communityscanoutput is unchanged.Contract:
internal/model/testdata/cargo_inventory_v1_golden.jsonholds IDs recomputed from its displayed paths, and it decodes strictly and round-trips byte-identically. For it to pass the Agent API validator, the API needs to:cached_package+vendor_unknownwhen the owner is alocal_registrysource;unsupportedwithpath_unresolved.Type of change
SCAN_COVERAGE.md,README.md)Testing
make smoke): pendinggo vet, golangci-lint (0 issues)go test ./... -race -count=1Also:
CGO_ENABLED=0builds for linux/amd64, darwin/arm64 and windows/amd64;go mod tidyshows no drift.Not yet done (release checks):
make smoke.cargo metadatareferences.Related Issues