scripts: manifest bearer gate lands as manifest_bearer_gate.py (the .gitignore *secret* pattern silently un-tracks any 'secret'-named gate file - the previous commit's gate never made it into git); references updated
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Manifest bearer-literal gate (v0.53.0, part of the hub bearer de-git) — no bearer-shaped
|
||||
literal (64 hex chars, the `openssl rand -hex 32` shape every felhom bearer/API key uses) may
|
||||
appear ANYWHERE in manifests/, comments included. Secrets ride out-of-band `kubectl create
|
||||
secret` + secretKeyRef (documentation/runbooks/secrets.md); the manifests carry only
|
||||
placeholders. The other known committed secrets in felhom.secret.yaml (passwords, non-hex
|
||||
shapes) are a tracked backlog item (secrets.md) and are NOT matched by this gate — extend the
|
||||
patterns when they are de-gitted.
|
||||
|
||||
Run from the repo root: python scripts/manifest_bearer_gate.py
|
||||
Exit 1 on any hit.
|
||||
|
||||
(Named "bearer", not "secret": the repo .gitignore's `*secret*` pattern — which guards real
|
||||
secret files — would silently un-track a gate with "secret" in its filename.)
|
||||
"""
|
||||
import io, os, re, sys
|
||||
|
||||
ROOT = "manifests"
|
||||
|
||||
# 64 hex chars with no hex/word neighbors (so longer blobs and sha256-of-file hexes embedded in
|
||||
# longer strings still match at 64+, but ordinary short ids never do).
|
||||
BEARER = re.compile(r"(?<![0-9a-fA-F])[0-9a-fA-F]{64}(?![0-9a-fA-F])")
|
||||
|
||||
# KNOWN BACKLOG (non-fatal, stays VISIBLE): felhom.secret.yaml commits pre-existing secrets
|
||||
# (umami APP_SECRET is 64-hex) tracked for de-git in documentation/runbooks/secrets.md — out of
|
||||
# the bearer-de-git scope (2026-07-13 operator ruling batch). Remove this carve-out when that
|
||||
# file is cleaned; new bearer literals must NOT be hidden behind it.
|
||||
KNOWN_BACKLOG = {"felhom.secret.yaml"}
|
||||
|
||||
|
||||
def main():
|
||||
total = 0
|
||||
for fn in sorted(os.listdir(ROOT)):
|
||||
if not fn.endswith((".yaml", ".yml")):
|
||||
continue
|
||||
path = os.path.join(ROOT, fn)
|
||||
for lineno, line in enumerate(io.open(path, encoding="utf-8", errors="replace"), 1):
|
||||
for m in BEARER.finditer(line):
|
||||
masked = m.group(0)[:8] + "..." + m.group(0)[-4:]
|
||||
if fn in KNOWN_BACKLOG:
|
||||
print("%s:%d KNOWN-BACKLOG committed secret %s (secrets.md de-git backlog; not this gate's failure)"
|
||||
% (path, lineno, masked))
|
||||
continue
|
||||
total += 1
|
||||
print("%s:%d bearer-shaped literal %s" % (path, lineno, masked))
|
||||
if total:
|
||||
print("MANIFEST BEARER GATE FAILED: %d bearer-shaped literal(s) in manifests/" % total)
|
||||
sys.exit(1)
|
||||
print("manifest bearer gate OK - no bearer-shaped literals in manifests/")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user