How It Works
Six gates, five hooks, eight commands and how they fit into Spec Kit's lifecycle.
The SDD lifecycle with speckit-security wired in
Spec Kit's native lifecycle has five phases: specify, plan,
tasks, implement, analyze. speckit-security layers six
gates on top of those phases via Spec Kit's hook system.
The after_specify and after_plan hooks run commands that
help the author write the data contract and threat model. The
gates themselves (A–F) are then all executed by gate-check.sh at
the before_implement hook — that's the single blocking step.
audit.sh runs at after_implement for the post-code scan, and
red-team runs at before_analyze.
The six gates
Each gate is an actual check run by a real bash script, not a checkbox on a form. Gates emit pass / fail / skip verdicts and append a JSONL entry to an append-only gate log.
Gate A, Data Contract
Data Contract section + Zod schema file, no z.any()
Gate B, Threat Model
Threat model section, no High/Critical unmitigated threats
Gate C, Model Governance
No unpinned model versions, rollback plan documented
Gate D, Guardrails
Guardrail YAML with blocked_patterns + redact_patterns
Gate E, Red Team
Red team report file present (runner is separate)
Gate F, Inline Content Scan
No inline system prompts, no committed secrets, no .env in git
Gate A, Data Contract
Runs three checks against the active spec and its schemas:
- The spec contains a
## 2. Data Contractor## Data Contractsection - A Zod schema file exists at
src/schemas/<slug>.ts - The schema file does not contain
z.any()(which bypasses type safety)
Blocks if any check fails. Note: the gate verifies the section and schema file exist, it does not parse the content of the section or enforce what's inside it. The reviewer is responsible for validating that PII, bias, drift, and retention policies are actually declared.
Gate B, Threat Model
Runs two checks:
- The spec contains a
## Security / Threat Modelsection (or a## Securitysection that mentionsSTRIDEorSpoofing) - No
[UNMITIGATED]markers exist adjacent toHighorCriticalseverity strings in the spec
Blocks if the section is missing or if the regex
[UNMITIGATED].*(High|Critical) matches.
Gate C, Model Governance
Only applies to features with an AI integration (detected by the
presence of AI Integration or model: in the spec). Runs two
checks:
- The spec does not contain
latest(anywhere) or"stable"(with quotes), both indicate an unpinned model version - The spec contains the word
Rollback(case-insensitive)
Blocks on unpinned versions or missing rollback mention. Note: the gate verifies the rollback mention, it does not parse the rollback plan to check triggers, target versions, or time budgets.
Gate D, Guardrails
Only runs when Gate C did not skip. Four checks:
prompts/guardrails/<slug>.ymlexistsprompts/system/<slug>.mdexists- The YAML contains
blocked_patterns: - The YAML contains
redact_patterns:
Blocks if any file is missing or if either pattern section is absent from the guardrail YAML.
Gate E, Red Team
Checks that a file matching red-team/RT-*-<slug>.md exists. Skips
with a warning if no file is found (red team is a VERIFY-phase
activity and not required at before_implement time).
The separate red-team-run.sh helper reads that report file, parses
scenarios from it, and POSTs them to a staging endpoint with safety
guards: refuses URLs matching prod/production, rate-limits to
max_rps (default 10), and injects an X-Red-Team header. That
script is triggered by the red-team command with the --run flag.
Gate F, Inline Content Scan
Three checks, in order:
- Inline prompts, greps
src/**/*.{ts,tsx,js,jsx,py}for patterns likeyou are a,as an ai,<|system|>(case-insensitive). Files withgatewayin their path are excluded so the gateway client itself can reference model SDKs. - Committed secrets, greps
*.ts,*.tsx,*.js,*.pyfiles across the repo (excludingnode_modules/,.git/,.next/,out/,.source/,.wrangler/, anddist/) forsk_live_,sk_test_,BEGIN (RSA|EC|OPENSSH) PRIVATE KEY,ghp_(GitHub personal tokens),AKIA[A-Z0-9]{16}(AWS), andAIza[A-Za-z0-9_-]{35}(Google). The post-implementationaudit.shscans an even wider set, includingxoxb-Slack tokens,gho_/ghs_,DSAandENCRYPTEDprivate keys, and also inspects.env*files directly. .envin git, runsgit ls-filesand checks for any path matching^\.env(\..*)?$.
Blocks if any of the three checks finds a hit.
Note: direct model SDK imports outside the gateway are checked
by audit.sh, not Gate F. Gate F is about inline prompts, secrets,
and committed .env only. See the audit command
for the direct-SDK-import check.
The five hooks
Hooks are how the gates fire automatically without the developer
remembering to run them. Each hook is registered in extension.yml
under the hooks: block.
| Hook | Command it runs | Blocking? |
|---|---|---|
after_specify | data-contract | Optional, prompts the user |
after_plan | threat-model | Optional, prompts the user |
before_implement | gate-check | Required, blocks on failure |
after_implement | audit | Required, blocks on critical findings |
before_analyze | red-team | Optional, prompts the user |
The eight commands
| Command | Purpose | Hook? |
|---|---|---|
/speckit.tekimax-security.data-contract | Declare data contract (schemas, PII, bias, drift, retention) | after_specify |
/speckit.tekimax-security.threat-model | Generate STRIDE threat model | after_plan |
/speckit.tekimax-security.model-governance | Pin model version, define eval criteria, rollback plan | manual |
/speckit.tekimax-security.guardrails | Generate input/output guardrail config | manual |
/speckit.tekimax-security.gate-check | Run all gates and emit verdict | before_implement |
/speckit.tekimax-security.audit | Post-implementation scan | after_implement |
/speckit.tekimax-security.red-team | Generate adversarial scenarios and run them | before_analyze |
/speckit.tekimax-security.install-rules | Install dev rules into docs, constitution, and agent context | manual |
Append-only gate log
Every gate-check run appends a JSONL entry to
.tekimax-security/gate-log.jsonl:
{"spec":"F-001","phase":"before_implement","verdict":"PASS","ts":"2026-04-13T08:30:00Z","user":"Christian Kaman","gates":{"A":"pass","B":"pass","C":"pass","D":"pass","E":"skip","F":"pass"}}Same for audit.sh → .tekimax-security/audit-log.jsonl. The log
is append-only by convention, never rewrite or delete entries. This
is the audit trail your compliance reviewer reads.
Runtime dependencies
The scripts use only standard tools that already ship with macOS
and Linux: bash, grep, sed, git, and python3. The shared
lib/config.sh helper shells out to python3 for a small inline
YAML reader so each script can fall back to config-defined
patterns, allowlists, and thresholds. install-rules.sh and
red-team-run.sh also use python3 for JSON handling.
No npm install. No pip install. No third-party Python packages,
just the standard library. No language runtime or package manager
beyond what your OS already provides. The full test suite runs in
under a second.