Skip to content

feat(secret-scan): add severity-aware failure policies#11

Open
gmanal wants to merge 1 commit into
mainfrom
feat/secret-scan-fail-policy
Open

feat(secret-scan): add severity-aware failure policies#11
gmanal wants to merge 1 commit into
mainfrom
feat/secret-scan-fail-policy

Conversation

@gmanal

@gmanal gmanal commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Replace the boolean fail-on-findings input with a constrained fail-policy input supporting all, verified, and none.

  • Preserve fail-closed behavior with all as the default.
  • Allow verified secrets to fail while unverified findings only warn.
  • Keep scanner infrastructure errors blocking under every policy.
  • Emit one policy-consistent annotation per scan outcome.
  • Update consumer examples and changelog documentation.

@gmanal
gmanal force-pushed the feat/secret-scan-fail-policy branch from be7c0c4 to f9d7d40 Compare July 20, 2026 17:48
Comment thread .github/workflows/ci.yml Outdated
# With fail-policy=verified, unverified secrets (exit 185) should be detected
# but the workflow should still pass when using fail-policy=verified.
# Here we verify the scanner detects them; the reusable workflow tests the policy.
if docker run --rm -v "$RUNNER_TEMP/dirty-verified:/scan:ro" \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This test does not test the reusable workflow. It also passes for any Docker error, not only exit code 185. Can we check for exit code 185 and test the policy logic directly?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

A true end-to-end negative test through the reusable workflow is structurally hard on GitHub Actions.

  • A uses: job can't run setup steps, so you can't plant a fixture before the reusable workflow's own checkout scans the tree.
  • Committing a fixture into the repo would trip the scanner on every other job (including the positive/clean tests).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

added a parameterised test stage - https://github.com/NVIDIA/security-workflows/pull/11/changes#diff-a68373eb11f8afb3fb42a99d6822680588bdf8a4caa85424aa265275df7c15d1R58
to generate the disposable secrets and test the reusable workflow.

--entrypoint pulse-secret-scanner \
"$PULSE_IMAGE" \
filesystem /repo "--results=${RESULTS}" --json --fail \
filesystem /repo --results=verified,unknown,unverified --json --fail \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We now include unknown results, but the SARIF code labels them as unverified. Can we keep unknown and unverified as separate result types?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes. changes applied.

Comment thread .github/workflows/secret-scan-pulse.yml Outdated
The scan always surfaces every finding class i.e. verified, unknown, and unverified.
This input only decides which classes fail the job.
Allowed:
- all (fail on verified or unverified)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These policy names do not match the GitLab component. For example, all has a different meaning here. Can we use the same names or choose clearer names? Please see https://gitlab-master.nvidia.com/security/devops-tools/ci-cd-components/secret-scan/-/blob/6.0.0/templates/source-code-secret-scan/template.yml#L64-75

@acrow-nvidia can you confirm

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes I agree. The GitLab component has the following policies:

  1. unverified - this is the default, allows unverified but fails on verified
  2. strict - fails on all findings: verified and unverified
  3. all - allows any job failure.

It would be good for the policies to match

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

changes applied to reflect the policy names similar to gitlab and actual secret scanner.

@gmanal
gmanal force-pushed the feat/secret-scan-fail-policy branch from fa202db to d64c9ef Compare July 21, 2026 08:03
Make failure_policy the single enforcement lever for the Pulse reusable
workflow, with names and default matching the GitLab secret-scan component so
the GitLab and GitHub surfaces behave identically.

failure_policy (default unverified):
- unverified — fail on verified/live secrets (exit 183); keep the job green on
  unverified findings (exit 185).
- strict — fail on any finding (183 or 185).
- all — warn only; never fail the job on findings.
Scanner/infra errors always fail closed; missing scan state fails the job.

Scan and reporting:
- Remove the caller-facing `results` input. The scan always runs with the
  broadest filter (--results=verified,unknown,unverified) so every finding
  class — including unverified findings such as private keys — reaches SARIF
  and is eligible for enforcement.
- SARIF labels each finding's verification state distinctly (verified /
  unknown / unverified), derived from the scanner's Verified + VerificationError
  fields; verified -> error, unknown/unverified -> warning, with the state also
  in properties.verificationState.

Testing:
- ci.yml exercises positive and negative cases across all three policies. The
  unverified and all negatives run end-to-end through the reusable workflow via
  the repo-guarded, CI-only ci_test_setup input (both expected to pass); the
  strict negative asserts the scanner's exact exit code (185).

Docs:
- README, workflow catalogue, and CHANGELOG updated.

Migration (pre-release interface change):
- Remove any `results:` input from consumer `with:` blocks.
- fail-on-findings: true  -> failure_policy: strict (or unverified to tolerate
  unverified findings)
- fail-on-findings: false -> failure_policy: all
@gmanal
gmanal force-pushed the feat/secret-scan-fail-policy branch from d64c9ef to 2ee7fba Compare July 21, 2026 08:08
@gmanal
gmanal requested a review from ftnv July 21, 2026 08:11
# results: verified,unknown # workflow default
# fail-on-findings: false # warn-only during initial rollout
# runs-on: linux-amd64-cpu4 # nv-gha-runners label
# failure_policy: unverified # fail on any finding (default: unverified — fail verified, warn unverified)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

"fail on any finding" is incorrect for this failure policy, update comment

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.

3 participants