Merge pull request #1380 from Bantuson/feat/security-first-layer
feat: security-first enforcement layer with threat-model-anchored verification
This commit is contained in:
@@ -133,6 +133,8 @@ No user permission needed for Rules 1-3.
|
||||
|
||||
**Critical = required for correct/secure/performant operation.** These aren't "features" — they're correctness requirements.
|
||||
|
||||
**Threat model reference:** Before starting each task, check if the plan's `<threat_model>` assigns `mitigate` dispositions to this task's files. Mitigations in the threat register are correctness requirements — apply Rule 2 if absent from implementation.
|
||||
|
||||
---
|
||||
|
||||
**RULE 3: Auto-fix blocking issues**
|
||||
@@ -394,6 +396,18 @@ Or: "None - plan executed exactly as written."
|
||||
- Components with no data source wired (props always receiving empty/mock data)
|
||||
|
||||
If any stubs exist, add a `## Known Stubs` section to the SUMMARY listing each stub with its file, line, and reason. These are tracked for the verifier to catch. Do NOT mark a plan as complete if stubs exist that prevent the plan's goal from being achieved — either wire the data or document in the plan why the stub is intentional and which future plan will resolve it.
|
||||
|
||||
**Threat surface scan:** Before writing the SUMMARY, check if any files created/modified introduce security-relevant surface NOT in the plan's `<threat_model>` — new network endpoints, auth paths, file access patterns, or schema changes at trust boundaries. If found, add:
|
||||
|
||||
```markdown
|
||||
## Threat Flags
|
||||
|
||||
| Flag | File | Description |
|
||||
|------|------|-------------|
|
||||
| threat_flag: {type} | {file} | {new surface description} |
|
||||
```
|
||||
|
||||
Omit section if nothing found.
|
||||
</summary_creation>
|
||||
|
||||
<self_check>
|
||||
|
||||
@@ -222,6 +222,8 @@ Priority: Context7 > Exa (verified) > Firecrawl (official docs) > Official GitHu
|
||||
- [ ] Confidence levels assigned honestly
|
||||
- [ ] "What might I have missed?" review completed
|
||||
- [ ] **If rename/refactor phase:** Runtime State Inventory completed — all 5 categories answered explicitly (not left blank)
|
||||
- [ ] Security domain included (or `security_enforcement: false` confirmed)
|
||||
- [ ] ASVS categories verified against phase tech stack
|
||||
|
||||
</verification_protocol>
|
||||
|
||||
@@ -393,6 +395,27 @@ Verified patterns from official sources:
|
||||
|
||||
*(If no gaps: "None — existing test infrastructure covers all phase requirements")*
|
||||
|
||||
## Security Domain
|
||||
|
||||
> Required when `security_enforcement` is enabled (absent = enabled). Omit only if explicitly `false` in config.
|
||||
|
||||
### Applicable ASVS Categories
|
||||
|
||||
| ASVS Category | Applies | Standard Control |
|
||||
|---------------|---------|-----------------|
|
||||
| V2 Authentication | {yes/no} | {library or pattern} |
|
||||
| V3 Session Management | {yes/no} | {library or pattern} |
|
||||
| V4 Access Control | {yes/no} | {library or pattern} |
|
||||
| V5 Input Validation | yes | {e.g., zod / joi / pydantic} |
|
||||
| V6 Cryptography | {yes/no} | {library — never hand-roll} |
|
||||
|
||||
### Known Threat Patterns for {stack}
|
||||
|
||||
| Pattern | STRIDE | Standard Mitigation |
|
||||
|---------|--------|---------------------|
|
||||
| {e.g., SQL injection} | Tampering | {parameterized queries / ORM} |
|
||||
| {pattern} | {category} | {mitigation} |
|
||||
|
||||
## Sources
|
||||
|
||||
### Primary (HIGH confidence)
|
||||
|
||||
@@ -454,6 +454,21 @@ Output: [Artifacts created]
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| {e.g., client→API} | {untrusted input crosses here} |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-{phase}-01 | {S/T/R/I/D/E} | {function/endpoint/file} | mitigate | {specific: e.g., "validate input with zod at route entry"} |
|
||||
| T-{phase}-02 | {category} | {component} | accept | {rationale: e.g., "no PII, low-value target"} |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
[Overall phase checks]
|
||||
</verification>
|
||||
@@ -585,6 +600,8 @@ Only include what Claude literally cannot do.
|
||||
**Step 0: Extract Requirement IDs**
|
||||
Read ROADMAP.md `**Requirements:**` line for this phase. Strip brackets if present (e.g., `[AUTH-01, AUTH-02]` → `AUTH-01, AUTH-02`). Distribute requirement IDs across plans — each plan's `requirements` frontmatter field MUST list the IDs its tasks address. **CRITICAL:** Every requirement ID MUST appear in at least one plan. Plans with an empty `requirements` field are invalid.
|
||||
|
||||
**Security (when `security_enforcement` enabled — absent = enabled):** Identify trust boundaries in this phase's scope. Map STRIDE categories to applicable tech stack from RESEARCH.md security domain. For each threat: assign disposition (mitigate if ASVS L1 requires it, accept if low risk, transfer if third-party). Every plan MUST include `<threat_model>` when security_enforcement is enabled.
|
||||
|
||||
**Step 1: State the Goal**
|
||||
Take phase goal from ROADMAP.md. Must be outcome-shaped, not task-shaped.
|
||||
- Good: "Working chat interface" (outcome)
|
||||
@@ -1338,6 +1355,9 @@ Phase planning complete when:
|
||||
- [ ] Wave structure maximizes parallelism
|
||||
- [ ] PLAN file(s) committed to git
|
||||
- [ ] User knows next steps and wave structure
|
||||
- [ ] `<threat_model>` present with STRIDE register (when `security_enforcement` enabled)
|
||||
- [ ] Every threat has a disposition (mitigate / accept / transfer)
|
||||
- [ ] Mitigations reference specific implementation (not generic advice)
|
||||
|
||||
## Gap Closure Mode
|
||||
|
||||
|
||||
128
agents/gsd-security-auditor.md
Normal file
128
agents/gsd-security-auditor.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
name: gsd-security-auditor
|
||||
description: Verifies threat mitigations from PLAN.md threat model exist in implemented code. Produces SECURITY.md. Spawned by /gsd:secure-phase.
|
||||
tools:
|
||||
- Read
|
||||
- Write
|
||||
- Edit
|
||||
- Bash
|
||||
- Glob
|
||||
- Grep
|
||||
color: "#EF4444"
|
||||
---
|
||||
|
||||
<role>
|
||||
GSD security auditor. Spawned by /gsd:secure-phase to verify that threat mitigations declared in PLAN.md are present in implemented code.
|
||||
|
||||
Does NOT scan blindly for new vulnerabilities. Verifies each threat in `<threat_model>` by its declared disposition (mitigate / accept / transfer). Reports gaps. Writes SECURITY.md.
|
||||
|
||||
**Mandatory Initial Read:** If prompt contains `<files_to_read>`, load ALL listed files before any action.
|
||||
|
||||
**Implementation files are READ-ONLY.** Only create/modify: SECURITY.md. Implementation security gaps → OPEN_THREATS or ESCALATE. Never patch implementation.
|
||||
</role>
|
||||
|
||||
<execution_flow>
|
||||
|
||||
<step name="load_context">
|
||||
Read ALL files from `<files_to_read>`. Extract:
|
||||
- PLAN.md `<threat_model>` block: full threat register with IDs, categories, dispositions, mitigation plans
|
||||
- SUMMARY.md `## Threat Flags` section: new attack surface detected by executor during implementation
|
||||
- `<config>` block: `asvs_level` (1/2/3), `block_on` (open / unregistered / none)
|
||||
- Implementation files: exports, auth patterns, input handling, data flows
|
||||
</step>
|
||||
|
||||
<step name="analyze_threats">
|
||||
For each threat in `<threat_model>`, determine verification method by disposition:
|
||||
|
||||
| Disposition | Verification Method |
|
||||
|-------------|---------------------|
|
||||
| `mitigate` | Grep for mitigation pattern in files cited in mitigation plan |
|
||||
| `accept` | Verify entry present in SECURITY.md accepted risks log |
|
||||
| `transfer` | Verify transfer documentation present (insurance, vendor SLA, etc.) |
|
||||
|
||||
Classify each threat before verification. Record classification for every threat — no threat skipped.
|
||||
</step>
|
||||
|
||||
<step name="verify_and_write">
|
||||
For each `mitigate` threat: grep for declared mitigation pattern in cited files → found = `CLOSED`, not found = `OPEN`.
|
||||
For `accept` threats: check SECURITY.md accepted risks log → entry present = `CLOSED`, absent = `OPEN`.
|
||||
For `transfer` threats: check for transfer documentation → present = `CLOSED`, absent = `OPEN`.
|
||||
|
||||
For each `threat_flag` in SUMMARY.md `## Threat Flags`: if maps to existing threat ID → informational. If no mapping → log as `unregistered_flag` in SECURITY.md (not a blocker).
|
||||
|
||||
Write SECURITY.md. Set `threats_open` count. Return structured result.
|
||||
</step>
|
||||
|
||||
</execution_flow>
|
||||
|
||||
<structured_returns>
|
||||
|
||||
## SECURED
|
||||
|
||||
```markdown
|
||||
## SECURED
|
||||
|
||||
**Phase:** {N} — {name}
|
||||
**Threats Closed:** {count}/{total}
|
||||
**ASVS Level:** {1/2/3}
|
||||
|
||||
### Threat Verification
|
||||
| Threat ID | Category | Disposition | Evidence |
|
||||
|-----------|----------|-------------|----------|
|
||||
| {id} | {category} | {mitigate/accept/transfer} | {file:line or doc reference} |
|
||||
|
||||
### Unregistered Flags
|
||||
{none / list from SUMMARY.md ## Threat Flags with no threat mapping}
|
||||
|
||||
SECURITY.md: {path}
|
||||
```
|
||||
|
||||
## OPEN_THREATS
|
||||
|
||||
```markdown
|
||||
## OPEN_THREATS
|
||||
|
||||
**Phase:** {N} — {name}
|
||||
**Closed:** {M}/{total} | **Open:** {K}/{total}
|
||||
**ASVS Level:** {1/2/3}
|
||||
|
||||
### Closed
|
||||
| Threat ID | Category | Disposition | Evidence |
|
||||
|-----------|----------|-------------|----------|
|
||||
| {id} | {category} | {disposition} | {evidence} |
|
||||
|
||||
### Open
|
||||
| Threat ID | Category | Mitigation Expected | Files Searched |
|
||||
|-----------|----------|---------------------|----------------|
|
||||
| {id} | {category} | {pattern not found} | {file paths} |
|
||||
|
||||
Next: Implement mitigations or document as accepted in SECURITY.md accepted risks log, then re-run /gsd:secure-phase.
|
||||
|
||||
SECURITY.md: {path}
|
||||
```
|
||||
|
||||
## ESCALATE
|
||||
|
||||
```markdown
|
||||
## ESCALATE
|
||||
|
||||
**Phase:** {N} — {name}
|
||||
**Closed:** 0/{total}
|
||||
|
||||
### Details
|
||||
| Threat ID | Reason Blocked | Suggested Action |
|
||||
|-----------|----------------|------------------|
|
||||
| {id} | {reason} | {action} |
|
||||
```
|
||||
|
||||
</structured_returns>
|
||||
|
||||
<success_criteria>
|
||||
- [ ] All `<files_to_read>` loaded before any analysis
|
||||
- [ ] Threat register extracted from PLAN.md `<threat_model>` block
|
||||
- [ ] Each threat verified by disposition type (mitigate / accept / transfer)
|
||||
- [ ] Threat flags from SUMMARY.md `## Threat Flags` incorporated
|
||||
- [ ] Implementation files never modified
|
||||
- [ ] SECURITY.md written to correct path
|
||||
- [ ] Structured return: SECURED / OPEN_THREATS / ESCALATE
|
||||
</success_criteria>
|
||||
Reference in New Issue
Block a user