feat(security): security-gate (gitleaks secret-scan + pip-audit) before merge
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>
This commit is contained in:
@@ -219,6 +219,36 @@ class Settings(BaseSettings):
|
||||
image_freshness_enabled: bool = True
|
||||
image_freshness_repos: str = ""
|
||||
|
||||
# ORCH-022: security-gate (secret-scanning + dependency audit) on the
|
||||
# deploy-staging -> deploy edge, run FIRST among the edge sub-gates (cheap to
|
||||
# fail before the expensive rebase/rebuild). Deterministic (no LLM): gitleaks
|
||||
# (offline secret-scan) + pip-audit (OSV/PyPI dependency audit), verdict in the
|
||||
# versioned 17-security-report.md frontmatter; FAIL -> rollback to development +
|
||||
# developer-retry (cap MAX_DEVELOPER_RETRIES). See ADR-001-security-gate.md.
|
||||
# security_gate_enabled -> SINGLE kill-switch; False -> pipeline 1:1 as
|
||||
# before ORCH-022 for everyone. Env
|
||||
# ORCH_SECURITY_GATE_ENABLED.
|
||||
# security_gate_repos -> CSV of repos where the gate is REAL; empty ->
|
||||
# only the self-hosting repo (orchestrator).
|
||||
# Mirrors merge_gate_repos / image_freshness_repos.
|
||||
# security_dep_block_severity -> CVE severity threshold that BLOCKS (CRITICAL >
|
||||
# HIGH > MEDIUM > LOW); below it / UNKNOWN -> a
|
||||
# warning only (anti-loop ADR-001 Р-4).
|
||||
# security_scan_timeout_s -> per external scanner call timeout (mirrors
|
||||
# merge_retest_timeout_s).
|
||||
# security_dep_audit_fail_closed -> strict mode: an unreachable CVE feed -> FAIL
|
||||
# instead of the default fail-open + warning
|
||||
# (Р-3). Default False (anti-loop ORCH-061).
|
||||
# security_secrets_block -> a found secret blocks (always True by default;
|
||||
# the offline secrets guarantee is unconditional,
|
||||
# BR-2).
|
||||
security_gate_enabled: bool = True
|
||||
security_gate_repos: str = ""
|
||||
security_dep_block_severity: str = "HIGH"
|
||||
security_scan_timeout_s: int = 300
|
||||
security_dep_audit_fail_closed: bool = False
|
||||
security_secrets_block: bool = True
|
||||
|
||||
# ORCH-061: tolerate KNOWN sandbox-infra FAILs (C9a/C9b) in the staging suite.
|
||||
# The self-hosting deploy-staging stage looped because scripts/staging_check.py
|
||||
# exited non-zero on ANY failed check, so two infra-only failures (sandbox bot
|
||||
|
||||
Reference in New Issue
Block a user