feat(container): surface provenance attestations behind feature flag [PRIM-100] - #7047
feat(container): surface provenance attestations behind feature flag [PRIM-100]#7047bdemeo12 wants to merge 5 commits into
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ccb7cb7 to
805f667
Compare
This comment has been minimized.
This comment has been minimized.
…[PRIM-100] Bump snyk-docker-plugin to ^9.18.0 (adds provenance attestation extraction) and gate the provenanceMetadata fact behind the surfaceProvenanceAttestations feature flag in filterDockerFacts, mirroring the allowNewContainerFacts pattern. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Picks up snyk-docker-plugin 9.19.0, which falls back to BuildKit's vcs.source for buildConfigSourceUri on local builds (snyk/snyk-docker-plugin#889) so locally-built images still surface their source repository in the provenanceMetadata fact. Registry maps that field to repository_uri when relaying the asset upsert. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
805f667 to
fc5416d
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Automated Verification Summary
Ran the verification pipeline (semantic analysis, adversarial review, security scan, code review) against the full PR diff (3b9cfbee...fc5416db2).
Scope check: this PR is not a dependency-only change — besides the snyk-docker-plugin bump in package.json/package-lock.json, it also modifies src/cli/commands/constants.ts and src/lib/ecosystems/common.ts (new feature-flag logic). Per this automation's policy, only pure dependency-bump PRs (e.g. a lone go.mod/package.json version change) are auto-approved — this one is not, so no approval was applied here regardless of findings below.
Should Fix
- Dependency bump silently makes every container scan perform an extra, unconditional registry call, undercutting the PR's "behind feature flag" framing — see inline comment on
package.json. Verified directly against the publishedsnyk-docker-plugin@9.20.0source, not just static reasoning. - Two independent feature-flag lookups are awaited sequentially instead of via
Promise.all, doubling network round-trip latency per scan path — see inline comment onsrc/lib/ecosystems/common.ts. - No test coverage for the new independent-flag interaction /
provenanceMetadatafiltering — see inline comment onsrc/lib/ecosystems/common.ts. This is more specific than Danger's generic "no test updates" warning: the existing suite mockshasFeatureFlagOrDefaultwith one blanket value per test, so it's structurally incapable of distinguishing the two flags' independent behavior, which is the entire point of this PR.
Suggestion
- When
surfaceProvenanceAttestationsis on, theprovenanceMetadatafact (which per the upstream plugin can include base64-encoded Dockerfile contents and build source URIs) is forwarded to Registry with no CLI-side size cap or redaction. Opt-in and non-blocking, but worth confirming Registry-side handling/documentation so org admins enabling the flag understand the exposure surface.
Verified correct
- Traced all 4 combinations of
includeAllFacts/includeProvenanceAttestations— the filter logic correctly implements independent rollout as described in the PR (theprovenanceMetadatacheck is ordered before theincludeAllFactsshort-circuit, which is what makes the flags actually independent). - No injection/parsing risk introduced (plain string/Set comparisons);
hasFeatureFlagOrDefaultfails closed (false) on lookup errors for both flags. - Lockfile/version bump itself introduces no new known CVEs (resolved transitive versions of
adm-zip/minimatch/shescapeare actually unchanged by this bump — only thepackage.jsonrange widened).
Notes
- Danger CI already flags on this PR: no test-folder updates alongside
src/changes, multiple commits (please squash before merge per repo convention), and a commit/PR title over 72 chars. Not re-detailed above, just flagging they still apply. - CI (build/lint/test) was still in progress at review time; findings above come from static analysis of the diff plus direct inspection of the published
snyk-docker-plugin@9.20.0package source (not from local test execution).
Sent by Cursor Automation: Automatic PR verification
| const includeProvenanceAttestations = await hasFeatureFlagOrDefault( | ||
| SURFACE_PROVENANCE_ATTESTATIONS_FEATURE_FLAG, | ||
| options, | ||
| false, | ||
| ); |
There was a problem hiding this comment.
Should Fix: includeAllFacts (above) and includeProvenanceAttestations (here) are two independent hasFeatureFlagOrDefault calls — each a real HTTP round-trip — but are awaited sequentially. filterDockerFacts runs once per scanned path in test.ts/monitor.ts, so this doubles feature-flag-lookup latency per path on every container scan.
const [includeAllFacts, includeProvenanceAttestations] = await Promise.all([
hasFeatureFlagOrDefault(CONTAINER_NEW_FACTS_FEATURE_FLAG, options, false),
hasFeatureFlagOrDefault(
SURFACE_PROVENANCE_ATTESTATIONS_FEATURE_FLAG,
options,
false,
),
]);| if (fact.type === PROVENANCE_METADATA_FACT_TYPE) { | ||
| return includeProvenanceAttestations; | ||
| } |
There was a problem hiding this comment.
Should Fix: this provenanceMetadata branch — the core new behavior of this PR — has no test coverage. test/jest/unit/ecosystems-common.spec.ts mocks hasFeatureFlagOrDefault with a single mockResolvedValue applied uniformly to every call, so the (includeAllFacts=true, includeProvenanceAttestations=false) and (false, true) combinations — the whole point of making these flags independent — are never exercised. None of the fixtures include a { type: 'provenanceMetadata' } fact either, so this line never actually matches in any existing test; a regression that swapped the two conditions here would pass unnoticed.
Suggest adding a fixture fact of this type plus a test using mockImplementation keyed on the flag name to assert the fact is kept/dropped independently of CONTAINER_NEW_FACTS_FEATURE_FLAG.
| "snyk-config": "^5.0.0", | ||
| "snyk-cpp-plugin": "^2.24.3", | ||
| "snyk-docker-plugin": "^9.16.0", | ||
| "snyk-docker-plugin": "^9.20.0", |
There was a problem hiding this comment.
Should Fix (verified against upstream source): bumping to snyk-docker-plugin@9.20.0 pulls in an unconditional attestation fetch. In that version's dist/static.js:
if (imageType === ImageType.Identifier &&
(!analysis.attestations || analysis.attestations.length === 0)) {
try {
analysis.attestations = await fetchAttestationsFromRegistry({ ... });
} catch (error) { /* best-effort, swallowed */ }
}fetchAttestationsFromRegistry runs whenever imageType === ImageType.Identifier (the default snyk container test <image>:<tag> path) and no attestations are already present — there's no option to skip it and no gate on surfaceProvenanceAttestations. The CLI flag added in this PR only decides whether the resulting provenanceMetadata fact is kept after the plugin has already made this extra registry round-trip. So every container scan — not just orgs with the flag enabled — pays for the additional network call the moment this bump merges, which runs counter to the "behind feature flag" framing in the PR title/description.
Worth confirming with the snyk-docker-plugin team whether the registry fetch itself can be gated by an option, or at minimum calling out this unconditional-cost scope explicitly in the rollout plan.
…ture flag Provenance attestations should be surfaced unconditionally, so drop the `surfaceProvenanceAttestations` gating. `shouldFilterFact` is a denylist and `provenanceMetadata` is not in it, so removing the special case is sufficient for the fact to always pass through. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PR Reviewer Guide 🔍
|
|
closing - handled here: #7130 |


What
Surfaces container image provenance attestations through the CLI, gated behind a feature flag.
snyk-docker-plugin^9.16.0→^9.18.0, which adds provenance attestation extraction (emits theprovenanceMetadatafact).surfaceProvenanceAttestationsfeature flag infilterDockerFacts, mirroring the existingallowNewContainerFactspattern. When the flag is off,provenanceMetadatais filtered out before facts are sent downstream; when on, it is forwarded to Registry for upsert.The provenance flag is independent of
allowNewContainerFactsso it can be rolled out separately.Changes
package.json/package-lock.json— bumpsnyk-docker-pluginto^9.18.0.src/cli/commands/constants.ts— addSURFACE_PROVENANCE_ATTESTATIONS_FEATURE_FLAG = 'surfaceProvenanceAttestations'.src/lib/ecosystems/common.ts— infilterDockerFacts, filterprovenanceMetadataunless the flag is enabled.Feature flag
surfaceProvenanceAttestations— defined in registry (snyk/registry#44819).Downstream
This is the CLI half of the end-to-end provenance work. Registry relays the fact and assets-api persists it.
Notes
n/a