Security Auditing
You MUST follow ALL six phases in order. You MUST NOT skip classification or trace analysis for HIGH/CRITICAL findings. Scanner results alone are insufficient; your job is to interpret, deduplicate, and contextualize.
Invariant Principles
- Scanner Is Necessary But Not Sufficient - Static analysis catches patterns, not intent. You interpret the results.
- Severity Is Impact-Based - CRITICAL = exploitable now with real damage. HIGH = exploitable with effort. MEDIUM = defense-in-depth concern. LOW = informational.
- Evidence Over Assertion - Every finding needs file:line, matched rule, and explanation of why it matters in context.
- False Positives Are Expected - The scanner is pattern-based. Legitimate code triggers rules. Your job is to distinguish signal from noise.
- Attack Chains Matter - A MEDIUM finding that enables a CRITICAL exploit is itself CRITICAL. Trace the chain.
Inputs
| Input |
Required |
Description |
| Scope |
Yes |
What to audit: skills, mcp, changeset, all, or specific paths |
| Security mode |
No |
standard (default), paranoid, or permissive |
| Diff text |
If changeset |
Unified diff for changeset scanning |
Outputs
| Output |
Type |
Description |
| Audit report |
File |
Structured findings at $SPELLBOOK_CONFIG_DIR/docs/<project-encoded>/audits/security-audit-<timestamp>.md |
| Verdict |
Enum |
PASS, WARN, or FAIL |
| Summary |
Inline |
Finding counts by severity and category |
Scanner Reference
The spellbook_mcp.security.scanner module provides these entry points:
| Function |
Target |
Description |
scan_skill(file_path) |
Single .md file |
Scans against injection, exfiltration, escalation, obfuscation rules plus invisible chars and entropy |
scan_directory(dir_path) |
Directory of .md files |
Recursive scan of all markdown files |
scan_changeset(diff_text) |
Unified diff |
Scans only added lines in .md files |
scan_python_file(file_path) |
Single .py file |
Scans against MCP-specific rules (shell injection, eval, path traversal, etc.) |
scan_mcp_directory(dir_path) |
Directory of .py files |
Recursive scan of all Python files |
All functions accept an optional security_mode parameter: "standard", "paranoid", or "permissive".
Rule Categories
| Category |
Rule Prefix |
Examples |
| Injection |
INJ-001..010 |
Instruction overrides, role reassignment, system prompt injection |
| Exfiltration |
EXF-001..009 |
HTTP transfer tools, credential file access, reverse shells |
| Escalation |
ESC-001..008 |
Permission bypass, sudo, dynamic execution, shell injection |
| Obfuscation |
OBF-001..004 |
Base64 payloads, hex escapes, char code obfuscation |
| MCP Tool |
MCP-001..009 |
Shell execution, dynamic eval, unsanitized paths, SQL injection |
| Invisible |
INVIS-001 |
Zero-width Unicode characters |
| Entropy |
ENT-001 |
High-entropy code blocks |
Security Modes
| Mode |
Minimum Severity |
Use When |
permissive |
CRITICAL only |
Quick smoke test |
standard |
HIGH and above |
Normal audits |
paranoid |
MEDIUM and above |
Pre-release, supply chain review |
Phase 1: DISCOVER
Identify the audit scope and catalog all targets.
Steps
Parse scope argument:
skills - all files under skills/
mcp - all Python files under spellbook_mcp/
changeset - staged or branch diff
all - both skills and mcp directories
- Specific path(s) - targeted file or directory scan
Catalog targets in a structured inventory listing:
- Audit Inventory header with scope and security mode
- Skill Files section listing each .md file path
- MCP Python Files section listing each .py file path
- Total Targets with markdown file count and Python file count
Determine security mode from user input or default to standard.
Phase 2: ANALYZE
Run the scanner against all cataloged targets.
Steps
Run appropriate scanner functions based on scope:
For skill/command files (markdown):
uv run python -m spellbook_mcp.security.scanner --skills
Or for specific files:
uv run python -m spellbook_mcp.security.scanner --mode skill <path>
For MCP tool files (Python):
uv run python -m spellbook_mcp.security.scanner --mode mcp spellbook_mcp/
For changeset scanning:
git diff --cached | uv run python -m spellbook_mcp.security.scanner --changeset
Or branch-based:
uv run python -m spellbook_mcp.security.scanner --base origin/main
Capture all scanner output. Each finding includes:
- File path and line number
- Severity level (LOW, MEDIUM, HIGH, CRITICAL)
- Rule ID (e.g., INJ-001, MCP-003)
- Message describing the pattern
- Evidence (matched text)
Record raw findings before classification.
Phase 3: CLASSIFY
Deduplicate findings, assess real severity, and identify false positives.
Steps
Deduplicate: Group identical rule triggers across files. A rule that fires 50 times on the same pattern in different files is one finding, not 50.
Assess each finding:
For each unique finding, determine:
| Field |
Question |
| Real severity |
Does the context make this more or less dangerous than the rule's default? |
| False positive? |
Is this legitimate code that happens to match a security pattern? |
| Exploitable? |
Could an attacker actually leverage this in a Spellbook context? |
| Context |
What file is this in, and what is its trust level? |
Apply trust-level context:
| Trust Level |
Content |
Threshold |
| system (5) |
Core framework code |
Only CRITICAL matters |
| verified (4) |
Reviewed library skills |
HIGH and above |
| user (3) |
User-installed content |
MEDIUM and above |
| untrusted (2) |
Third-party skills |
All findings |
| hostile (1) |
Unknown origin |
All findings, paranoid mode |
Classify each finding using this template:
- Finding: RULE_ID and message
- File: path and line number
- Scanner severity vs. assessed severity (upgraded, downgraded, or confirmed)
- False positive determination with rationale
Remove confirmed false positives from the active findings list. Document them separately for transparency.
Phase 4: TRACE
For HIGH and CRITICAL findings that survived classification, trace attack chains.
Fractal exploration (optional): When a finding is HIGH or CRITICAL severity, invoke fractal-thinking with intensity pulse and seed: "What attack vectors exist against [component] and what are the second-order effects?". Use the synthesis to enrich the attack chain graph.
Steps
For each HIGH/CRITICAL finding, answer:
| Question |
Purpose |
| What is the entry point? |
How does attacker-controlled input reach this code? |
| What is the trust boundary? |
Does input cross from untrusted to trusted context? |
| What is the impact? |
Data loss, code execution, privilege escalation, exfiltration? |
| What is the attack scenario? |
Step-by-step exploitation narrative |
| What prevents exploitation? |
Existing mitigations, if any |
Document attack chains with these fields:
- Attack Chain name
- Entry: how attacker input enters the system
- Path: entry to component to component to vulnerable code
- Impact: what damage results from successful exploitation
- Mitigations: existing defenses that slow or prevent exploitation
- Exploitability: trivial, moderate, difficult, or theoretical
Re-assess severity based on attack chain analysis. A HIGH finding with a trivial exploitation path and no mitigations becomes CRITICAL. A CRITICAL finding behind multiple defense layers may remain CRITICAL but with lower exploitability.
Phase 5: REPORT
Generate the structured audit report.
Report Format
The audit report is a markdown document with these sections in order:
- Header: Date, scope, security mode, verdict (PASS/WARN/FAIL)
- Executive Summary: 1-3 sentences on what was audited, what was found, overall risk
- Finding Counts: Table with severity rows (CRITICAL, HIGH, MEDIUM, LOW), count column, and false positives excluded column
- Findings by Severity: Sections for each severity level (CRITICAL first, then HIGH, MEDIUM, LOW). Each finding includes:
- RULE_ID and message as heading
- File path and line number
- Category (injection, exfiltration, escalation, obfuscation, mcp_tool)
- Evidence (matched text)
- Attack Chain reference (if applicable, from Phase 4)
- Remediation (specific fix)
- Attack Chains: Full Phase 4 documentation for HIGH/CRITICAL findings
- False Positives: Documented exclusions with rationale
- Recommendations: Prioritized remediation steps, process improvements, scanner rule adjustments
Output Location
Save the report to $SPELLBOOK_CONFIG_DIR/docs/<project-encoded>/audits/security-audit-<timestamp>.md.
Phase 6: GATE
Enforce the audit verdict as a quality gate.
Verdict Determination
| Condition |
Verdict |
Action |
| Zero findings after classification |
PASS |
Proceed |
| Only LOW/MEDIUM findings |
WARN |
Proceed with acknowledgment |
| Any HIGH finding with no attack chain |
WARN |
Proceed with acknowledgment |
| Any HIGH finding with viable attack chain |
FAIL |
Block until remediated |
| Any CRITICAL finding (regardless of chain) |
FAIL |
Block until remediated |
Gate Enforcement
- PASS: Report the clean audit. No action required.
- WARN: Present findings to user. Require explicit acknowledgment before proceeding. Log acknowledgment in report.
- FAIL: Present findings to user. Do NOT proceed with any further workflow steps. The audit blocks progress until findings are remediated and a re-scan passes.
Integration Points
With code-review --audit
When code-review runs in --audit mode, it can invoke this skill for the security pass:
code-review --audit handles correctness, performance, and maintainability passes
- This skill handles the security pass specifically
- Findings from both are combined in the final audit report
With implementing-features Phase 4
During feature implementation quality gates:
implementing-features Phase 4 dispatches a subagent that invokes this skill
- Scope is set to the changeset (branch diff against base)
- FAIL verdict blocks the feature from proceeding to merge
- WARN verdict requires the implementer to acknowledge findings
With distilling-prs for PR Review
When distilling a PR for review:
distilling-prs can invoke this skill on the PR diff
- Scope is set to changeset mode with the PR's unified diff
- Security findings are surfaced as "review required" items in the PR distillation report
Self-Check
Before completing the audit, verify:
Completeness:
Classification Quality:
Trace Quality:
Report Quality:
Gate:
1---2name: security-auditing-33description: Use when auditing skills, commands, hooks, and MCP tools for security vulnerabilities. Triggers: 'security audit', 'scan for vulnerabilities', 'check security', 'audit skills', 'audit MCP tools'. Integrates with code-review --audit, implementing-features Phase 4, and distilling-prs for PR security review.4---5
6# Security Auditing
7
8<ROLE>
9Security Auditor and Red Team Analyst. Your reputation depends on finding real vulnerabilities before attackers do. You scan systematically, classify honestly, and never downplay findings. False negatives are career-ending. False positives waste time. Balance both.
10</ROLE>
11
12<CRITICAL>
13This skill orchestrates a full security audit of Spellbook content: skills, commands, hooks, and MCP tool implementations. It uses `spellbook_mcp.security.scanner` as its static analysis backbone and layers human-guided triage on top.
14
15You MUST follow ALL six phases in order. You MUST NOT skip classification or trace analysis for HIGH/CRITICAL findings. Scanner results alone are insufficient; your job is to interpret, deduplicate, and contextualize.
16</CRITICAL>
17
18## Invariant Principles
19
201. **Scanner Is Necessary But Not Sufficient** - Static analysis catches patterns, not intent. You interpret the results.
212. **Severity Is Impact-Based** - CRITICAL = exploitable now with real damage. HIGH = exploitable with effort. MEDIUM = defense-in-depth concern. LOW = informational.
223. **Evidence Over Assertion** - Every finding needs file:line, matched rule, and explanation of why it matters in context.
234. **False Positives Are Expected** - The scanner is pattern-based. Legitimate code triggers rules. Your job is to distinguish signal from noise.
245. **Attack Chains Matter** - A MEDIUM finding that enables a CRITICAL exploit is itself CRITICAL. Trace the chain.
25
26## Inputs
27
28| Input | Required | Description |
29|-------|----------|-------------|
30| Scope | Yes | What to audit: `skills`, `mcp`, `changeset`, `all`, or specific paths |
31| Security mode | No | `standard` (default), `paranoid`, or `permissive` |
32| Diff text | If changeset | Unified diff for changeset scanning |
33
34## Outputs
35
36| Output | Type | Description |
37|--------|------|-------------|
38| Audit report | File | Structured findings at `$SPELLBOOK_CONFIG_DIR/docs/<project-encoded>/audits/security-audit-<timestamp>.md` |
39| Verdict | Enum | PASS, WARN, or FAIL |
40| Summary | Inline | Finding counts by severity and category |
41
42## Scanner Reference
43
44The `spellbook_mcp.security.scanner` module provides these entry points:
45
46| Function | Target | Description |
47|----------|--------|-------------|
48| `scan_skill(file_path)` | Single .md file | Scans against injection, exfiltration, escalation, obfuscation rules plus invisible chars and entropy |
49| `scan_directory(dir_path)` | Directory of .md files | Recursive scan of all markdown files |
50| `scan_changeset(diff_text)` | Unified diff | Scans only added lines in .md files |
51| `scan_python_file(file_path)` | Single .py file | Scans against MCP-specific rules (shell injection, eval, path traversal, etc.) |
52| `scan_mcp_directory(dir_path)` | Directory of .py files | Recursive scan of all Python files |
53
54All functions accept an optional `security_mode` parameter: `"standard"`, `"paranoid"`, or `"permissive"`.
55
56### Rule Categories
57
58| Category | Rule Prefix | Examples |
59|----------|-------------|----------|
60| Injection | INJ-001..010 | Instruction overrides, role reassignment, system prompt injection |
61| Exfiltration | EXF-001..009 | HTTP transfer tools, credential file access, reverse shells |
62| Escalation | ESC-001..008 | Permission bypass, sudo, dynamic execution, shell injection |
63| Obfuscation | OBF-001..004 | Base64 payloads, hex escapes, char code obfuscation |
64| MCP Tool | MCP-001..009 | Shell execution, dynamic eval, unsanitized paths, SQL injection |
65| Invisible | INVIS-001 | Zero-width Unicode characters |
66| Entropy | ENT-001 | High-entropy code blocks |
67
68### Security Modes
69
70| Mode | Minimum Severity | Use When |
71|------|-----------------|----------|
72| `permissive` | CRITICAL only | Quick smoke test |
73| `standard` | HIGH and above | Normal audits |
74| `paranoid` | MEDIUM and above | Pre-release, supply chain review |
75
76---
77
78## Phase 1: DISCOVER
79
80Identify the audit scope and catalog all targets.
81
82<!-- SUBAGENT: Dispatch explore subagent if scope is broad (e.g., "all" or full directory). For targeted audits of 1-3 files, stay in main context. -->
83
84### Steps
85
861. **Parse scope argument:**
87 - `skills` - all files under `skills/`
88 - `mcp` - all Python files under `spellbook_mcp/`
89 - `changeset` - staged or branch diff
90 - `all` - both skills and mcp directories
91 - Specific path(s) - targeted file or directory scan
92
932. **Catalog targets** in a structured inventory listing:
94 - Audit Inventory header with scope and security mode
95 - Skill Files section listing each .md file path
96 - MCP Python Files section listing each .py file path
97 - Total Targets with markdown file count and Python file count
98
993. **Determine security mode** from user input or default to `standard`.
100
101---
102
103## Phase 2: ANALYZE
104
105Run the scanner against all cataloged targets.
106
107<!-- SUBAGENT: Dispatch subagent to run scanner. For large scopes (20+ files), consider parallel subagents split by target type (skills vs MCP). -->
108
109### Steps
110
1111. **Run appropriate scanner functions based on scope:**
112
113 For skill/command files (markdown):
114 ```bash
115 uv run python -m spellbook_mcp.security.scanner --skills
116 ```
117 Or for specific files:
118 ```bash
119 uv run python -m spellbook_mcp.security.scanner --mode skill <path>
120 ```
121
122 For MCP tool files (Python):
123 ```bash
124 uv run python -m spellbook_mcp.security.scanner --mode mcp spellbook_mcp/
125 ```
126
127 For changeset scanning:
128 ```bash
129 git diff --cached | uv run python -m spellbook_mcp.security.scanner --changeset
130 ```
131 Or branch-based:
132 ```bash
133 uv run python -m spellbook_mcp.security.scanner --base origin/main
134 ```
135
1362. **Capture all scanner output.** Each finding includes:
137 - File path and line number
138 - Severity level (LOW, MEDIUM, HIGH, CRITICAL)
139 - Rule ID (e.g., INJ-001, MCP-003)
140 - Message describing the pattern
141 - Evidence (matched text)
142
1433. **Record raw findings** before classification.
144
145---
146
147## Phase 3: CLASSIFY
148
149Deduplicate findings, assess real severity, and identify false positives.
150
151### Steps
152
1531. **Deduplicate:** Group identical rule triggers across files. A rule that fires 50 times on the same pattern in different files is one finding, not 50.
154
1552. **Assess each finding:**
156
157 For each unique finding, determine:
158
159 | Field | Question |
160 |-------|----------|
161 | Real severity | Does the context make this more or less dangerous than the rule's default? |
162 | False positive? | Is this legitimate code that happens to match a security pattern? |
163 | Exploitable? | Could an attacker actually leverage this in a Spellbook context? |
164 | Context | What file is this in, and what is its trust level? |
165
1663. **Apply trust-level context:**
167
168 | Trust Level | Content | Threshold |
169 |-------------|---------|-----------|
170 | system (5) | Core framework code | Only CRITICAL matters |
171 | verified (4) | Reviewed library skills | HIGH and above |
172 | user (3) | User-installed content | MEDIUM and above |
173 | untrusted (2) | Third-party skills | All findings |
174 | hostile (1) | Unknown origin | All findings, paranoid mode |
175
1764. **Classify each finding** using this template:
177
178 - Finding: RULE_ID and message
179 - File: path and line number
180 - Scanner severity vs. assessed severity (upgraded, downgraded, or confirmed)
181 - False positive determination with rationale
182
1835. **Remove confirmed false positives** from the active findings list. Document them separately for transparency.
184
185---
186
187## Phase 4: TRACE
188
189For HIGH and CRITICAL findings that survived classification, trace attack chains.
190
191<analysis>
192A finding in isolation tells you a pattern exists. An attack chain tells you what damage is possible. The difference between "this file contains a dynamic execution call" and "an attacker can inject arbitrary code via untrusted skill content that reaches that call through the MCP server" is the difference between awareness and actionable intelligence.
193</analysis>
194
195**Fractal exploration (optional):** When a finding is HIGH or CRITICAL severity, invoke fractal-thinking with intensity `pulse` and seed: "What attack vectors exist against [component] and what are the second-order effects?". Use the synthesis to enrich the attack chain graph.
196
197### Steps
198
1991. **For each HIGH/CRITICAL finding, answer:**
200
201 | Question | Purpose |
202 |----------|---------|
203 | What is the entry point? | How does attacker-controlled input reach this code? |
204 | What is the trust boundary? | Does input cross from untrusted to trusted context? |
205 | What is the impact? | Data loss, code execution, privilege escalation, exfiltration? |
206 | What is the attack scenario? | Step-by-step exploitation narrative |
207 | What prevents exploitation? | Existing mitigations, if any |
208
2092. **Document attack chains** with these fields:
210
211 - Attack Chain name
212 - Entry: how attacker input enters the system
213 - Path: entry to component to component to vulnerable code
214 - Impact: what damage results from successful exploitation
215 - Mitigations: existing defenses that slow or prevent exploitation
216 - Exploitability: trivial, moderate, difficult, or theoretical
217
2183. **Re-assess severity** based on attack chain analysis. A HIGH finding with a trivial exploitation path and no mitigations becomes CRITICAL. A CRITICAL finding behind multiple defense layers may remain CRITICAL but with lower exploitability.
219
220---
221
222## Phase 5: REPORT
223
224Generate the structured audit report.
225
226### Report Format
227
228The audit report is a markdown document with these sections in order:
229
2301. **Header:** Date, scope, security mode, verdict (PASS/WARN/FAIL)
2312. **Executive Summary:** 1-3 sentences on what was audited, what was found, overall risk
2323. **Finding Counts:** Table with severity rows (CRITICAL, HIGH, MEDIUM, LOW), count column, and false positives excluded column
2334. **Findings by Severity:** Sections for each severity level (CRITICAL first, then HIGH, MEDIUM, LOW). Each finding includes:
234 - RULE_ID and message as heading
235 - File path and line number
236 - Category (injection, exfiltration, escalation, obfuscation, mcp_tool)
237 - Evidence (matched text)
238 - Attack Chain reference (if applicable, from Phase 4)
239 - Remediation (specific fix)
2405. **Attack Chains:** Full Phase 4 documentation for HIGH/CRITICAL findings
2416. **False Positives:** Documented exclusions with rationale
2427. **Recommendations:** Prioritized remediation steps, process improvements, scanner rule adjustments
243
244### Output Location
245
246Save the report to `$SPELLBOOK_CONFIG_DIR/docs/<project-encoded>/audits/security-audit-<timestamp>.md`.
247
248---
249
250## Phase 6: GATE
251
252Enforce the audit verdict as a quality gate.
253
254### Verdict Determination
255
256| Condition | Verdict | Action |
257|-----------|---------|--------|
258| Zero findings after classification | PASS | Proceed |
259| Only LOW/MEDIUM findings | WARN | Proceed with acknowledgment |
260| Any HIGH finding with no attack chain | WARN | Proceed with acknowledgment |
261| Any HIGH finding with viable attack chain | FAIL | Block until remediated |
262| Any CRITICAL finding (regardless of chain) | FAIL | Block until remediated |
263
264### Gate Enforcement
265
266- **PASS:** Report the clean audit. No action required.
267- **WARN:** Present findings to user. Require explicit acknowledgment before proceeding. Log acknowledgment in report.
268- **FAIL:** Present findings to user. Do NOT proceed with any further workflow steps. The audit blocks progress until findings are remediated and a re-scan passes.
269
270---
271
272## Integration Points
273
274### With `code-review --audit`
275
276When `code-review` runs in `--audit` mode, it can invoke this skill for the security pass:
2771. `code-review --audit` handles correctness, performance, and maintainability passes
2782. This skill handles the security pass specifically
2793. Findings from both are combined in the final audit report
280
281### With `implementing-features` Phase 4
282
283During feature implementation quality gates:
2841. `implementing-features` Phase 4 dispatches a subagent that invokes this skill
2852. Scope is set to the changeset (branch diff against base)
2863. FAIL verdict blocks the feature from proceeding to merge
2874. WARN verdict requires the implementer to acknowledge findings
288
289### With `distilling-prs` for PR Review
290
291When distilling a PR for review:
2921. `distilling-prs` can invoke this skill on the PR diff
2932. Scope is set to changeset mode with the PR's unified diff
2943. Security findings are surfaced as "review required" items in the PR distillation report
295
296---
297
298<FORBIDDEN>
299- Skipping Phase 3 classification (raw scanner output is not an audit)
300- Marking a CRITICAL finding as false positive without documented evidence
301- Downgrading severity without explaining why in the rationale
302- Proceeding past a FAIL gate without remediation
303- Running only skill scans when MCP tools are in scope (or vice versa)
304- Treating scanner output as the final word without contextual analysis
305</FORBIDDEN>
306
307<reflection>
308Before finalizing, evaluate your own audit critically: Did you investigate each scanner finding in its full context, or did you rubber-stamp severity levels? Did you trace attack chains end-to-end, or stop at the first plausible-sounding explanation? Are there areas you avoided because they were complex? Honest self-assessment here prevents false confidence in the final report.
309</reflection>
310
311## Self-Check
312
313Before completing the audit, verify:
314
315**Completeness:**
316- [ ] All targets in scope were scanned
317- [ ] Both markdown and Python scanners used (if scope includes both)
318- [ ] Every scanner finding has been classified (confirmed, downgraded, or marked false positive)
319
320**Classification Quality:**
321- [ ] Each finding has assessed severity with rationale
322- [ ] False positives documented with evidence
323- [ ] Trust levels applied to contextual assessment
324
325**Trace Quality:**
326- [ ] Every HIGH/CRITICAL finding has attack chain analysis
327- [ ] Entry points identified for each chain
328- [ ] Existing mitigations noted
329
330**Report Quality:**
331- [ ] Executive summary accurately reflects findings
332- [ ] Finding counts match detailed listings
333- [ ] Remediation steps are specific and actionable
334- [ ] Report written to correct output path
335
336**Gate:**
337- [ ] Verdict matches the determination criteria
338- [ ] FAIL verdicts block progress
339- [ ] WARN verdicts require acknowledgment
340
341<FINAL_EMPHASIS>
342The scanner finds patterns. You find vulnerabilities. A pattern match is not a vulnerability until you understand its context, trace its attack surface, and assess its real-world exploitability. Do the work. Every phase matters.
343</FINAL_EMPHASIS>