Skip to content

sscsb verify-and-upgrade: close signing-model's probeable half; keep Gitleaks alongside TruffleHog - #57

Open
p4gs wants to merge 4 commits into
mainfrom
chore/trufflehog-only-secrets
Open

p4gs wants to merge 4 commits into
mainfrom
chore/trufflehog-only-secrets

Conversation

@p4gs

@p4gs p4gs commented Sep 12, 2026 •

Copy link
Copy Markdown
Owner

Verify-and-upgrade pass over this repo's sscsb controls.

Update 2026-10-06: Gitleaks stays alongside TruffleHog, by owner decision, reversing this PR's original approach. TruffleHog only finds credentials for providers it has a detector for, and with --results=verified,unknown it reports a match only when the provider confirms it live or the verification attempt errors; it drops matches it could not verify, including those from detectors that have no verifier. Gitleaks matches on shape, so it also catches generic secrets such as passwords, internal tokens and keys for services TruffleHog has no detector for — so one scanner can't safely stand in for the other here. An earlier commit on this branch (e206066) removed Gitleaks from the control; a85df1b restored it in config, CI, .gitleaks.toml and the badge, but not in the scan record that 14e8b5e had republished at the TruffleHog-only state.

The change

Net result: the secrets configuration — both CI jobs, gitleaks = true, .gitleaks.toml's original allowlist, and the .sscsb/best-practices-badge.md row crediting TruffleHog + Gitleaks — matches main, apart from comment lines. The one non-comment secrets change left in this branch is the signed scan record, and it is stale: merging as-is would replace main's own record (bound to 710cf8e, reading gitleaks: 8.30.1 and listing harden-runner in job gitleaks) with this branch's e206066 record, which reads gitleaks: disabled in config and omits the gitleaks job from the harden-runner list.

The secrets jobs and config values are otherwise functionally identical to main. The only differences in secrets-scan.yml and in the [controls.secrets] block of .sscsb/config.toml are comment lines — a reworded header (redundancy → backstop) plus an explanation of why both scanners run: TruffleHog only finds credentials for providers it has a detector for, and with --results=verified,unknown it reports a match only when the provider confirms it live or the verification attempt errors; it drops matches it could not verify, including those from detectors that have no verifier. Gitleaks matches on shape, so it also catches generic secrets such as passwords, internal tokens and keys for services TruffleHog has no detector for. .sscsb/config.toml's other change — a 27-line STANDING DEGRADED comment block above [controls.signing-model] — is unrelated to secrets; see signing-model below. The scan record is the exception and must be regenerated (see Verification below).

SAST keeps both engines. CodeQL and OpenGrep both stay enabled — they model different vulnerability classes. CodeQL's matrix (actions, javascript-typescript) covers this repo's tracked .ts files and workflow files; neither needed adding.

signing-model

Closed the probeable half: sscsb signing setup cloud-claude wrote .claude/settings.json (attribution.sessionUrl), which syncs the Claude-Session trailer to cloud containers. It sets no signing identity.

The four remaining sub-items are now documented in the config beside the control instead of being rediscovered every audit. None is unfinished work:

  • agent-claude-code will not be converged. Its setup path requires an agent identity whose email "must NOT be a verified email on your GitHub account"; the one-signer directive of 2026-08-02 retired the separate AI identity outright. The control and the directive genuinely disagree, and the directive wins.
  • github-web wants vigilant_mode and phishing_resistant_mfa, which no API answers. Measured rather than assumed: gh api user returns two_factor_authentication: null, and even with read:user GitHub exposes a 2FA boolean and never the factor type — so "phishing-resistant" is structurally unreadable.
  • cloud-claude's github_app_installed and codespaces' gpg_verification are off-machine account actions in the same class.

Those three close with --confirm, which records a dated human assertion — deliberately not run by an agent, since the entire value of an attestation is that a person vouched for what they saw.

Verification

These numbers were measured on e206066, the intermediate TruffleHog-only commit on this branch, before the owner's 2026-10-06 reversal. They describe that state, not the current head:

  • sscsb verify: 0 failed, 1 degraded — 31 PASS / 1 DEGRADED / 0 FAIL / 4 INFO / 11 disabled, one fewer open signing-model sub-item.
  • sscsb sast: 0 findings (opengrep 1.25.0).
  • sscsb report: framework coverage byte-identical to the report before Gitleaks was removed (the control, not the tool, carries the mapping). Map still covers all 47 controls.
  • Scan record bound to e206066, signature verified Good for the approved signer.

The final commit (a85df1b) restored Gitleaks in config, CI, .gitleaks.toml, and the badge, but did not regenerate the scan record that 14e8b5e had republished at the e206066 state. .sscsb/scan-record.local.json in this PR still names commit e206066, still reads "gitleaks: disabled in config", and is still missing the harden-runner line for the gitleaks job (secrets-scan.yml: harden-runner present in job `gitleaks`) — all three stale against the current head, where gitleaks = true and the job runs again. main's own record is itself not current — it's bound to 710cf8e, 62 commits behind main's head, and reports 146 tracked files against the current 179 — but its secrets lines (gitleaks: 8.30.1, harden-runner in job gitleaks) match the restored config, and those secrets lines have no reason to change on this PR's account. Merging as-is would overwrite that record with this branch's own e206066 snapshot — which descends from 710cf8e and actually sits closer to main's head, but still gets secrets wrong: it reads gitleaks: disabled in config against the restored config.

No sscsb verify / sscsb report run was performed after the restore. CI on head a85df1b did run both secret-scan jobs directly: trufflehog pass and gitleaks pass (Actions run 37414591919). CodeQL (actions, javascript-typescript; run 37414592014) and OpenGrep (run 37414591914) also passed on a85df1b.

Before merge: regenerate and re-sign .sscsb/scan-record.local.json at head, so this PR doesn't overwrite main's secrets record with a stale one. (Restoring main's own record instead isn't a clean alternative: it would also reintroduce its stale cloud-claude: repo-side attribution is probeable and is not in place line, which this PR's own .claude/settings.json addition makes false.)

🤖 Generated with Claude Code

https://claude.ai/code/session_017N6Qc2T7buVAXHZ9vYa1xm

p4gs and others added 4 commits September 12, 2026 10:27
Where two tools cover one control, keep the single strongest. TruffleHog
live-validates a candidate credential against the issuing provider, so a
finding means an ACTIVE secret; Gitleaks is regex and entropy matching with
no verification step. Running both did not widen detection — it widened the
unverified-finding surface, and two tools reporting on one control is also
two places for a triager to learn to skim.

Removed rather than left dormant, in three places that each mattered:

- `.sscsb/config.toml`: `gitleaks = false`. The control still PASSes on
  TruffleHog alone and now reports `gitleaks: disabled in config` — an
  explicit off, not an absence that reads the same as a missing binary.
- `.github/workflows/secrets-scan.yml`: the `gitleaks` job is gone. The
  workflow keeps its TruffleHog job with `--results=verified,unknown`.
- `.gitleaks.toml`: deleted. Worth noting on its own — that file carried an
  allowlist for `.sscsb/out/*.cdx.json` and `*.spdx.json`, and every
  allowlist entry is a scanning blind spot. Retiring the tool retires its
  blind spots with it rather than leaving them configured for a scanner
  nothing runs.

`site/data/**`, root `scan-record.json`, and `site/src/glossary.ts` still
name gitleaks and are deliberately untouched: the first two are bot-PR
artifacts of the directory-publish lane (they regenerate), and the glossary
must keep explaining the term because OTHER repositories in the directory
still run it. This change is about which tools THIS repository runs.

Also closes the probeable half of `signing-model` and documents the rest.
`sscsb signing setup cloud-claude` wrote `.claude/settings.json` — an
attribution block (`sessionUrl: true`) that syncs the Claude-Session trailer
to cloud containers. It sets no signing identity, so it does not touch the
one-signer question.

The four sub-items that remain DEGRADED are now written down in the config
beside the control instead of being rediscovered every audit. None is
unfinished work:

- `agent-claude-code` will not be converged. The setup path requires an
  agent identity whose email "must NOT be a verified email on your GitHub
  account"; the one-signer directive of 2026-08-02 retired the separate AI
  identity outright. The control and the directive genuinely disagree, and
  the directive wins — agent commits attributing to the human is the
  intended posture here, not identity blur.
- `github-web` asks for `vigilant_mode` and `phishing_resistant_mfa`, which
  no API answers. Measured rather than assumed: `gh api user` returns
  `two_factor_authentication: null` (the token lacks `read:user`), and even
  with that scope GitHub exposes a 2FA boolean and never the factor TYPE —
  so "phishing-resistant" is structurally unreadable, which is exactly why
  sscsb models it as an attestation.
- `cloud-claude`'s `github_app_installed` and `codespaces`' `gpg_verification`
  are off-machine account actions in the same class.

Those three close with `--confirm`, which records a dated HUMAN assertion.
Deliberately not run from here: the entire value of an attestation is that a
person vouched for what they saw.

Verified: `sscsb verify` 0 failed, 1 degraded (unchanged count, one fewer
sub-item); `secrets` PASS on TruffleHog 3.96.0 alone; `sscsb sast` 0 findings
with opengrep 1.25.0; CodeQL and OpenGrep both remain enabled, CodeQL's
matrix (`actions`, `javascript-typescript`) matching the repo's 82 .ts and 20
workflow files. secrets-scan.yml re-parsed after the job removal — one job,
`trufflehog`.

AI-Assisted: true
AI-Tool: Claude Code
AI-Model: claude-opus-5
AI-Role: draft

Claude-Session: https://claude.ai/code/session_017N6Qc2T7buVAXHZ9vYa1xm

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rebinds the record to e206066, where the secrets control runs TruffleHog
alone. The previous record was signed at an earlier commit and still
asserted `gitleaks: 8.30.1 (/opt/homebrew/bin/gitleaks)` — a record binds its
result to a commit, so leaving it would have published a claim about a tool
this repository no longer runs.

The secrets evidence now reads `trufflehog: 3.96.0` plus `gitleaks: disabled
in config`. That second line is worth keeping rather than suppressing: it
distinguishes a deliberate opt-out from a missing binary, which is the
distinction the directory scores on.

Signature verified Good for the approved signer at the bound commit.

AI-Assisted: true
AI-Tool: Claude Code
AI-Model: claude-opus-5
AI-Role: draft

Claude-Session: https://claude.ai/code/session_017N6Qc2T7buVAXHZ9vYa1xm

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Owner decision: run Gitleaks alongside TruffleHog rather than retiring it.
Independent probes showed Gitleaks catches generic secrets (e.g. a bare
api_key = "<random>") and unverifiable keys that TruffleHog's
--results=verified,unknown filter drops, since TruffleHog can only report a
finding once it live-validates it against the issuing provider. Restores the
gitleaks CI job and .gitleaks.toml from main and reverts the config/doc lines
that claimed TruffleHog-only coverage or that Gitleaks added no detection
class TruffleHog lacks.

AI-Assisted: true
AI-Tool: Claude Code
AI-Model: Sonnet 5
AI-Role: draft
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012hwWMsTiv9Uf2gNbMh75uk
@p4gs p4gs changed the title secrets: TruffleHog only — retire Gitleaks from the control it shared sscsb verify-and-upgrade: close signing-model's probeable half; keep Gitleaks alongside TruffleHog Oct 6, 2026

This branch has not been deployed

No deployments
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.

1 participant