infra#344. The removed block suppressed
docs/superpowers/plans/2026-04-22-phase4-attempt-wiring.md, and its description
stated why:
"Literal placeholder word REDACTED matched as if it were a token
(verified 2026-08-04: extracted Secret == 'REDACTED' exactly, gitleaks'
curl-auth-header rule matched the placeholder text itself, not a real
credential)"
That is not what the file contained. Line 1054 carried a real 40-character hex
Gitea PAT in an `Authorization: token ...` header — not the eight-character word
REDACTED. Whether the file changed after the check or the check was wrong, the
justification has been guarding the wrong thing since.
Confirmed dead by side-effect before touching it, never by printing it: `GET
/api/v1/user` with that token returns 401. So there is nothing to rotate. It is
redacted here anyway, because a dead credential in a doc is still a working
example of how to write a live one, and git history keeps the original either
way.
Two independent failures had to line up, which is the same pair as infra#256:
1. The `paths` clause made the block far broader than its description. gitleaks
ORs global allowlist clauses and ignores `condition = "AND"`, so the ENTIRE
file was immune — a live token pasted into that doc tomorrow would have been
suppressed on the strength of a note about a different value.
2. The justification was never re-checked against the file it justifies.
With the token redacted the allowlist has nothing left to do, so it is deleted
rather than narrowed. Repo scans clean, and a planted live-shaped credential in
that same file is now caught.
Refs: mathias/infra#344, mathias/infra#256, mathias/infra#317
72 lines
3.2 KiB
TOML
72 lines
3.2 KiB
TOML
# gitleaks config for the hyperguild repo (infra#39 — leak prevention pass,
|
|
# Phase 3 checklist item: "gitleaks pre-commit hook in infra AND hyperguild").
|
|
#
|
|
# Ported from mathias/infra's .gitleaks.toml (2026-08-04) — same homelab
|
|
# token-shape rules, minus the SOPS/searxng allowlists infra needed (this
|
|
# repo doesn't use SOPS).
|
|
|
|
title = "hyperguild gitleaks config"
|
|
|
|
[extend]
|
|
useDefault = true
|
|
|
|
# --- Homelab-specific rules -------------------------------------------------
|
|
|
|
[[rules]]
|
|
id = "homelab-static-bearer"
|
|
description = "Homelab MCP/LLM static bearer or API key assigned a long literal value"
|
|
regex = '''(?i)\b(DMABE_[A-Z0-9_]+|[A-Z0-9_]*MCP_TOKEN|ROUTING_MCP_TOKEN|INFRA_MCP_TOKEN|BRAIN_MCP_TOKEN|GITEA_MCP_TOKEN|LITELLM_MASTER_KEY|LITELLM_SALT_KEY|DMABE_LLMAPI_KEY|BRAIN_PG_DSN)\s*[:=]\s*['"]?([A-Za-z0-9/_+.\-]{16,})['"]?'''
|
|
keywords = ["dmabe_", "mcp_token", "litellm_master_key", "litellm_salt_key", "llmapi_key", "brain_pg_dsn"]
|
|
[[rules.allowlists]]
|
|
description = "Env indirection is not a literal secret"
|
|
regexes = [
|
|
'''os\.environ''',
|
|
'''valueFrom''',
|
|
'''secretKeyRef''',
|
|
'''\$\{?[A-Za-z_][A-Za-z0-9_]*\}?''',
|
|
'''REDACTED''',
|
|
'''<[A-Z_]+>''',
|
|
]
|
|
|
|
[[rules]]
|
|
id = "homelab-authorization-bearer"
|
|
description = "Hardcoded Authorization: Bearer header"
|
|
regex = '''(?i)authorization['"]?\s*[:=]\s*['"]?bearer\s+([A-Za-z0-9/_+.\-=]{16,})'''
|
|
keywords = ["authorization", "bearer"]
|
|
[[rules.allowlists]]
|
|
description = "Env indirection is not a literal secret"
|
|
regexes = [
|
|
'''\$\{?[A-Za-z_][A-Za-z0-9_]*\}?''',
|
|
'''os\.environ''',
|
|
'''REDACTED''',
|
|
'''<[A-Z_]+>''',
|
|
]
|
|
|
|
# --- Global allowlist: claudewatcher's own scrubber test fixtures ------------
|
|
# ingestion/internal/claudewatcher/{scrubber,watcher}_test.go deliberately
|
|
# contain fake secret-shaped literals to test that the scrubber detects and
|
|
# redacts them. Verified 2026-08-04: all 9 findings here are test fixtures
|
|
# (github-pat, jwt, generic-api-key, homelab-authorization-bearer rules) plus
|
|
# 1 doc finding that was gitleaks matching the literal placeholder word
|
|
# "REDACTED" in a plan doc — not a real secret in either case.
|
|
[[allowlists]]
|
|
description = "claudewatcher scrubber test fixtures — deliberately fake secrets"
|
|
paths = [
|
|
'''ingestion/internal/claudewatcher/scrubber_test\.go$''',
|
|
'''ingestion/internal/claudewatcher/watcher_test\.go$''',
|
|
]
|
|
|
|
# infra#344: the allowlist that used to sit here is gone, and so is the reason
|
|
# for it. It suppressed docs/superpowers/plans/2026-04-22-phase4-attempt-wiring.md
|
|
# on the stated grounds that "extracted Secret == 'REDACTED' exactly ... the
|
|
# placeholder text itself, not a real credential" (verified 2026-08-04). That was
|
|
# not what the file contained: line 1054 carried a real 40-char hex Gitea PAT in
|
|
# an `Authorization: token ...` header. Confirmed dead by side-effect — GET
|
|
# /api/v1/user with it returns 401 — and redacted in that file, so there is now
|
|
# nothing to allowlist.
|
|
#
|
|
# The `paths` entry also made the block far broader than its description: gitleaks
|
|
# ORs global allowlist clauses and ignores `condition = "AND"`, so the whole file
|
|
# was immune, not just lines matching /REDACTED/. A live token added to that doc
|
|
# would have been suppressed on the strength of a note about a different value.
|