Add a deterministic (no-LLM) security sub-gate on the deploy-staging -> deploy edge, run FIRST (before merge-gate ORCH-043 and image-freshness ORCH-058) so it fails cheaply before any expensive rebase/rebuild, and scans origin/main..HEAD before rebase so a task is never blamed for a CVE introduced by an updated main. Why: the autonomous pipeline merged branches into main with no check for a leaked secret or a vulnerable dependency. For the self-hosting orchestrator (one shared prod instance serving every project from a shared DB) a single leak/CVE landed in the prod of all projects (CLAUDE.md self-hosting, section 8). - New leaf src/security_gate.py (never-raise): gitleaks (offline, fail-closed on tool error => secrets guarantee is unconditional) + pip-audit (best-effort; unreachable CVE feed degrades fail-open + loud warning by default, strict via security_dep_audit_fail_closed). Verdict lives ONLY in 17-security-report.md YAML frontmatter (write -> read-back single source of truth); FAIL is authoritative; missing/broken frontmatter => fail-closed. - check_security_gate thin wrapper registered in QG_CHECKS (lazy import, no cycle). - _handle_security_gate wired FIRST in advance_stage deploy-staging block: FAIL -> rollback to development + developer-retry (cap MAX_DEVELOPER_RETRIES); task_desc carries verbatim findings (ORCH-046 pattern). No merge-lease release (runs before lease acquire). Self-hosting safe: only reads/scans/writes, never deploys. - Conditional rollout (security_gate_enabled + security_gate_repos; empty scope -> self-hosting only). 6 new ORCH_SECURITY_* settings. - Infra: pinned gitleaks Go binary in Dockerfile (+curl/ca-certificates), pip-audit in requirements.txt, versioned .gitleaks.toml at repo root. - STAGE_TRANSITIONS and DB schema unchanged. Docs: docs/architecture/README.md (marked realized), CLAUDE.md (artifact 17), CHANGELOG.md. Tests: test_security_gate.py, test_qg_security.py, test_stage_engine_security_gate.py + updated registry/edge snapshots. Refs: ORCH-022 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
39 lines
1.7 KiB
TOML
39 lines
1.7 KiB
TOML
# gitleaks config — ORCH-022 security-gate (secret-scanning).
|
|
#
|
|
# Versioned in the repo root (07-infra I-4 / BR-13): rules + an allowlist of
|
|
# known-safe matches are reviewed as code. The security-gate (src/security_gate.py)
|
|
# passes this file via `--config` when present. gitleaks runs OFFLINE (local rules)
|
|
# so the "a secret always blocks" guarantee (BR-2) never depends on the network.
|
|
#
|
|
# Strategy: extend the built-in ruleset (broad coverage, maintained upstream) and
|
|
# only ADD a narrow allowlist for placeholders / fixtures that are intentionally
|
|
# fake (e.g. .env.example dummy values, test fixtures). Keep the allowlist tight —
|
|
# an over-broad allowlist silently re-opens the leak it was meant to bless.
|
|
|
|
title = "orchestrator gitleaks config"
|
|
|
|
[extend]
|
|
# Start from gitleaks' maintained default ruleset.
|
|
useDefault = true
|
|
|
|
[allowlist]
|
|
description = "Known-safe, intentionally non-secret matches (placeholders + fixtures)."
|
|
|
|
# Files that legitimately contain placeholder/dummy secret-shaped values:
|
|
# * .env.example — the committed canon of env vars with DUMMY values (CLAUDE.md §8;
|
|
# real secrets live only in the host .env / .env.staging, never in git).
|
|
# * tests/ — fixtures may embed fake tokens to exercise the scanner itself (TC-03).
|
|
# * .gitleaks.toml — this file (avoid self-matching example patterns below).
|
|
paths = [
|
|
'''(^|/)\.env\.example$''',
|
|
'''(^|/)tests/''',
|
|
'''(^|/)\.gitleaks\.toml$''',
|
|
]
|
|
|
|
# Generic placeholder tokens used in docs / examples that are NOT real secrets.
|
|
regexes = [
|
|
'''(?i)(your[-_]?(token|key|secret|password)[-_]?here)''',
|
|
'''(?i)(changeme|dummy|example|placeholder|xxxxx+)''',
|
|
'''(?i)<[a-z0-9_-]+>''',
|
|
]
|