Skip to content

feat(container): surface provenance attestations behind feature flag [PRIM-100] - #7047

Closed
bdemeo12 wants to merge 5 commits into
mainfrom
PRIM-100/cli-provenance-attestations-ff
Closed

feat(container): surface provenance attestations behind feature flag [PRIM-100]#7047
bdemeo12 wants to merge 5 commits into
mainfrom
PRIM-100/cli-provenance-attestations-ff

Conversation

@bdemeo12

@bdemeo12 bdemeo12 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

What

Surfaces container image provenance attestations through the CLI, gated behind a feature flag.

  • Bumps snyk-docker-plugin ^9.16.0^9.18.0, which adds provenance attestation extraction (emits the provenanceMetadata fact).
  • Gates that fact behind the surfaceProvenanceAttestations feature flag in filterDockerFacts, mirroring the existing allowNewContainerFacts pattern. When the flag is off, provenanceMetadata is filtered out before facts are sent downstream; when on, it is forwarded to Registry for upsert.

The provenance flag is independent of allowNewContainerFacts so it can be rolled out separately.

Changes

  • package.json / package-lock.json — bump snyk-docker-plugin to ^9.18.0.
  • src/cli/commands/constants.ts — add SURFACE_PROVENANCE_ATTESTATIONS_FEATURE_FLAG = 'surfaceProvenanceAttestations'.
  • src/lib/ecosystems/common.ts — in filterDockerFacts, filter provenanceMetadata unless 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

@snyk-io

snyk-io Bot commented Jul 28, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor
Warnings
⚠️ There are multiple commits on your branch, please squash them locally before merging!
⚠️

"[feat(container): surface provenance attestations behind feature flag PRIM-100](#7047)" is too long. Keep the first line of your commit message under 72 characters.

⚠️

"refactor(container): do not gate provenance attestations behind a feature flag" is too long. Keep the first line of your commit message under 72 characters.

⚠️

"[feat(container): surface provenance attestations behind feature flag PRIM-100](https://api.github.com/repos/snyk/cli/git/commits/4032ff161fa5df73596b7def4446f7f6631ee5b0)" is too long. Keep the first line of your commit message under 72 characters.

Generated by 🚫 dangerJS against 49977ec

@bdemeo12
bdemeo12 marked this pull request as ready for review July 28, 2026 14:50
@bdemeo12
bdemeo12 requested a review from a team as a code owner July 28, 2026 14:50
@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

@bdemeo12
bdemeo12 force-pushed the PRIM-100/cli-provenance-attestations-ff branch from ccb7cb7 to 805f667 Compare August 3, 2026 19:29
@snyk-pr-review-bot

This comment has been minimized.

bdemeo12 and others added 4 commits August 4, 2026 09:07
…[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>
@bdemeo12
bdemeo12 force-pushed the PRIM-100/cli-provenance-attestations-ff branch from 805f667 to fc5416d Compare August 4, 2026 13:07
@snyk-pr-review-bot

This comment has been minimized.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  1. 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 published snyk-docker-plugin@9.20.0 source, not just static reasoning.
  2. Two independent feature-flag lookups are awaited sequentially instead of via Promise.all, doubling network round-trip latency per scan path — see inline comment on src/lib/ecosystems/common.ts.
  3. No test coverage for the new independent-flag interaction / provenanceMetadata filtering — see inline comment on src/lib/ecosystems/common.ts. This is more specific than Danger's generic "no test updates" warning: the existing suite mocks hasFeatureFlagOrDefault with 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 surfaceProvenanceAttestations is on, the provenanceMetadata fact (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 (the provenanceMetadata check is ordered before the includeAllFacts short-circuit, which is what makes the flags actually independent).
  • No injection/parsing risk introduced (plain string/Set comparisons); hasFeatureFlagOrDefault fails closed (false) on lookup errors for both flags.
  • Lockfile/version bump itself introduces no new known CVEs (resolved transitive versions of adm-zip/minimatch/shescape are actually unchanged by this bump — only the package.json range 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.0 package source (not from local test execution).
Open in Web View Automation 

Sent by Cursor Automation: Automatic PR verification

Comment thread src/lib/ecosystems/common.ts Outdated
Comment on lines +60 to +64
const includeProvenanceAttestations = await hasFeatureFlagOrDefault(
SURFACE_PROVENANCE_ATTESTATIONS_FEATURE_FLAG,
options,
false,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,
  ),
]);

Comment thread src/lib/ecosystems/common.ts Outdated
Comment on lines +76 to +78
if (fact.type === PROVENANCE_METADATA_FACT_TYPE) {
return includeProvenanceAttestations;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread package.json
"snyk-config": "^5.0.0",
"snyk-cpp-plugin": "^2.24.3",
"snyk-docker-plugin": "^9.16.0",
"snyk-docker-plugin": "^9.20.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@snyk-pr-review-bot

Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Implementation Files 🔴 [critical]

The PR description describes logic changes to src/cli/commands/constants.ts and src/lib/ecosystems/common.ts for feature flag gating, but these files are not present in the PR diff. Only package.json and package-lock.json are included. This results in the dependencies being updated without the actual feature logic being deployed.

"snyk-docker-plugin": "^9.20.0",
Version Mismatch 🟡 [minor]

The PR description states that snyk-docker-plugin is being bumped to ^9.18.0, but the code actually bumps it to ^9.20.0. While likely intentional to resolve the shescape vulnerability mentioned in the overrides, the documentation should be updated to reflect the version actually used.

"snyk-docker-plugin": "^9.20.0",
📚 Repository Context Analyzed

This review considered 5 relevant code sections from 2 files (average relevance: 0.46)

🤖 Repository instructions applied (from AGENTS.md)

@bdemeo12

Copy link
Copy Markdown
Contributor Author

closing - handled here: #7130

@bdemeo12 bdemeo12 closed this Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants