Skip to content

ci(codeql): move config to a file and exclude rust/cleartext-logging - #139

Merged
tonibergholm merged 3 commits into
mainfrom
ci/codeql-config-file
Sep 3, 2026
Merged

ci(codeql): move config to a file and exclude rust/cleartext-logging#139
tonibergholm merged 3 commits into
mainfrom
ci/codeql-config-file

Conversation

@tonibergholm

Copy link
Copy Markdown
Member

What

Code scanning had 145 open high alerts, every one of them from rust/cleartext-logging. This excludes that rule and moves the CodeQL exclusions out of the workflow's inline config: block into .github/codeql/codeql-config.yml, so each one carries its reason somewhere reviewable.

Why the rule is noise here

rust/cleartext-logging taints anything flowing out of a type or function whose name contains Secret, then flags every println!/eprintln! downstream. In this codebase that is the entire secrets API by design, so all 145 alerts landed on metadata that is public by construction:

  • eprintln!("skipped (no key): {path}") — a file path (~30 alerts, across switch, sparse, ws, workspace)
  • eprintln!("warning: not authorized for secret {name}; skipping") — a secret name, i.e. public registry data
  • println!("{index:<3} landed @ {}", merged_tip.short()) — a snapshot id
  • println!("{}", serve_tls_fingerprint(&root)?) — a cert fingerprint, which is the entire point of the command
  • assert_eq!(..., "{path}: decrypts back to ...") — a test assertion message

None print plaintext. Secret plaintext has exactly one sanctioned egress — the child-process env injected by sc run (ADR-0008). There is no sc secret show; sc secret list emits names plus a recipient count. The one intentional plaintext print is sc serve token add, which prints a freshly minted token once and stores only its hash (ADR-0040).

What this exclusion costs

It would hide a genuine cleartext egress if one were ever added. That trade-off is recorded in the config file itself, along with the compensating controls: docs/THREAT-MODEL.md and the P5 commit-time secret scanner.

The critical alert

Alert #166 (rust/hard-coded-cryptographic-value at crates/crypto/src/envelope.rs:427) is let wrong = [0u8; 32]; — a deliberately-wrong key in a #[cfg(test)] negative test asserting decrypt_path rejects it. Dismissed as a false positive rather than filtered: tests are inline per CLAUDE.md, so a paths-ignore entry would also blind that rule to the real crypto in the same file. The rule stays armed for crates/crypto.

Verification

  • Both YAML files parse.
  • Code scanning default setup is not-configured and all recent analyses carry the workflow's /language:* categories, so the config-file will actually be honored (a config file is silently ignored under default setup).

🤖 Generated with Claude Code

Code scanning had 145 open high alerts, all from rust/cleartext-logging.
The rule taints anything flowing out of a type or function whose name
contains "Secret", then flags every println!/eprintln! downstream. In this
codebase that is the entire secrets API by design, so every alert was on
metadata that is public by construction: file paths ("skipped (no key):
{path}"), secret names from the public registry, snapshot ids, and TLS
fingerprints. None printed plaintext.

Secret plaintext has one sanctioned egress, the child-process env injected
by `sc run` (ADR-0008). There is no `sc secret show`; `sc secret list`
emits names plus a recipient count. The one intentional plaintext print is
`sc serve token add`, which prints a freshly minted token once and stores
only its hash (ADR-0040).

Exclude the rule via query-filters, and move the exclusions out of the
inline `config:` block into .github/codeql/codeql-config.yml so each one
carries its reason in a reviewable place. The exclusion's cost is recorded
there too: it would hide a genuine cleartext egress, so the compensating
controls are docs/THREAT-MODEL.md and the P5 commit-time secret scanner.

The remaining critical alert (a deliberately-wrong key in a #[cfg(test)]
negative test in crates/crypto/src/envelope.rs) is dismissed as a false
positive rather than filtered: tests are inline per CLAUDE.md, so a
paths-ignore entry would also blind rust/hard-coded-cryptographic-value to
the real crypto in the same file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@tonibergholm
tonibergholm merged commit 813227e into main Sep 3, 2026
7 checks passed
@tonibergholm
tonibergholm deleted the ci/codeql-config-file branch September 3, 2026 08:46
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