Files
bot-bottle/docs/prds/prd-new-gitleaks-inline-suppression-supervision.md
T
didericis-codex 842caf40fe
lint / lint (push) Successful in 1m35s
test / unit (pull_request) Successful in 29s
test / integration (pull_request) Successful in 16s
docs(prd): add gitleaks allow supervision
2026-06-19 21:58:29 -04:00

3.8 KiB

PRD prd-new: Gitleaks inline suppression supervision

  • Status: Active
  • Author: codex
  • Created: 2026-06-10
  • Issue: #208

Summary

Route every # gitleaks:allow inline suppression through the existing supervisor approval queue before git-gate forwards a push upstream. The annotation remains available for test fixtures and confirmed false positives, but it no longer lets an agent silently bypass the gate's secret scan.

Problem

Gitleaks supports inline suppression comments. With the default behaviour, a pushed line that contains a secret-like value and # gitleaks:allow is ignored by gitleaks and accepted by git-gate. That is convenient for dummy credentials in tests, but it also gives an agent a one-line bypass for a real secret. Once the commit lands, the diff alone cannot prove whether the suppression was legitimate.

Goals / Success Criteria

  1. Git-gate continues to run the normal gitleaks scan for every incoming ref.
  2. After the normal scan passes, git-gate runs a second scan with --ignore-gitleaks-allow and a JSON report so suppressed findings become visible.
  3. If that second scan reports no suppressed findings, the push proceeds unchanged.
  4. If it reports suppressed findings, git-gate creates a gitleaks-allow supervisor proposal containing the ref, file path, line number, rule, commit, and flagged line for each finding.
  5. The push proceeds only when the supervisor explicitly approves the proposal; rejection, malformed responses, missing supervisor configuration, and timeout all refuse the push.
  6. The supervisor TUI requires a reason when approving a gitleaks-allow proposal, so the audit trail records whether the approval was for a test fixture or a false positive.

Non-goals

  • Replacing gitleaks or changing the main secret-detection rule set.
  • Removing support for # gitleaks:allow.
  • Automatically classifying fixture files or false positives.
  • Adding new supervisor transport or authentication mechanisms.

Design

Git-gate flow

git_gate_render_hook() emits a supervise_gitleaks_allow shell helper. For each incoming ref, git-gate first runs the existing gitleaks command. If that scan passes, it runs:

gitleaks git \
  --log-opts="$log_opts" \
  --no-banner \
  --redact \
  --ignore-gitleaks-allow \
  --report-format=json \
  --report-path="$report_file" \
  --exit-code 0

The second pass keeps the push path non-interactive while producing a report of findings that would otherwise have been hidden by inline suppression.

Supervisor proposal

When the JSON report contains findings, an embedded Python helper writes a proposal into SUPERVISE_QUEUE_DIR using the existing proposal schema. The proposal uses:

  • tool: "gitleaks-allow"
  • a text payload with the ref and each finding's file, line, rule, commit, and redacted code line
  • a justification that tells the operator to approve only dummy test fixtures or confirmed false positives

Git-gate then waits for <proposal-id>.response.json for SUPERVISE_GITLEAKS_ALLOW_TIMEOUT_SECONDS, defaulting to 300 seconds. approved and modified responses allow the push; rejected, invalid responses, invalid timeout configuration, or timeout refuse it.

Supervisor UI

TOOL_GITLEAKS_ALLOW is added to the supervisor tool registry. The curses supervisor renders the proposal as text and allows approval or rejection. Modification is unavailable for this proposal type because there is no file patch to apply. Approval from the TUI prompts for a non-empty reason and writes that reason to the response/audit path.

Tests

Unit tests assert that the rendered git-gate hook includes the second gitleaks pass, supervisor queue fields, and fail-closed messages. Supervisor tests cover the new tool constant, proposal archiving, and the required TUI approval reason.