Skip to content

epic: enforced security hooks — deterministic security enforcement for Claude Code #235

Description

@rocklambros

Epic: Enforced Security Hooks

Vision

Transform ZERG's security rules from informational .md files (non-deterministic, LLM may ignore) into enforced hooks (deterministic, code cannot bypass). Security violations are caught at write-time, blocked, and auto-remediated using TikiTribe rule examples.

Problem

Today, security rules fetched from TikiTribe/claude-secure-coding-rules are stored as .claude/rules/security/*.md files. Claude Code auto-loads them into context, but:

  • LLM compliance is non-deterministic — rules may or may not be followed
  • No runtime enforcement — insecure code can be written and committed
  • Pre-commit hook exists but is never installed (dead code)
  • Security quality gate is configured as required: false
  • Pattern registry (1017 lines) duplicated between Python and shell hook (390 lines)

Architecture

┌─────────────────────────────────────────────────┐
│              Claude Code Session                 │
│                                                  │
│  Write/Edit ──→ PostToolUse Hook                │
│                    │                             │
│                    ├── Layer 1: Command Hook     │
│                    │   semgrep + regex + CVE     │
│                    │   (deterministic)           │
│                    │                             │
│                    ├── Layer 2: Prompt Hook      │
│                    │   TikiTribe rules filtered  │
│                    │   by file type (~100 tokens) │
│                    │   (semantic analysis)        │
│                    │                             │
│                    └── Violation? ──→ Block      │
│                         │    ↓                   │
│                         │  Inject 'Do' example   │
│                         │    ↓                   │
│                         │  Worker rewrites       │
│                         │    ↓                   │
│                         │  Re-scan (3x max)      │
│                         │    ↓                   │
│                         └── Escalate to human    │
│                                                  │
│  git commit ──→ Pre-commit Hook                 │
│                    python -m zerg.security.scanner│
│                    (same unified scanner)         │
│                                                  │
│  /zerg:merge ──→ Full project scan              │
│                    SARIF → GitHub Security tab   │
│                                                  │
│  All findings → .zerg/security/findings.json    │
└─────────────────────────────────────────────────┘

Decisions Made (Brainstorm Session)

Decision Choice Reasoning
SAST tool Semgrep only (no bandit) p/bandit ruleset covers 95% of bandit. One tool, 30+ languages
Hook type Layered: command + prompt Deterministic tools for patterns, semantic prompt for context
Trigger point PostToolUse(Write/Edit) Catch after write, enable rewrite. Most practical
Scope Project-wide (.claude/settings.json) All sessions get enforcement, not just ZERG workers
Violation handling Block + inject 'Do' example + 3 retries Strongest guarantee with auto-remediation
Scan scope Changed file + AST-resolved imports Catches cross-file issues without full project scan
Context engineering filter_rules_for_files() ~100-200 tokens per check. Already implemented
Findings store Local JSON + SARIF to GitHub Audit trail + PR annotations
Pre-commit Replace shell with Python Single source of truth, eliminates 390 lines of duplication
Tool install Auto during init + devcontainer bundle User confirmation required, bypass available

Phased Roadmap

Phase 1: Foundation (P1)

Phase 2: Integration (P2)

Dependency Graph

#228 Unified Scanner (FOUNDATION)
 ├──→ #229 PostToolUse Hook
 │     ├──→ #233 Import Resolver
 │     └──→ #234 Violation Handling
 ├──→ #230 Python Pre-Commit Hook
 └──→ #232 Findings Store
        └──→ #234 Violation Handling

#231 Semgrep Install (parallel, no deps)

Key Constraint

All enforcement is opt-in during init and configurable via .zerg/config.yaml. Users can disable hooks, choose regex-only fallback, or customize severity thresholds. The system never silently installs tools or blocks without explanation.

Source

Brainstorm session: /zerg:brainstorm security-hooks-enforcement
Research: Claude Code hooks documentation, semgrep vs bandit analysis, ZERG security infrastructure audit

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityarchitectureArchitectural improvementsenhancementNew feature or requestsecuritySecurity vulnerabilities and hardening

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions