@rafter-security/cli 0.7.0 → 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 +20 -1
- package/dist/commands/agent/audit-skill.js +2 -1
- package/dist/commands/agent/audit.js +27 -0
- package/dist/commands/agent/components.js +800 -0
- package/dist/commands/agent/disable.js +47 -0
- package/dist/commands/agent/enable.js +50 -0
- package/dist/commands/agent/index.js +6 -0
- package/dist/commands/agent/init.js +162 -164
- package/dist/commands/agent/list.js +72 -0
- package/dist/commands/brief.js +20 -0
- 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/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/index.js +6 -0
- package/package.json +1 -1
- package/resources/skills/rafter/SKILL.md +76 -96
- 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-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
package/dist/index.js
CHANGED
|
@@ -6,11 +6,13 @@ import { createGetCommand } from "./commands/backend/get.js";
|
|
|
6
6
|
import { createUsageCommand } from "./commands/backend/usage.js";
|
|
7
7
|
import { createScanGroupCommand } from "./commands/scan/index.js";
|
|
8
8
|
import { createAgentCommand } from "./commands/agent/index.js";
|
|
9
|
+
import { createSkillCommand } from "./commands/skill/index.js";
|
|
9
10
|
import { createCiCommand } from "./commands/ci/index.js";
|
|
10
11
|
import { createHookCommand } from "./commands/hook/index.js";
|
|
11
12
|
import { createMcpCommand } from "./commands/mcp/index.js";
|
|
12
13
|
import { createPolicyCommand } from "./commands/policy/index.js";
|
|
13
14
|
import { createBriefCommand } from "./commands/brief.js";
|
|
15
|
+
import { createDocsCommand } from "./commands/docs/index.js";
|
|
14
16
|
import { createNotifyCommand } from "./commands/notify.js";
|
|
15
17
|
import { createCompletionCommand } from "./commands/completion.js";
|
|
16
18
|
import { createIssuesCommand } from "./commands/issues/index.js";
|
|
@@ -40,6 +42,8 @@ program.addCommand(createUsageCommand());
|
|
|
40
42
|
program.addCommand(createScanGroupCommand());
|
|
41
43
|
// Agent commands
|
|
42
44
|
program.addCommand(createAgentCommand());
|
|
45
|
+
// Skill commands (install / uninstall / list rafter-authored skills)
|
|
46
|
+
program.addCommand(createSkillCommand());
|
|
43
47
|
// CI commands
|
|
44
48
|
program.addCommand(createCiCommand());
|
|
45
49
|
// Hook commands (for agent platform integration)
|
|
@@ -48,6 +52,8 @@ program.addCommand(createHookCommand());
|
|
|
48
52
|
program.addCommand(createMcpCommand());
|
|
49
53
|
// Policy commands
|
|
50
54
|
program.addCommand(createPolicyCommand());
|
|
55
|
+
// Docs — repo-specific security docs from .rafter.yml
|
|
56
|
+
program.addCommand(createDocsCommand());
|
|
51
57
|
// GitHub Issues integration
|
|
52
58
|
program.addCommand(createIssuesCommand());
|
|
53
59
|
// Brief — agent-independent knowledge delivery
|
package/package.json
CHANGED
|
@@ -1,138 +1,118 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rafter
|
|
3
|
-
description: "Rafter — the security toolkit built for AI workflows.
|
|
3
|
+
description: "Rafter — the security toolkit built for AI workflows. Router skill: pick your task below and Read the matching sub-doc. Covers (a) scanning code/repos, (b) evaluating a command before running, (c) auditing a plugin or skill, (d) understanding a finding, (e) writing secure code from scratch, (f) analyzing existing code for flaws. Local features are free, deterministic, and offline (no API key). Remote SAST/SCA via RAFTER_API_KEY when deeper analysis is needed. If RAFTER_API_KEY is missing, local still works — don't block on it."
|
|
4
4
|
version: 0.7.0
|
|
5
|
-
allowed-tools: [Bash]
|
|
5
|
+
allowed-tools: [Bash, Read]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Rafter Security Toolkit
|
|
8
|
+
# Rafter — Security Toolkit for AI Workflows
|
|
9
9
|
|
|
10
|
-
Rafter
|
|
10
|
+
Rafter ships three tiers of security tooling:
|
|
11
11
|
|
|
12
|
-
1. **Local
|
|
13
|
-
2. **Remote fast** —
|
|
14
|
-
3. **Remote plus** — agentic deep-dive analysis
|
|
12
|
+
1. **Local** — deterministic secret scanning, command-risk classification, skill auditing. Free, offline, no API key.
|
|
13
|
+
2. **Remote fast** (default) — SAST + SCA + deterministic secrets via the Rafter API.
|
|
14
|
+
3. **Remote plus** — agentic deep-dive analysis. Your code is deleted after the run.
|
|
15
15
|
|
|
16
|
-
Stable
|
|
16
|
+
Stable exit codes, stable JSON shapes, deterministic findings. Safe to chain in CI and in agent loops.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
> **Platform setup**: Run `rafter brief setup/<platform>` for integration guides.
|
|
18
|
+
---
|
|
20
19
|
|
|
21
|
-
##
|
|
20
|
+
## Choose Your Adventure
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
Pick the branch that matches what you're trying to do. Each branch points at a sub-doc — `Read` only the one you need so you don't flood context.
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
rafter run [--repo org/repo] [--branch branch-name]
|
|
27
|
-
# or
|
|
28
|
-
rafter scan [--repo org/repo] [--branch branch-name]
|
|
29
|
-
```
|
|
24
|
+
### (a) I want to scan code or a repo for issues
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
Use this for: "Is this safe to push?", "Check for leaks", "Run a security scan", pre-merge / pre-deploy gating, post-dependency-update checks.
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- After dependency updates
|
|
38
|
-
- User mentions: security audit, vulnerability scan, SAST, code analysis
|
|
39
|
-
- User asks: "Is this safe to merge?", "Are there vulnerabilities?", "Check this PR"
|
|
28
|
+
- Local secret scan (fast, no key): `rafter scan local .`
|
|
29
|
+
- Remote SAST/SCA (needs `RAFTER_API_KEY`): `rafter run` (alias `rafter scan`)
|
|
30
|
+
- **Read `docs/backend.md`** for fast-vs-plus modes, auth, latency, cost.
|
|
31
|
+
- **Read `docs/cli-reference.md`** §`scan` and §`run` for full flag matrix.
|
|
40
32
|
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
# In a git repo
|
|
44
|
-
rafter scan
|
|
33
|
+
### (b) I want to evaluate a command before running it
|
|
45
34
|
|
|
46
|
-
|
|
47
|
-
rafter scan --repo myorg/myrepo --branch main
|
|
48
|
-
```
|
|
35
|
+
Use this for: "Is `rm -rf $DIR` safe?", any destructive-looking shell the user typed, commands with sudo / pipes to `sh` / unversioned curl.
|
|
49
36
|
|
|
50
|
-
|
|
37
|
+
- One-shot: `rafter agent exec --dry-run -- <command>`
|
|
38
|
+
- Wrap execution: `rafter agent exec -- <command>` (blocks on critical, prompts on high)
|
|
39
|
+
- **Read `docs/guardrails.md`** for how PreToolUse hooks, risk tiers, and overrides work.
|
|
51
40
|
|
|
52
|
-
|
|
53
|
-
rafter get <scan-id>
|
|
54
|
-
```
|
|
41
|
+
### (c) I want to review a plugin, skill, or extension before installing
|
|
55
42
|
|
|
56
|
-
|
|
43
|
+
Use this for: installing an MCP server, adding a Claude skill, vetting an AI tool config.
|
|
57
44
|
|
|
58
|
-
**
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
45
|
+
- **Installing a new skill? → Read `rafter-skill-review/SKILL.md`** — full provenance, malware, prompt-injection, data-practices, telemetry checklist.
|
|
46
|
+
- Run the deterministic pass: `rafter skill review <path-or-url>` (emits JSON).
|
|
47
|
+
- Audit a directory: `rafter agent audit <path>` (still supported).
|
|
48
|
+
- **Read `docs/cli-reference.md`** §`skill review` / §`agent audit` for output shape and exit codes.
|
|
62
49
|
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
rafter get scan_abc123xyz
|
|
66
|
-
```
|
|
50
|
+
### (d) I want to understand a finding I already have
|
|
67
51
|
|
|
68
|
-
|
|
52
|
+
Use this for: "What does `HARDCODED_SECRET` mean?", "Is this a real issue or noise?", triaging a scan report.
|
|
69
53
|
|
|
70
|
-
|
|
71
|
-
rafter usage
|
|
72
|
-
```
|
|
54
|
+
- **Read `docs/finding-triage.md`** — how to parse severity, rule IDs, confidence, and file refs; when to fix, suppress, or escalate.
|
|
73
55
|
|
|
74
|
-
|
|
56
|
+
### (e) I want to write secure code from scratch
|
|
75
57
|
|
|
76
|
-
|
|
77
|
-
- User asks about remaining scans
|
|
78
|
-
- Before triggering a scan to confirm quota
|
|
79
|
-
- User mentions: quota, usage, limits, remaining scans
|
|
58
|
+
Use this for: designing a new feature, picking auth/crypto primitives, shaping APIs before they exist.
|
|
80
59
|
|
|
81
|
-
|
|
60
|
+
- **Read `docs/shift-left.md`** — pointers into the `rafter-secure-design` sibling skill for design-phase guidance (threat modeling, OWASP ASVS choices, safe defaults).
|
|
82
61
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
62
|
+
### (f) I want to analyze existing code for flaws
|
|
63
|
+
|
|
64
|
+
Use this for: code review, refactoring risky modules, OWASP / MITRE ATT&CK / ASVS walks.
|
|
65
|
+
|
|
66
|
+
- **Read `docs/shift-left.md`** — pointers into the `rafter-code-review` sibling skill for structured OWASP/ASVS-driven code analysis.
|
|
67
|
+
- For automated SAST findings first, see branch (a).
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Repo-Specific Security Rules
|
|
72
|
+
|
|
73
|
+
Projects can declare a `docs:` list in `.rafter.yml` pointing at repo-specific security guides, threat models, or compliance policies — files or URLs. **Before doing any security-relevant work (scanning, reviewing, writing auth/crypto/input-handling code), check for these docs:**
|
|
87
74
|
|
|
88
|
-
Or create `.env` file:
|
|
89
75
|
```bash
|
|
90
|
-
|
|
76
|
+
rafter docs list # enumerate available docs (no network)
|
|
77
|
+
rafter docs list --tag threat-model # filter by tag
|
|
78
|
+
rafter docs show secure-coding # read one by id (fetches + caches URLs)
|
|
79
|
+
rafter docs show owasp # id OR tag — if a tag matches, all tagged docs are concatenated
|
|
91
80
|
```
|
|
92
81
|
|
|
93
|
-
|
|
82
|
+
If docs exist, treat them as authoritative project rules: they override general guidance when they conflict. If no docs are configured (`exit 3` / "No docs configured"), fall back to the standard OWASP / ASVS advice.
|
|
94
83
|
|
|
95
|
-
|
|
96
|
-
1. Trigger scan: `rafter run`
|
|
97
|
-
2. Get results: `rafter get <scan-id>`
|
|
98
|
-
3. Review findings and suggest fixes
|
|
84
|
+
MCP-connected agents: the same surface is exposed as the `rafter://docs` resource plus `list_docs` / `get_doc` tools.
|
|
99
85
|
|
|
100
|
-
|
|
101
|
-
1. Check quota: `rafter usage`
|
|
102
|
-
2. Trigger scan on feature branch: `rafter run --branch feature-branch`
|
|
103
|
-
3. Review results before creating PR
|
|
86
|
+
## Fast Path (most common)
|
|
104
87
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
88
|
+
```bash
|
|
89
|
+
rafter scan local . # secrets, offline, exit 0/1/2
|
|
90
|
+
rafter run # remote SAST/SCA (auto-detects repo/branch)
|
|
91
|
+
rafter get <scan-id> # fetch results
|
|
92
|
+
rafter usage # check API quota
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- Exit `0` = clean / no findings
|
|
96
|
+
- Exit `1` = findings detected OR error
|
|
97
|
+
- Exit `2` = invalid input / scan not found
|
|
109
98
|
|
|
110
|
-
|
|
99
|
+
Full CLI tree: **Read `docs/cli-reference.md`**. Full digest: `rafter brief commands`.
|
|
111
100
|
|
|
112
|
-
|
|
113
|
-
- **Code security findings** - SAST issues, security anti-patterns, hardcoded credentials
|
|
114
|
-
- **Configuration issues** - Insecure settings, exposed secrets
|
|
115
|
-
- **Severity levels** - Each finding rated by risk impact
|
|
101
|
+
## Configuration
|
|
116
102
|
|
|
117
|
-
|
|
103
|
+
Remote scanning needs an API key:
|
|
118
104
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
4. **Actionable recommendations** - Provide specific fixes for each finding
|
|
123
|
-
5. **Graceful degradation** - If RAFTER_API_KEY is not set, use `rafter scan local` instead. Don't let a missing key block the workflow.
|
|
105
|
+
```bash
|
|
106
|
+
export RAFTER_API_KEY="..." # or put it in .env
|
|
107
|
+
```
|
|
124
108
|
|
|
125
|
-
|
|
109
|
+
Without a key, local scanning still works fully — do not block the workflow.
|
|
126
110
|
|
|
127
|
-
|
|
128
|
-
- Wait for scan completion or show scan ID for later retrieval
|
|
129
|
-
- Parse JSON output for structured analysis
|
|
130
|
-
- Link findings to specific files and lines when available
|
|
111
|
+
## Strengthen the Project
|
|
131
112
|
|
|
132
|
-
|
|
113
|
+
If this repo doesn't have Rafter wired in yet:
|
|
133
114
|
|
|
134
|
-
|
|
135
|
-
- `rafter
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
- `rafter brief setup/<platform>` — platform-specific integration guide
|
|
115
|
+
- `rafter agent install-hook` — pre-commit secret scan
|
|
116
|
+
- `rafter ci init` — CI workflow with scanning
|
|
117
|
+
- `.rafter.yml` — project-specific policy
|
|
118
|
+
- `rafter brief setup/<platform>` — per-agent integration guide
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Rafter Remote Backend — Fast vs Plus
|
|
2
|
+
|
|
3
|
+
When to reach for the Rafter API instead of (or in addition to) the local scanner, and what to expect in terms of depth, cost, and latency.
|
|
4
|
+
|
|
5
|
+
## Local vs Remote — Which First?
|
|
6
|
+
|
|
7
|
+
| Question | Answer |
|
|
8
|
+
|---|---|
|
|
9
|
+
| "Are there leaked secrets in this diff/repo?" | **Local first** (`rafter scan local .`). Deterministic, offline, sub-second. |
|
|
10
|
+
| "Any SAST issues — SQLi, XSS, insecure deserialization, weak crypto?" | **Remote** (`rafter run`). Needs the backend's analyzers. |
|
|
11
|
+
| "Are my dependencies vulnerable (CVEs)?" | **Remote** — SCA runs server-side. |
|
|
12
|
+
| "I'm in a CI pipeline without a `RAFTER_API_KEY`" | **Local only**. Don't fail the build on a missing key. |
|
|
13
|
+
| "I need a deep, agent-driven review with hypotheses and cross-file reasoning" | **Remote plus** (`--mode plus`). |
|
|
14
|
+
|
|
15
|
+
Rule of thumb: local is a guardrail; remote is a review.
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
export RAFTER_API_KEY="..."
|
|
21
|
+
# or
|
|
22
|
+
echo "RAFTER_API_KEY=..." >> .env
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Private GitHub repos need `RAFTER_GITHUB_TOKEN` (or `--github-token`) so the backend can clone the ref.
|
|
26
|
+
|
|
27
|
+
Check quota with `rafter usage` before firing a batch of scans.
|
|
28
|
+
|
|
29
|
+
If the key is missing, `rafter run` exits with a clear error — **do not** prompt the user mid-flow; recommend `rafter scan local` and move on.
|
|
30
|
+
|
|
31
|
+
## Modes
|
|
32
|
+
|
|
33
|
+
### `--mode fast` (default)
|
|
34
|
+
|
|
35
|
+
Deterministic SAST + SCA + secret detection via the analyzer pipeline. Same input → same output. Good for CI gates and PR checks.
|
|
36
|
+
|
|
37
|
+
- **Latency**: typically seconds to a couple of minutes, depending on repo size.
|
|
38
|
+
- **Cost**: lowest per-scan. Free tier covers casual use. See `rafter brief pricing`.
|
|
39
|
+
- **Output**: stable JSON; findings carry `ruleId`, `severity`, `file`, `line`, `confidence`.
|
|
40
|
+
|
|
41
|
+
### `--mode plus`
|
|
42
|
+
|
|
43
|
+
Agentic deep-dive pass on top of fast mode: cross-file reasoning, data-flow hypotheses, design-level flags. Non-deterministic but reproducible in aggregate.
|
|
44
|
+
|
|
45
|
+
- **Latency**: minutes (larger repos can take longer).
|
|
46
|
+
- **Cost**: higher per-scan. Use when fast mode has flagged something worth triaging deeply, or on a release candidate.
|
|
47
|
+
- **Output**: same JSON shape as fast mode, plus narrative `notes` and higher-confidence chains.
|
|
48
|
+
|
|
49
|
+
Recommended flow:
|
|
50
|
+
1. `rafter scan local .` — secrets guardrail in dev loop.
|
|
51
|
+
2. `rafter run --mode fast` — every PR in CI.
|
|
52
|
+
3. `rafter run --mode plus` — before release, or when a fast-mode finding needs deeper context.
|
|
53
|
+
|
|
54
|
+
## Authentication & Data Handling
|
|
55
|
+
|
|
56
|
+
- The backend clones the specified ref, runs analysis, returns results, and **deletes the code**. No long-term retention of source.
|
|
57
|
+
- Scan artifacts (findings JSON, reports) are retained so `rafter get <scan-id>` works after the fact.
|
|
58
|
+
- Self-hosted / VPC deployments are an enterprise option; see rafter.so.
|
|
59
|
+
|
|
60
|
+
## Output Contract
|
|
61
|
+
|
|
62
|
+
Every remote scan returns:
|
|
63
|
+
|
|
64
|
+
```jsonc
|
|
65
|
+
{
|
|
66
|
+
"scanId": "scan_...",
|
|
67
|
+
"status": "completed" | "running" | "failed",
|
|
68
|
+
"mode": "fast" | "plus",
|
|
69
|
+
"findings": [
|
|
70
|
+
{ "ruleId": "...", "severity": "critical|high|medium|low|info",
|
|
71
|
+
"file": "...", "line": 42, "confidence": "high|medium|low",
|
|
72
|
+
"title": "...", "description": "...", "recommendation": "..." }
|
|
73
|
+
],
|
|
74
|
+
"summary": { "critical": 0, "high": 2, "medium": 5, "low": 3 }
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
See `shared-docs/CLI_SPEC.md` for the full schema. See `docs/finding-triage.md` for how to read a finding.
|
|
79
|
+
|
|
80
|
+
## Async / Non-Blocking Scans
|
|
81
|
+
|
|
82
|
+
`rafter run --skip-interactive` returns the `scan_id` immediately. Poll later:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
SCAN=$(rafter run --skip-interactive --format json | jq -r .scanId)
|
|
86
|
+
# ... do other work ...
|
|
87
|
+
rafter get "$SCAN" --format json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
This is the pattern for long-running CI jobs and background agent loops.
|
|
91
|
+
|
|
92
|
+
## Latency & Cost Expectations (rule of thumb)
|
|
93
|
+
|
|
94
|
+
| Repo size | fast | plus |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| < 5k LOC | ~10–30s | ~1–3 min |
|
|
97
|
+
| 5k – 50k LOC | ~30s – 2 min | ~3–10 min |
|
|
98
|
+
| 50k+ LOC | minutes | tens of minutes |
|
|
99
|
+
|
|
100
|
+
Plus mode's latency scales with "how much there is to reason about", not strictly LOC. Don't block an agent turn on plus; use `--skip-interactive` and poll.
|
|
101
|
+
|
|
102
|
+
## When NOT to use the remote backend
|
|
103
|
+
|
|
104
|
+
- You're iterating locally on a tiny diff — local scan + lint is faster.
|
|
105
|
+
- You have no network / no API key — stay local.
|
|
106
|
+
- You've already run the same scan ten minutes ago with no code changes — cache the last result instead of re-scanning.
|
|
@@ -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`.
|