@rafter-security/cli 0.6.6 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -10
- package/dist/commands/agent/audit-skill.js +22 -20
- package/dist/commands/agent/audit.js +27 -0
- package/dist/commands/agent/components.js +800 -0
- package/dist/commands/agent/config.js +2 -1
- package/dist/commands/agent/disable.js +47 -0
- package/dist/commands/agent/enable.js +50 -0
- package/dist/commands/agent/exec.js +2 -0
- package/dist/commands/agent/index.js +6 -0
- package/dist/commands/agent/init.js +162 -163
- package/dist/commands/agent/install-hook.js +15 -14
- package/dist/commands/agent/list.js +72 -0
- package/dist/commands/agent/scan.js +4 -3
- package/dist/commands/agent/verify.js +1 -1
- package/dist/commands/backend/run.js +12 -3
- package/dist/commands/backend/scan-status.js +3 -2
- package/dist/commands/brief.js +22 -2
- package/dist/commands/ci/init.js +25 -21
- package/dist/commands/completion.js +4 -3
- package/dist/commands/docs/index.js +18 -0
- package/dist/commands/docs/list.js +37 -0
- package/dist/commands/docs/show.js +64 -0
- package/dist/commands/mcp/server.js +84 -0
- package/dist/commands/report.js +42 -41
- package/dist/commands/scan/index.js +7 -5
- package/dist/commands/skill/index.js +14 -0
- package/dist/commands/skill/install.js +89 -0
- package/dist/commands/skill/list.js +79 -0
- package/dist/commands/skill/registry.js +273 -0
- package/dist/commands/skill/remote.js +333 -0
- package/dist/commands/skill/review.js +975 -0
- package/dist/commands/skill/uninstall.js +65 -0
- package/dist/core/audit-logger.js +262 -21
- package/dist/core/config-manager.js +3 -0
- package/dist/core/docs-loader.js +148 -0
- package/dist/core/policy-loader.js +72 -1
- package/dist/core/risk-rules.js +16 -3
- package/dist/index.js +19 -9
- package/dist/scanners/gitleaks.js +6 -2
- package/package.json +1 -1
- package/resources/skills/rafter/SKILL.md +77 -97
- package/resources/skills/rafter/docs/backend.md +106 -0
- package/resources/skills/rafter/docs/cli-reference.md +199 -0
- package/resources/skills/rafter/docs/finding-triage.md +79 -0
- package/resources/skills/rafter/docs/guardrails.md +91 -0
- package/resources/skills/rafter/docs/shift-left.md +64 -0
- package/resources/skills/rafter-agent-security/SKILL.md +1 -1
- package/resources/skills/rafter-code-review/SKILL.md +91 -0
- package/resources/skills/rafter-code-review/docs/api.md +90 -0
- package/resources/skills/rafter-code-review/docs/asvs.md +120 -0
- package/resources/skills/rafter-code-review/docs/cwe-top25.md +78 -0
- package/resources/skills/rafter-code-review/docs/investigation-playbook.md +101 -0
- package/resources/skills/rafter-code-review/docs/llm.md +87 -0
- package/resources/skills/rafter-code-review/docs/web-app.md +84 -0
- package/resources/skills/rafter-secure-design/SKILL.md +103 -0
- package/resources/skills/rafter-secure-design/docs/api-design.md +97 -0
- package/resources/skills/rafter-secure-design/docs/auth.md +67 -0
- package/resources/skills/rafter-secure-design/docs/data-storage.md +90 -0
- package/resources/skills/rafter-secure-design/docs/dependencies.md +101 -0
- package/resources/skills/rafter-secure-design/docs/deployment.md +104 -0
- package/resources/skills/rafter-secure-design/docs/ingestion.md +98 -0
- package/resources/skills/rafter-secure-design/docs/standards-pointers.md +102 -0
- package/resources/skills/rafter-secure-design/docs/threat-modeling.md +128 -0
- package/resources/skills/rafter-skill-review/SKILL.md +106 -0
- package/resources/skills/rafter-skill-review/docs/authorship-provenance.md +82 -0
- package/resources/skills/rafter-skill-review/docs/changelog-review.md +99 -0
- package/resources/skills/rafter-skill-review/docs/data-practices.md +88 -0
- package/resources/skills/rafter-skill-review/docs/malware-indicators.md +79 -0
- package/resources/skills/rafter-skill-review/docs/prompt-injection.md +85 -0
- package/resources/skills/rafter-skill-review/docs/telemetry.md +78 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Rafter CLI Reference
|
|
2
|
+
|
|
3
|
+
Full command tree for the `rafter` CLI. Commands group by concern: **scanning**, **agent** (local security primitives), **hook** (platform bridges), **policy**, **ci**, **mcp**, **docs/brief**, **notify**, **report**.
|
|
4
|
+
|
|
5
|
+
Global flags:
|
|
6
|
+
- `-a, --agent` — plain output (no colors/emoji) for AI consumers.
|
|
7
|
+
- `--version`, `version` — print version.
|
|
8
|
+
|
|
9
|
+
Exit codes (consistent across commands):
|
|
10
|
+
- `0` — success / no findings
|
|
11
|
+
- `1` — findings detected OR general error
|
|
12
|
+
- `2` — invalid input / scan not found
|
|
13
|
+
|
|
14
|
+
All scan commands write results as JSON on stdout and status on stderr; safe to pipe.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Scanning
|
|
19
|
+
|
|
20
|
+
### `rafter run [opts]` · `rafter scan [opts]` · `rafter scan remote [opts]`
|
|
21
|
+
|
|
22
|
+
Trigger a remote security scan on a GitHub repo. Auto-detects current repo/branch.
|
|
23
|
+
|
|
24
|
+
When to reach for it:
|
|
25
|
+
- "Is this branch safe to merge?"
|
|
26
|
+
- Pre-deploy / post-dependency-update gating.
|
|
27
|
+
- Any request for SAST, SCA, or "security audit" of a repo.
|
|
28
|
+
|
|
29
|
+
Key options: `--repo org/repo`, `--branch <name>`, `--mode fast|plus`, `--format json|md`, `--api-key <key>`, `--github-token <pat>` (private repos), `--skip-interactive`, `--quiet`.
|
|
30
|
+
|
|
31
|
+
Example: `rafter run --repo myorg/api --branch feature/auth --mode plus --format json`
|
|
32
|
+
|
|
33
|
+
### `rafter scan local [path]`
|
|
34
|
+
|
|
35
|
+
Local secret scan. Deterministic, offline, no API key. Dual-engine: Gitleaks binary if present, built-in regex fallback (21+ patterns).
|
|
36
|
+
|
|
37
|
+
When: pre-commit, pre-push, fast first pass before remote scan, air-gapped envs.
|
|
38
|
+
|
|
39
|
+
Useful flags: `--history` (scan git history with Gitleaks), `--format json`, `--quiet`.
|
|
40
|
+
|
|
41
|
+
Example: `rafter scan local . --format json`
|
|
42
|
+
|
|
43
|
+
### `rafter get <scan-id>`
|
|
44
|
+
|
|
45
|
+
Retrieve results of a previously triggered remote scan.
|
|
46
|
+
|
|
47
|
+
When: after `rafter run --skip-interactive`, or when a scan id was shown and you need the report.
|
|
48
|
+
|
|
49
|
+
Example: `rafter get scan_abc123xyz --format json`
|
|
50
|
+
|
|
51
|
+
### `rafter usage`
|
|
52
|
+
|
|
53
|
+
Show API quota / usage for `RAFTER_API_KEY`.
|
|
54
|
+
|
|
55
|
+
When: before firing multiple remote scans, or when the user asks about limits.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Agent (Local Security Primitives)
|
|
60
|
+
|
|
61
|
+
### `rafter agent exec -- <command>`
|
|
62
|
+
|
|
63
|
+
Classify and optionally run a shell command through Rafter's risk tiers (critical / high / medium / low).
|
|
64
|
+
|
|
65
|
+
When: any time a destructive-looking command is about to be executed by an agent. Use `--dry-run` to classify without running.
|
|
66
|
+
|
|
67
|
+
Example: `rafter agent exec --dry-run -- rm -rf $WORK_DIR`
|
|
68
|
+
|
|
69
|
+
### `rafter agent audit [path]`
|
|
70
|
+
|
|
71
|
+
Audit a directory for suspicious or risky code patterns — focused on plugins, skills, extensions, and tooling a user might install.
|
|
72
|
+
|
|
73
|
+
When: vetting a third-party skill, MCP server, or CLI plugin before install.
|
|
74
|
+
|
|
75
|
+
### `rafter agent audit-skill <path>`
|
|
76
|
+
|
|
77
|
+
Audit a single skill file (SKILL.md). Flags prompt-injection, unbounded tool use, exfiltration patterns.
|
|
78
|
+
|
|
79
|
+
### `rafter agent scan [path]`
|
|
80
|
+
|
|
81
|
+
Alias for `rafter scan local` kept for back-compat. Prefer `rafter scan local`.
|
|
82
|
+
|
|
83
|
+
### `rafter agent status` · `rafter agent verify`
|
|
84
|
+
|
|
85
|
+
`status`: dump config, hook state, gitleaks availability, audit log location.
|
|
86
|
+
`verify`: sanity-check installation; exit non-zero if anything is broken.
|
|
87
|
+
|
|
88
|
+
### `rafter agent init [--with-<platform>]`
|
|
89
|
+
|
|
90
|
+
Install rafter skills and/or hooks into a supported agent (`claude-code`, `codex`, `gemini`, `cursor`, `windsurf`, `aider`, `openclaw`, `continue`). See `rafter brief setup/<platform>`.
|
|
91
|
+
|
|
92
|
+
### `rafter agent init-project`
|
|
93
|
+
|
|
94
|
+
Scaffold `.rafter.yml` and a baseline for the current repo.
|
|
95
|
+
|
|
96
|
+
### `rafter agent install-hook`
|
|
97
|
+
|
|
98
|
+
Install a pre-commit hook that runs `rafter scan local` before every commit.
|
|
99
|
+
|
|
100
|
+
### `rafter agent config [get|set|list]`
|
|
101
|
+
|
|
102
|
+
Read/write Rafter config (global `~/.rafter/config.yml` and local `.rafter.yml`).
|
|
103
|
+
|
|
104
|
+
### `rafter agent baseline`
|
|
105
|
+
|
|
106
|
+
Snapshot current findings so only *new* ones fail future scans.
|
|
107
|
+
|
|
108
|
+
### `rafter agent instruction-block`
|
|
109
|
+
|
|
110
|
+
Emit a ready-to-paste instruction block for an agent's system prompt.
|
|
111
|
+
|
|
112
|
+
### `rafter agent update-gitleaks`
|
|
113
|
+
|
|
114
|
+
Download / upgrade the Gitleaks binary Rafter uses for local scans.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Hooks (Agent Platform Bridges)
|
|
119
|
+
|
|
120
|
+
### `rafter hook pretool`
|
|
121
|
+
|
|
122
|
+
Stdin → JSON pretool event from an agent (e.g. Claude Code). Classifies the pending tool call and returns approve/block with reasoning.
|
|
123
|
+
|
|
124
|
+
### `rafter hook posttool`
|
|
125
|
+
|
|
126
|
+
Stdin → JSON posttool event. Logs to audit trail, optionally post-scans written files for secrets.
|
|
127
|
+
|
|
128
|
+
See `docs/guardrails.md` for how these plug into Claude Code / other platforms.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Policy
|
|
133
|
+
|
|
134
|
+
### `rafter policy export [--format yml|json]`
|
|
135
|
+
|
|
136
|
+
Emit the effective merged policy (defaults + global + `.rafter.yml`).
|
|
137
|
+
|
|
138
|
+
### `rafter policy validate <file>`
|
|
139
|
+
|
|
140
|
+
Lint a policy file. Non-zero exit on invalid structure.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## CI
|
|
145
|
+
|
|
146
|
+
### `rafter ci init [--provider github|gitlab|circle|...]`
|
|
147
|
+
|
|
148
|
+
Generate a CI workflow that runs `rafter scan` on PR + main, with sensible defaults (caching, JSON artifact, comment-on-PR where supported).
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## MCP
|
|
153
|
+
|
|
154
|
+
### `rafter mcp serve`
|
|
155
|
+
|
|
156
|
+
Start the Rafter MCP server over stdio. Exposes:
|
|
157
|
+
- Tools: `scan_secrets`, `evaluate_command`, `read_audit_log`, `get_config`
|
|
158
|
+
- Resources: `rafter://config`, `rafter://policy`
|
|
159
|
+
|
|
160
|
+
Use from any MCP-capable client (Gemini, Cursor, Windsurf, Aider, Continue.dev). See `rafter brief setup/<platform>`.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Knowledge / Meta
|
|
165
|
+
|
|
166
|
+
### `rafter brief [topic]`
|
|
167
|
+
|
|
168
|
+
Print rafter knowledge for any agent. Topics include: `security`, `scanning`, `commands`, `pricing`, `setup`, `setup/<platform>`, `all`, plus sub-doc topics (`cli-reference`, `guardrails`, `backend`, `shift-left`, `finding-triage`).
|
|
169
|
+
|
|
170
|
+
### `rafter notify --scan-id <id> --to <slack|discord-webhook>`
|
|
171
|
+
|
|
172
|
+
Post a scan summary to Slack or Discord.
|
|
173
|
+
|
|
174
|
+
### `rafter report --scan-id <id> [--out report.html]`
|
|
175
|
+
|
|
176
|
+
Generate a self-contained HTML security report for sharing.
|
|
177
|
+
|
|
178
|
+
### `rafter issues sync --scan-id <id>`
|
|
179
|
+
|
|
180
|
+
Open / update GitHub Issues from scan findings (one issue per rule).
|
|
181
|
+
|
|
182
|
+
### `rafter completion <bash|zsh|fish>`
|
|
183
|
+
|
|
184
|
+
Emit shell completion script.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Quick Decision Table
|
|
189
|
+
|
|
190
|
+
| User intent | Command |
|
|
191
|
+
|---|---|
|
|
192
|
+
| Fast secret check locally | `rafter scan local .` |
|
|
193
|
+
| Full repo security review | `rafter run` (then `rafter get <id>`) |
|
|
194
|
+
| "Is this command safe?" | `rafter agent exec --dry-run -- <cmd>` |
|
|
195
|
+
| "Is this skill safe to install?" | `rafter agent audit <path>` |
|
|
196
|
+
| Add pre-commit protection | `rafter agent install-hook` |
|
|
197
|
+
| Wire up CI | `rafter ci init` |
|
|
198
|
+
| Connect an agent | `rafter agent init --with-<platform>` |
|
|
199
|
+
| Share a report | `rafter report --scan-id <id>` |
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Finding Triage — Reading a Rafter Finding
|
|
2
|
+
|
|
3
|
+
How to go from a raw Rafter finding to a decision: **fix now**, **fix later**, **suppress**, or **escalate**.
|
|
4
|
+
|
|
5
|
+
## Anatomy of a Finding
|
|
6
|
+
|
|
7
|
+
Every finding (local or remote) has this shape:
|
|
8
|
+
|
|
9
|
+
```jsonc
|
|
10
|
+
{
|
|
11
|
+
"ruleId": "HARDCODED_API_KEY", // stable ID — use in overrides / baselines
|
|
12
|
+
"severity": "critical", // critical | high | medium | low | info
|
|
13
|
+
"confidence": "high", // high | medium | low
|
|
14
|
+
"file": "src/config/prod.ts",
|
|
15
|
+
"line": 42,
|
|
16
|
+
"title": "Hardcoded API key",
|
|
17
|
+
"description": "...",
|
|
18
|
+
"recommendation": "...", // suggested fix, when available
|
|
19
|
+
"evidence": "API_KEY = \"sk-...\"" // snippet (may be redacted)
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Three fields do most of the work: **severity**, **confidence**, and **ruleId**.
|
|
24
|
+
|
|
25
|
+
## Decision Flow
|
|
26
|
+
|
|
27
|
+
1. **Severity `critical` + confidence `high`** → fix before merge. Non-negotiable. Examples: hardcoded production secrets, SQL injection, RCE via unsafe deserialization.
|
|
28
|
+
2. **Severity `high` + confidence `high`** → fix this PR unless there's a specific reason not to (document it in the baseline).
|
|
29
|
+
3. **`high` + confidence `medium/low`** → investigate. Often a real issue in a weird codepath; sometimes a pattern false-positive.
|
|
30
|
+
4. **`medium`** → fix within a reasonable window; batch with related work.
|
|
31
|
+
5. **`low` / `info`** → style/hygiene. Suppress at the rule level if consistently noisy.
|
|
32
|
+
|
|
33
|
+
Confidence matters: a `high`-severity, `low`-confidence finding is a hypothesis, not a verdict. Confirm by reading the evidence + surrounding code before acting.
|
|
34
|
+
|
|
35
|
+
## Common Rule Categories
|
|
36
|
+
|
|
37
|
+
| Rule family | What it means | First move |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| `HARDCODED_*` (secrets, tokens, keys) | A literal credential is in source | Rotate the credential, then remove from code & git history |
|
|
40
|
+
| `SQL_INJECTION`, `COMMAND_INJECTION` | Unsanitized input reaches a sink | Parameterize / use a safe API; fix at the source, not by escaping at the sink |
|
|
41
|
+
| `INSECURE_DESERIALIZATION` | `pickle`, `yaml.load`, `Marshal`, untrusted JSON → `eval` | Switch to safe loader; never deserialize untrusted data into native objects |
|
|
42
|
+
| `WEAK_CRYPTO` (`MD5`, `SHA1`, `DES`, `ECB`) | Algorithm/mode doesn't meet modern threat model | Swap algorithm; check for backwards-compat constraints |
|
|
43
|
+
| `PATH_TRAVERSAL` | User input flows into filesystem path | Canonicalize + verify within allow-rooted dir |
|
|
44
|
+
| `SSRF` | User input controls outbound URL | Allowlist hosts; resolve IPs and block internal ranges |
|
|
45
|
+
| `DEPENDENCY_CVE` (SCA) | Transitive/direct dep has known CVE | Bump to a patched version; if none, check if the vulnerable code path is reachable |
|
|
46
|
+
|
|
47
|
+
## Before Rotating or Nuking Something
|
|
48
|
+
|
|
49
|
+
If the finding is a leaked secret that was committed:
|
|
50
|
+
1. **Rotate first.** Assume the secret is compromised the moment it touched git history.
|
|
51
|
+
2. Remove from history if the repo is private *and* short-lived; otherwise rotation is the real fix.
|
|
52
|
+
3. Add the pattern to pre-commit (`rafter agent install-hook`) so it doesn't happen again.
|
|
53
|
+
|
|
54
|
+
## Suppression — When It's OK
|
|
55
|
+
|
|
56
|
+
Suppress only when the finding is a real false positive *for this context*, with a written reason. Two mechanisms:
|
|
57
|
+
|
|
58
|
+
- **Inline**: `// rafter-ignore: HARDCODED_API_KEY — test fixture, not a real key`
|
|
59
|
+
- **Baseline**: `rafter agent baseline` snapshots current findings; only *new* findings fail future scans. Good for adopting Rafter on a legacy codebase without a big bang.
|
|
60
|
+
|
|
61
|
+
Never suppress by:
|
|
62
|
+
- Commenting out the rule globally.
|
|
63
|
+
- Broadening an allow-pattern beyond the specific file/context.
|
|
64
|
+
- Deleting the scan step from CI.
|
|
65
|
+
|
|
66
|
+
## Escalation
|
|
67
|
+
|
|
68
|
+
Escalate a finding (to security team, or back to the user) when:
|
|
69
|
+
- It implicates production credentials or customer data.
|
|
70
|
+
- It's a design-level issue the local fix can't address (e.g. "the auth model is wrong").
|
|
71
|
+
- The fix requires coordination across services or a rotation playbook.
|
|
72
|
+
|
|
73
|
+
Provide `scanId`, `ruleId`, file + line, and the evidence snippet. Exit code + JSON makes this a copy-paste to a ticket.
|
|
74
|
+
|
|
75
|
+
## Tie-Backs
|
|
76
|
+
|
|
77
|
+
- Want depth on a single finding? Rerun with `--mode plus` (see `docs/backend.md`).
|
|
78
|
+
- Want to prevent the class of finding? See `docs/shift-left.md` → `rafter-secure-design`.
|
|
79
|
+
- Want structured review around the finding? See `docs/shift-left.md` → `rafter-code-review`.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Rafter Guardrails — PreToolUse Hooks & Command Risk
|
|
2
|
+
|
|
3
|
+
How Rafter intercepts agent tool calls before they execute, how it decides what to block, and how to override safely.
|
|
4
|
+
|
|
5
|
+
## The Shape
|
|
6
|
+
|
|
7
|
+
Rafter exposes two hook handlers over stdio:
|
|
8
|
+
|
|
9
|
+
- `rafter hook pretool` — read a JSON event on stdin (from Claude Code, etc.), emit an approve/block decision on stdout.
|
|
10
|
+
- `rafter hook posttool` — read a JSON event after a tool ran; log to audit trail, optionally rescan written files for secrets.
|
|
11
|
+
|
|
12
|
+
For platforms without hooks, the same classifier is reachable as:
|
|
13
|
+
- `rafter agent exec --dry-run -- <command>` (returns risk, exits 0/1)
|
|
14
|
+
- `rafter mcp serve` → MCP tool `evaluate_command`
|
|
15
|
+
|
|
16
|
+
## Risk Tiers
|
|
17
|
+
|
|
18
|
+
Every command (Bash-like tool call) gets classified into one of four tiers by `src/core/risk-rules.ts`:
|
|
19
|
+
|
|
20
|
+
| Tier | What it means | Default hook behavior |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| `low` | Read-only, safe prefix (`ls`, `cat`, `grep`, `git status` …), no chaining | **approve** silently |
|
|
23
|
+
| `medium` | State-changing but recoverable (package installs, git commits on current branch) | **approve with note** in audit log |
|
|
24
|
+
| `high` | Destructive or privileged (force push, `sudo`, broad file deletion, curl | sh) | **prompt** the agent / user for approval |
|
|
25
|
+
| `critical` | Likely irreversible damage (`rm -rf /`, DB drop, wiping .git, repo-wide chmod) | **block** hard |
|
|
26
|
+
|
|
27
|
+
Tiers are derived from regex patterns in `risk-rules.ts` (`CRITICAL_PATTERNS`, `HIGH_PATTERNS`, `MEDIUM_PATTERNS`) plus a `SAFE_PREFIX` allowlist. Presence of chain operators (`&&`, `||`, `;`, `|`) disqualifies the safe-prefix shortcut.
|
|
28
|
+
|
|
29
|
+
## Policy Overrides
|
|
30
|
+
|
|
31
|
+
`.rafter.yml` (project) and `~/.rafter/config.yml` (global) can override defaults:
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
risk:
|
|
35
|
+
blocked_patterns:
|
|
36
|
+
- "terraform destroy"
|
|
37
|
+
require_approval:
|
|
38
|
+
- "^npm publish"
|
|
39
|
+
allow:
|
|
40
|
+
- "^pnpm run test" # force low regardless of content
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Merge order (most specific wins): project `.rafter.yml` > global config > built-in defaults. Dump the effective merged policy with `rafter policy export`.
|
|
44
|
+
|
|
45
|
+
## How to Interpret a Block
|
|
46
|
+
|
|
47
|
+
When a hook blocks a command, the JSON response includes:
|
|
48
|
+
|
|
49
|
+
- `decision`: `"block" | "approve" | "ask"`
|
|
50
|
+
- `riskLevel`: `"critical" | "high" | "medium" | "low"`
|
|
51
|
+
- `reason`: the matched pattern or policy rule
|
|
52
|
+
- `ruleId`: stable ID you can reference in overrides / suppressions
|
|
53
|
+
|
|
54
|
+
**Before overriding, ask: is there a safer form of this command?** Example:
|
|
55
|
+
- `rm -rf $DIR` with unvalidated `$DIR` → use explicit path or `--one-file-system`.
|
|
56
|
+
- `curl <url> | sh` → download, inspect, then run.
|
|
57
|
+
- `git push --force` → `git push --force-with-lease`.
|
|
58
|
+
|
|
59
|
+
## How to Request an Override
|
|
60
|
+
|
|
61
|
+
If the block is a false positive **for this specific context**, the right path is:
|
|
62
|
+
|
|
63
|
+
1. Add an allow pattern scoped to the project in `.rafter.yml`:
|
|
64
|
+
```yaml
|
|
65
|
+
risk:
|
|
66
|
+
allow:
|
|
67
|
+
- "^terraform destroy -target=module\\.sandbox"
|
|
68
|
+
```
|
|
69
|
+
2. Or run once with an explicit ack flag: `rafter agent exec --force -- <command>` (logged to audit trail; still shows up in `rafter agent audit` history).
|
|
70
|
+
3. Never disable the hook globally to get past one command — that silently drops protection for every future call.
|
|
71
|
+
|
|
72
|
+
## Audit Trail
|
|
73
|
+
|
|
74
|
+
Every hook decision (approve / ask / block) is appended to the JSONL audit log:
|
|
75
|
+
|
|
76
|
+
- Location: `rafter agent status` prints the path.
|
|
77
|
+
- Read: `rafter agent audit --log` (or MCP `read_audit_log`).
|
|
78
|
+
- Use it for postmortems: *why did this command run?*, *what did the agent try before the block?*
|
|
79
|
+
|
|
80
|
+
## Platform Notes
|
|
81
|
+
|
|
82
|
+
- **Claude Code**: `rafter agent init --with-claude-code` wires `pretool` + `posttool` into `~/.claude/settings.json`. Hook timeout is 5s; long scans defer to the async posttool path.
|
|
83
|
+
- **MCP clients (Gemini, Cursor, …)**: no native hook; use the `evaluate_command` MCP tool from your agent's system prompt ("before Bash, call rafter.evaluate_command").
|
|
84
|
+
- **CI**: hooks don't fire in CI. Use `rafter scan` + `rafter policy validate` in the pipeline instead.
|
|
85
|
+
|
|
86
|
+
## Common Pitfalls
|
|
87
|
+
|
|
88
|
+
- A `low` classification is not a safety guarantee — it means "no known-bad pattern matched". Still review unusual commands.
|
|
89
|
+
- Chaining defeats the safe-prefix allowlist on purpose (`ls && rm -rf /` is not low-risk).
|
|
90
|
+
- `sudo` always escalates to at least `high` regardless of the wrapped command.
|
|
91
|
+
- Secret leaks in arguments (`curl -H "Authorization: Bearer abc..."`) are flagged by posttool scanning, not by the pretool risk classifier.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Shift-Left — Secure Design & Code Review Skills
|
|
2
|
+
|
|
3
|
+
`rafter` (this skill) handles **detection**: scanners, hooks, risk classifiers. Two sibling skills cover the earlier stages of the lifecycle — use them when prevention or structured review is more valuable than another scan pass.
|
|
4
|
+
|
|
5
|
+
## Decision Tree
|
|
6
|
+
|
|
7
|
+
| You're trying to … | Reach for |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Write code that **doesn't have the flaw in the first place** (design phase, picking primitives, shaping APIs) | `rafter-secure-design` |
|
|
10
|
+
| **Review existing code** against OWASP Top 10 / MITRE ATT&CK / ASVS with a structured walkthrough | `rafter-code-review` |
|
|
11
|
+
| Find concrete bugs / leaks / CVEs automatically | stay in this skill — see branch (a) in SKILL.md |
|
|
12
|
+
|
|
13
|
+
The three skills compose: design well (secure-design) → write it → review it (code-review) → detect what slipped through (rafter scan + guardrails).
|
|
14
|
+
|
|
15
|
+
## `rafter-secure-design` (filed as rf-bcr)
|
|
16
|
+
|
|
17
|
+
Use at feature kickoff or during architecture review, *before* code exists. It's a CYOA over design decisions:
|
|
18
|
+
|
|
19
|
+
- Authn / authz primitives: which to pick, which to refuse (e.g. homegrown JWT signing).
|
|
20
|
+
- Input boundaries: where to validate, where to escape, where to parameterize.
|
|
21
|
+
- Secrets handling: storage, rotation, scoping of least-privilege credentials.
|
|
22
|
+
- Data-in-transit / data-at-rest defaults per language/framework.
|
|
23
|
+
- Threat modeling prompts: STRIDE-style walks you can run with an agent.
|
|
24
|
+
|
|
25
|
+
Invoke it by name in platforms that auto-trigger skills, or:
|
|
26
|
+
```bash
|
|
27
|
+
rafter brief shift-left # this doc
|
|
28
|
+
# and then load the sibling:
|
|
29
|
+
# Read skills/rafter-secure-design/SKILL.md
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## `rafter-code-review` (landed)
|
|
33
|
+
|
|
34
|
+
Use during code review — your own or an AI's. A CYOA router into OWASP / MITRE / ASVS walkthroughs phrased as *questions*, not as monolithic audits. It's the *analysis* counterpart to automated scanning.
|
|
35
|
+
|
|
36
|
+
Pick the category that matches the code in front of you:
|
|
37
|
+
|
|
38
|
+
- **Web app** → `rafter-code-review/docs/web-app.md` (OWASP Top 10 2021).
|
|
39
|
+
- **REST / GraphQL / gRPC API** → `rafter-code-review/docs/api.md` (OWASP API Top 10 2023).
|
|
40
|
+
- **LLM-integrated feature** → `rafter-code-review/docs/llm.md` (OWASP LLM Top 10 2025).
|
|
41
|
+
- **CLI / library / IaC** → `rafter-code-review/docs/cwe-top25.md` (MITRE CWE Top 25, keyed by language).
|
|
42
|
+
- **Need to pick review depth** → `rafter-code-review/docs/asvs.md` (ASVS L1/L2/L3 selection + spot-checks).
|
|
43
|
+
- **Single suspicious finding to chase** → `rafter-code-review/docs/investigation-playbook.md`.
|
|
44
|
+
|
|
45
|
+
Start at `rafter-code-review/SKILL.md` — it's a router; Read only the one sub-doc you need so you don't flood context.
|
|
46
|
+
|
|
47
|
+
Pair with `rafter run --mode plus` when you want both a human-style walkthrough and the backend's deep pass on the same diff.
|
|
48
|
+
|
|
49
|
+
## When to use which (cheat sheet)
|
|
50
|
+
|
|
51
|
+
- Designing a new service → **secure-design**.
|
|
52
|
+
- Reviewing a teammate's PR by eye → **code-review**.
|
|
53
|
+
- CI gate / pre-push / scheduled scan → **rafter** (this skill), `rafter run` / `rafter scan local`.
|
|
54
|
+
- "I have a finding, now what?" → **rafter**, `docs/finding-triage.md`.
|
|
55
|
+
- "I have a risky command, is it safe?" → **rafter**, `docs/guardrails.md`.
|
|
56
|
+
|
|
57
|
+
Do not duplicate. If a sibling skill already owns the topic, Read it and stop — don't re-derive the checklist here.
|
|
58
|
+
|
|
59
|
+
## Status
|
|
60
|
+
|
|
61
|
+
- `rafter-code-review` — **landed** (rf-z7j). Ships alongside this skill; invoke directly.
|
|
62
|
+
- `rafter-secure-design` — **landed** (rf-bcr). Ships alongside this skill; invoke directly. Router skill with sub-docs for auth, data storage, API design, ingestion, deployment, dependencies, threat modeling, and standards pointers.
|
|
63
|
+
|
|
64
|
+
Both are installed — prefer invoking them directly for structured output over re-deriving checklists here.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rafter-agent-security
|
|
3
3
|
description: "Rafter local security tools — deterministic secret scanning, command risk assessment, skill auditing, and audit log review. Use when: checking for leaked credentials or API keys, evaluating whether code is safe to push, auditing skills before installation, reviewing security events. Works offline, no API key needed. Run `rafter brief security` for full capabilities."
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
allowed-tools: [Bash, Read, Glob, Grep]
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rafter-code-review
|
|
3
|
+
description: "Structured security code review — OWASP / MITRE / ASVS walkthroughs as questions, not audits. Router skill: pick what kind of code you're reviewing (web app, REST/GraphQL API, LLM-integrated, CLI/library/IaC) and Read the matching sub-doc. Designed to pair with `rafter scan` / `rafter run` — the scanner finds known-bad patterns, this skill asks the questions that patterns miss. Use during PR review, refactoring risky modules, or pre-release hardening."
|
|
4
|
+
version: 0.7.0
|
|
5
|
+
allowed-tools: [Bash, Read, Glob, Grep]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Rafter Code Review — Structured Security Walkthroughs
|
|
9
|
+
|
|
10
|
+
A reviewer's skill, not an audit generator. Each sub-doc is a set of **questions** to run against the code — what to grep for, what to trace, what to ask before you sign off. No monolithic reports.
|
|
11
|
+
|
|
12
|
+
> Pair with the `rafter` skill (detection: `rafter scan`, `rafter run`) and `rafter-secure-design` (prevention: design-phase walks). This skill is the middle stage — review before merge.
|
|
13
|
+
|
|
14
|
+
## How to use this skill
|
|
15
|
+
|
|
16
|
+
1. Identify the category of code in front of you (below).
|
|
17
|
+
2. `Read` only the matching sub-doc — do not preload them all.
|
|
18
|
+
3. Work through its questions against the specific files/diff. Cite file:line evidence as you go.
|
|
19
|
+
4. When in doubt on a single finding, jump to `docs/investigation-playbook.md` for canonical follow-up questions.
|
|
20
|
+
5. Finish with `rafter run --mode plus` on the same diff if the stakes warrant a deep automated pass.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Choose Your Adventure
|
|
25
|
+
|
|
26
|
+
### (1) Web application (server-rendered, session-based, or SPA backend)
|
|
27
|
+
|
|
28
|
+
For: login flows, session/cookie handling, form handlers, template rendering, admin panels, anything browser-facing.
|
|
29
|
+
|
|
30
|
+
- **Read `docs/web-app.md`** — OWASP Top 10 (2021) walk: broken access control, crypto failures, injection, insecure design, misconfig, vulnerable components, authn failures, integrity failures, logging gaps, SSRF.
|
|
31
|
+
|
|
32
|
+
### (2) REST / GraphQL / gRPC API (machine-to-machine, mobile backend, public API)
|
|
33
|
+
|
|
34
|
+
For: endpoint surface that isn't primarily rendering HTML — tokens instead of sessions, authz-per-endpoint, rate limiting.
|
|
35
|
+
|
|
36
|
+
- **Read `docs/api.md`** — OWASP API Security Top 10 (2023): BOLA, broken authn, BOPLA, unrestricted resource consumption, BFLA, unrestricted access to sensitive business flows, SSRF, misconfig, improper inventory, unsafe consumption of third-party APIs.
|
|
37
|
+
|
|
38
|
+
### (3) LLM-integrated feature (prompts, agents, tools, RAG, embeddings)
|
|
39
|
+
|
|
40
|
+
For: anything that sends user text to a model, uses tool calls, retrieves untrusted context, or ships model output to a downstream system.
|
|
41
|
+
|
|
42
|
+
- **Read `docs/llm.md`** — OWASP LLM Top 10 (2025): prompt injection, sensitive info disclosure, supply chain, data/model poisoning, improper output handling, excessive agency, system prompt leakage, vector/embedding weaknesses, misinformation, unbounded consumption.
|
|
43
|
+
|
|
44
|
+
### (4) CLI, library, or infra-as-code
|
|
45
|
+
|
|
46
|
+
For: build tooling, developer CLIs, shared SDK packages, Terraform / CloudFormation / Kubernetes manifests, shell scripts.
|
|
47
|
+
|
|
48
|
+
- **Read `docs/cwe-top25.md`** — MITRE CWE Top 25, keyed by language (Python / JS / Go / Rust / Java) and by IaC primitive. Focus on injection, memory safety, path traversal, race conditions, privilege mismanagement.
|
|
49
|
+
|
|
50
|
+
### (5) I need to pick the right depth for this review
|
|
51
|
+
|
|
52
|
+
For: "how hard should I look?", scoping a review before starting, compliance-adjacent changes.
|
|
53
|
+
|
|
54
|
+
- **Read `docs/asvs.md`** — OWASP ASVS L1 / L2 / L3. Picks the level based on risk tier of the code, then gives spot-check questions per level.
|
|
55
|
+
|
|
56
|
+
### (6) I have one specific question to investigate
|
|
57
|
+
|
|
58
|
+
For: single-finding follow-up, tracing a suspicious call, "is this input reachable from outside?".
|
|
59
|
+
|
|
60
|
+
- **Read `docs/investigation-playbook.md`** — canonical questions: reachability, authz coverage, data-flow direction, trust boundary placement.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## What this skill will NOT do
|
|
65
|
+
|
|
66
|
+
- It will not generate a monolithic "security audit report". If you need a report, run `rafter run --mode plus` — the backend is better at that.
|
|
67
|
+
- It will not replace automated scanning. Always pair with `rafter scan local .` (secrets) and `rafter run` (SAST/SCA) before review.
|
|
68
|
+
- It will not produce recommendations without evidence. Every question expects a file:line answer before moving on.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Fast path for a typical PR review
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 1. Run deterministic checks first — cheap, catches the obvious
|
|
76
|
+
rafter scan local .
|
|
77
|
+
rafter run # remote SAST/SCA, if RAFTER_API_KEY set
|
|
78
|
+
|
|
79
|
+
# 2. Then pick the category and walk the questions
|
|
80
|
+
# Read docs/<category>.md
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
If the diff spans categories (e.g. a web app that also has an LLM feature), Read both sub-docs and walk them sequentially. Don't try to merge the checklists.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Tie-backs
|
|
88
|
+
|
|
89
|
+
- Finding from the scanner you don't understand? → `rafter` skill, `docs/finding-triage.md`.
|
|
90
|
+
- Designing a new feature instead of reviewing one? → `rafter-secure-design`.
|
|
91
|
+
- Risky command came up mid-review? → `rafter` skill, `docs/guardrails.md`.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# API Review — OWASP API Security Top 10 (2023)
|
|
2
|
+
|
|
3
|
+
REST / GraphQL / gRPC review: authz-per-endpoint, per-object and per-field; rate limiting; bulk operations. Walk each category as questions. Cite file:line before moving on.
|
|
4
|
+
|
|
5
|
+
## API1 — Broken Object Level Authorization (BOLA)
|
|
6
|
+
|
|
7
|
+
The most common API vuln. Per-object authz, not per-endpoint.
|
|
8
|
+
|
|
9
|
+
- For every handler that takes an id (`/orders/:id`, `/users/:user_id/settings`), is there a check that the id belongs to the caller? "Authenticated" is not "authorized".
|
|
10
|
+
- Grep patterns: `findById`, `SELECT ... WHERE id = ?`, `get_object_or_404`. Is the caller's identity in the query, or compared after?
|
|
11
|
+
- GraphQL: authz at the resolver level for *each* field that returns a user-owned object. Schema-level auth is not enough if resolvers fan out.
|
|
12
|
+
- UUIDs do not save you. They only slow discovery; they do not provide authorization.
|
|
13
|
+
|
|
14
|
+
## API2 — Broken Authentication
|
|
15
|
+
|
|
16
|
+
- Every unauthenticated endpoint — is it supposed to be? List them: grep for `@AnonymousAllowed`, `permission_classes = []`, middleware skips.
|
|
17
|
+
- Token lifetime, refresh, and revocation: where is a token invalidated on logout / password change / user deletion?
|
|
18
|
+
- JWT-specific: is `alg` pinned? Is the key rotated? Is `iss` / `aud` checked? Is clock skew bounded?
|
|
19
|
+
- API keys: how are they generated (entropy), stored (hashed?), scoped (per-tenant? per-capability?), rotated?
|
|
20
|
+
- Credential endpoints (login, reset, MFA enroll) — rate-limited separately from normal endpoints? Return generic errors? Constant-time compare?
|
|
21
|
+
|
|
22
|
+
## API3 — Broken Object Property Level Authorization (BOPLA)
|
|
23
|
+
|
|
24
|
+
Covers both mass-assignment and excessive data exposure.
|
|
25
|
+
|
|
26
|
+
- Serialization: when returning an object, are sensitive fields (`password_hash`, `mfa_secret`, `internal_notes`, `role`) explicitly excluded? "Return the model" is a red flag; "return a DTO" is the fix.
|
|
27
|
+
- Mass assignment: can the client set fields they shouldn't? `User.objects.update(**request.data)`, `req.body` spread into an ORM constructor, Rails `params.permit!`. Check every update/create path.
|
|
28
|
+
- GraphQL: schema exposes fields; are resolvers authz-checked per field? Can a non-admin introspect admin-only fields?
|
|
29
|
+
|
|
30
|
+
## API4 — Unrestricted Resource Consumption
|
|
31
|
+
|
|
32
|
+
- Pagination on every list endpoint? Max page size enforced server-side (not just a default)?
|
|
33
|
+
- Rate limits: per-user, per-IP, per-endpoint. Token bucket? What happens at the limit — 429 with `Retry-After`, or silent 500?
|
|
34
|
+
- Request size limits: body size, file upload size, JSON depth, GraphQL query depth / complexity.
|
|
35
|
+
- Expensive operations: image processing, PDF generation, report export — are they queued, timeboxed, cost-accounted?
|
|
36
|
+
- Amplification: does one API call trigger N outbound calls (email, SMS, push)? Can that N be user-controlled?
|
|
37
|
+
|
|
38
|
+
## API5 — Broken Function Level Authorization (BFLA)
|
|
39
|
+
|
|
40
|
+
Different from BOLA — this is "can a regular user invoke an admin function at all?", not "can user A touch user B's data?".
|
|
41
|
+
|
|
42
|
+
- List admin / privileged endpoints. For each, is there a role check? Is the role from a trusted source (session/token claim) or from the request (`X-Role: admin`)?
|
|
43
|
+
- HTTP verb confusion: does the handler accept PUT/PATCH/DELETE when only GET was authz'd? Are method restrictions on the router or in the handler?
|
|
44
|
+
- Feature flags: does the flag gate *access* or only *visibility*? If the endpoint is reachable when the flag is off, the flag isn't security.
|
|
45
|
+
|
|
46
|
+
## API6 — Unrestricted Access to Sensitive Business Flows
|
|
47
|
+
|
|
48
|
+
- Identify flows worth abusing: signup, promo code redemption, ticket/inventory purchase, "add friend", "send invite".
|
|
49
|
+
- Per-flow: is there anti-automation (captcha, proof of work, device fingerprint, delay between steps)? Rate limit per account *and* per payment instrument *and* per IP range?
|
|
50
|
+
- Does the flow leak enumeration? Signup "email already registered" is a known tradeoff — is it the right one here?
|
|
51
|
+
|
|
52
|
+
## API7 — Server-Side Request Forgery
|
|
53
|
+
|
|
54
|
+
(Same question set as web-app A10 — see `web-app.md`.)
|
|
55
|
+
|
|
56
|
+
- Webhook configurators, URL-based imports, OAuth discovery endpoints, image fetchers: any user-supplied URL that the server fetches?
|
|
57
|
+
- DNS rebinding: is the URL resolved once and then reused, or re-resolved on each redirect? Are redirects followed blindly?
|
|
58
|
+
- Cloud metadata (`169.254.169.254`, `metadata.google.internal`) explicitly blocked?
|
|
59
|
+
|
|
60
|
+
## API8 — Security Misconfiguration
|
|
61
|
+
|
|
62
|
+
- Error responses: do they include stack traces, SQL fragments, internal hostnames? Production should return stable error shapes only.
|
|
63
|
+
- CORS per-endpoint: any endpoint with `Allow-Credentials: true` *and* a reflected / wildcard origin?
|
|
64
|
+
- Default routes from frameworks still mounted (`/actuator/*`, `/debug/*`, `/_next/*` in dev mode)?
|
|
65
|
+
- Are OPTIONS responses correctly restrictive? Do HEAD and OPTIONS follow the same authz as GET?
|
|
66
|
+
- TLS: are older APIs allowed to accept plain HTTP for backwards compat? If yes — is that documented and scoped?
|
|
67
|
+
|
|
68
|
+
## API9 — Improper Inventory Management
|
|
69
|
+
|
|
70
|
+
A governance issue, but reviewable:
|
|
71
|
+
|
|
72
|
+
- Is there an API version registry? When this PR adds or changes an endpoint, is it documented (OpenAPI / GraphQL schema committed)?
|
|
73
|
+
- Are deprecated endpoints marked and scheduled for removal? Still reachable in production?
|
|
74
|
+
- Non-prod environments (staging, sandbox) — do they share data, credentials, or network paths with prod? Often the weakest link.
|
|
75
|
+
|
|
76
|
+
## API10 — Unsafe Consumption of Third-Party APIs
|
|
77
|
+
|
|
78
|
+
- Outbound API calls: is the response validated before use (schema, size, type)? "Trust the third party" is the failure mode.
|
|
79
|
+
- Credentials to third parties: scoped to least privilege? Rotated? Not shared across tenants?
|
|
80
|
+
- What happens on timeout / 5xx from the third party? Fallback to cached data? Log and surface?
|
|
81
|
+
- If the third party is compromised, what is the blast radius here? Does our data flow into untrusted callbacks?
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Exit criteria
|
|
86
|
+
|
|
87
|
+
- Every endpoint touched by the diff has a documented answer for API1 (per-object authz) and API5 (per-function authz).
|
|
88
|
+
- Every new third-party integration has answers for API10.
|
|
89
|
+
- Every new flow has a rate-limit story (API4) and an abuse story (API6).
|
|
90
|
+
- Scanner cross-check: run `rafter run` and reconcile SAST findings against this walk.
|