sec(sscsb): close every verify gap but branch protection; TruffleHog is the only secret scanner - #22
Open
p4gs wants to merge 1 commit into
Open
sec(sscsb): close every verify gap but branch protection; TruffleHog is the only secret scanner#22p4gs wants to merge 1 commit into
p4gs wants to merge 1 commit into
Conversation
…is the only secret scanner `sscsb verify` went 19 PASS / 8 FAIL / 1 DEGRADED -> 27 PASS / 1 FAIL / 1 DEGRADED. Secret scanning is now TruffleHog ONLY. gitleaks is off in .sscsb/config.toml, its CI job is gone from secrets-scan.yml, and .gitleaks.toml is deleted. TruffleHog validates a candidate against the issuing provider, so `verified` means a live credential; gitleaks matches entropy and regex and cannot make that call. Running both bought a second scan and a second allowlist file to keep honest, for no detection the stronger tool did not already make. The same reasoning retires the weaker duplicate TruffleHog job in ci.yml: secrets-scan.yml runs the same tool on a superset of triggers with a newer pinned release and --results=verified,unknown instead of --only-verified, so nothing is lost by deleting the duplicate. SAST keeps THREE engines on purpose. codeql.yml is added (rust + actions, buildless) alongside the existing OpenGrep and Semgrep workflows: CodeQL does interprocedural taint tracking over a compiled database and surfaces classes an OpenGrep default ruleset does not express at all. That is not the kind of redundancy gitleaks was. Five controls (secrets, commit-signing, ai-trailers, ai-dep-gate, package-trust) were failing for one shared reason: core.hooksPath pointed at .git/hooks, which holds only git's samples, so NO sscsb hook had been running. The shims were also tracked mode 0644 — git silently skips a non-executable hook, so a fresh clone would have had the same silent no-op even with the path set. Both fixed; the shims are 0755 now. dependency-pinning: the parity job's `pip install pyyaml` becomes a hash-locked `--require-hashes` install, and both Dockerfile stages are digest-pinned. Pinning stage 2 surfaced a live break — cgr.dev/chainguard/cc-dynamic is no longer anonymously pullable (403 FORBIDDEN on the anonymous pull token), so that build could not have succeeded on a runner without Chainguard credentials. Swapped to glibc-dynamic, which is anonymously pullable and carries everything this stage needs (verified in the image: libc.so.6, libgcc_s.so.1, ld-linux, ca-certificates.crt). Also: release.yml's top-level write grants no longer leak into `build` and `sbom`, and `attestations: write` is dropped outright because no job in that workflow uses actions/attest*. LICENSE (Apache-2.0) is added — Cargo.toml and README both declared it and README linked to a file that did not exist. SECURITY.md is added, which security-insights.yml already pointed at. The stale "REPLACE-ME / TODO" note is removed from security-insights.yml (there were no placeholders left), flipping it INFO -> PASS. What is NOT closed, with reasons, is written down in .sscsb/POSTURE.md rather than left to be scrolled past: - branch-protection FAILs because a ruleset lives in GitHub's settings, not the tree, and `sscsb harden` cannot write this one (it looks for a ruleset naming the branch literally; ours targets ~DEFAULT_BRANCH). The three missing rules are checked in as an importable ruleset under .github/rulesets/, with the gh command beside it. - signing-model stays DEGRADED. Three lanes need an owner attestation of GitHub web settings that have no read API. The agent-claude-code lane is deliberately NOT converged: it asks for a distinct agent identity, and this owner runs one-signer, everywhere, with AI involvement recorded through commit trailers instead. Verified, not assumed: sscsb verify 27/1/1; sscsb sast 0 findings; sscsb scan 1 low (Dockerfile HEALTHCHECK, below the `high` fail threshold); the hash-locked pip install resolved and installed in a clean venv; both image digests resolved from the live registries; the glibc-dynamic layer contents were listed, not assumed. AI-Assisted: true AI-Tool: Claude Code AI-Model: claude-opus-5 AI-Role: draft Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017N6Qc2T7buVAXHZ9vYa1xm
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
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 this does
sscsb verifyon this repo went 19 PASS / 8 FAIL / 1 DEGRADED → 27 PASS / 1 FAIL / 1 DEGRADED.Secret scanning is now TruffleHog only
gitleaks is off in
.sscsb/config.toml, its CI job is gone fromsecrets-scan.yml, and.gitleaks.tomlis deleted. TruffleHog validates a candidate against the issuing provider, soverifiedmeans a live credential; gitleaks matches entropy and regex and cannot make that call. Running both bought a second scan and a second allowlist file to keep honest, for no detection the stronger tool did not already make.The same reasoning retires the weaker duplicate TruffleHog job in
ci.yml:secrets-scan.ymlruns the same tool on a superset of triggers (push to main + every PR, vs PRs targeting main) with a newer pinned release and--results=verified,unknowninstead of--only-verified. Nothing is lost by deleting the duplicate.SAST keeps three engines on purpose
codeql.ymlis added (rust + actions, buildless) alongside the existing OpenGrep and Semgrep workflows. CodeQL does interprocedural taint tracking over a compiled database and surfaces classes an OpenGrep default ruleset does not express at all. That is not the kind of redundancy gitleaks was.Five controls were failing for one shared reason
secrets,commit-signing,ai-trailers,ai-dep-gateandpackage-trustall failed becausecore.hooksPathpointed at.git/hooks, which holds only git's samples — so no sscsb hook had ever run. The shims were also tracked at mode0644, and git silently skips a non-executable hook, so a fresh clone would have hit the same silent no-op even with the path set. Both fixed; the shims are0755in the tree now.dependency-pinning
pip install pyyamlin theparityjob → hash-lockedpip install --require-hashes -r scripts/requirements-parity.txt.Dockerfilestages digest-pinned.Pinning stage 2 surfaced a live break:
cgr.dev/chainguard/cc-dynamicis no longer anonymously pullable (403 FORBIDDEN on the anonymous pull token), so that build could not have succeeded on a runner without Chainguard credentials. Swapped toglibc-dynamic, which is anonymously pullable and carries everything this stage needs — verified by listing the image layers:libc.so.6,libgcc_s.so.1,ld-linux-*.so,ca-certificates.crt.Also
release.yml: top-level write grants no longer leak intobuildandsbom;attestations: writedropped outright (no job in that workflow usesactions/attest*).LICENSE(Apache-2.0) added —Cargo.tomlandREADME.mdboth declared it and the README linked to a file that did not exist.SECURITY.mdadded —security-insights.ymlalready pointed at it.security-insights.yml(there were no placeholders left), flipping it INFO → PASS..sscsb/out/gitignored (generated SBOM/scan output).What is NOT closed
Written down in
.sscsb/POSTURE.mdrather than left to be scrolled past.branch-protectionFAILs. A ruleset lives in GitHub's settings, not the tree, andsscsb harden branch-protectioncannot write this one — it looks for a ruleset naming the branch literally, and ours targets the~DEFAULT_BRANCHalias, so the planner reports "no ruleset targets this branch" and changes nothing. The three missing rules (required PRs, required signed commits, required status checks) are checked in as an importable ruleset:signing-modelstays DEGRADED. Three lanes need an owner attestation of GitHub web settings that have no read API. Theagent-claude-codelane is deliberately not converged: it asks for a distinct agent identity, and this owner runs one-signer-everywhere with AI involvement recorded through commit trailers instead.Verified, not assumed
sscsb verify27 PASS / 1 FAIL / 1 DEGRADED / 3 INFO / 15 disabledsscsb sast— 0 findingssscsb scan— 1 low (DS-0026, Dockerfile HEALTHCHECK), below thehighfail thresholdglibc-dynamiclayer contents were listed, not assumed