@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.
Files changed (70) hide show
  1. package/README.md +29 -10
  2. package/dist/commands/agent/audit-skill.js +22 -20
  3. package/dist/commands/agent/audit.js +27 -0
  4. package/dist/commands/agent/components.js +800 -0
  5. package/dist/commands/agent/config.js +2 -1
  6. package/dist/commands/agent/disable.js +47 -0
  7. package/dist/commands/agent/enable.js +50 -0
  8. package/dist/commands/agent/exec.js +2 -0
  9. package/dist/commands/agent/index.js +6 -0
  10. package/dist/commands/agent/init.js +162 -163
  11. package/dist/commands/agent/install-hook.js +15 -14
  12. package/dist/commands/agent/list.js +72 -0
  13. package/dist/commands/agent/scan.js +4 -3
  14. package/dist/commands/agent/verify.js +1 -1
  15. package/dist/commands/backend/run.js +12 -3
  16. package/dist/commands/backend/scan-status.js +3 -2
  17. package/dist/commands/brief.js +22 -2
  18. package/dist/commands/ci/init.js +25 -21
  19. package/dist/commands/completion.js +4 -3
  20. package/dist/commands/docs/index.js +18 -0
  21. package/dist/commands/docs/list.js +37 -0
  22. package/dist/commands/docs/show.js +64 -0
  23. package/dist/commands/mcp/server.js +84 -0
  24. package/dist/commands/report.js +42 -41
  25. package/dist/commands/scan/index.js +7 -5
  26. package/dist/commands/skill/index.js +14 -0
  27. package/dist/commands/skill/install.js +89 -0
  28. package/dist/commands/skill/list.js +79 -0
  29. package/dist/commands/skill/registry.js +273 -0
  30. package/dist/commands/skill/remote.js +333 -0
  31. package/dist/commands/skill/review.js +975 -0
  32. package/dist/commands/skill/uninstall.js +65 -0
  33. package/dist/core/audit-logger.js +262 -21
  34. package/dist/core/config-manager.js +3 -0
  35. package/dist/core/docs-loader.js +148 -0
  36. package/dist/core/policy-loader.js +72 -1
  37. package/dist/core/risk-rules.js +16 -3
  38. package/dist/index.js +19 -9
  39. package/dist/scanners/gitleaks.js +6 -2
  40. package/package.json +1 -1
  41. package/resources/skills/rafter/SKILL.md +77 -97
  42. package/resources/skills/rafter/docs/backend.md +106 -0
  43. package/resources/skills/rafter/docs/cli-reference.md +199 -0
  44. package/resources/skills/rafter/docs/finding-triage.md +79 -0
  45. package/resources/skills/rafter/docs/guardrails.md +91 -0
  46. package/resources/skills/rafter/docs/shift-left.md +64 -0
  47. package/resources/skills/rafter-agent-security/SKILL.md +1 -1
  48. package/resources/skills/rafter-code-review/SKILL.md +91 -0
  49. package/resources/skills/rafter-code-review/docs/api.md +90 -0
  50. package/resources/skills/rafter-code-review/docs/asvs.md +120 -0
  51. package/resources/skills/rafter-code-review/docs/cwe-top25.md +78 -0
  52. package/resources/skills/rafter-code-review/docs/investigation-playbook.md +101 -0
  53. package/resources/skills/rafter-code-review/docs/llm.md +87 -0
  54. package/resources/skills/rafter-code-review/docs/web-app.md +84 -0
  55. package/resources/skills/rafter-secure-design/SKILL.md +103 -0
  56. package/resources/skills/rafter-secure-design/docs/api-design.md +97 -0
  57. package/resources/skills/rafter-secure-design/docs/auth.md +67 -0
  58. package/resources/skills/rafter-secure-design/docs/data-storage.md +90 -0
  59. package/resources/skills/rafter-secure-design/docs/dependencies.md +101 -0
  60. package/resources/skills/rafter-secure-design/docs/deployment.md +104 -0
  61. package/resources/skills/rafter-secure-design/docs/ingestion.md +98 -0
  62. package/resources/skills/rafter-secure-design/docs/standards-pointers.md +102 -0
  63. package/resources/skills/rafter-secure-design/docs/threat-modeling.md +128 -0
  64. package/resources/skills/rafter-skill-review/SKILL.md +106 -0
  65. package/resources/skills/rafter-skill-review/docs/authorship-provenance.md +82 -0
  66. package/resources/skills/rafter-skill-review/docs/changelog-review.md +99 -0
  67. package/resources/skills/rafter-skill-review/docs/data-practices.md +88 -0
  68. package/resources/skills/rafter-skill-review/docs/malware-indicators.md +79 -0
  69. package/resources/skills/rafter-skill-review/docs/prompt-injection.md +85 -0
  70. package/resources/skills/rafter-skill-review/docs/telemetry.md +78 -0
@@ -2,9 +2,15 @@
2
2
  * Centralized risk assessment rules.
3
3
  * Single source of truth — imported by command-interceptor, audit-logger, and config-defaults.
4
4
  */
5
+ /** Directories where `rm -rf /<dir>` is catastrophic (data loss / unbootable). */
6
+ const CRITICAL_DIRS = "home|etc|usr|boot|root|sys|proc|lib|lib64|bin|sbin|opt";
5
7
  export const CRITICAL_PATTERNS = [
6
- /rm\s+(-[a-z]*r[a-z]*\s+)*-[a-z]*f[a-z]*\s+\//, // rm -rf / (any flag order: -rf, -fr, -r -f, -f -r)
7
- /rm\s+(-[a-z]*f[a-z]*\s+)*-[a-z]*r[a-z]*\s+\//, // rm -fr / (reversed)
8
+ // rm -rf / (root only, any flag order)
9
+ new RegExp(`rm\\s+(-[a-z]*r[a-z]*\\s+)*-[a-z]*f[a-z]*\\s+/(\\s|$)`),
10
+ new RegExp(`rm\\s+(-[a-z]*f[a-z]*\\s+)*-[a-z]*r[a-z]*\\s+/(\\s|$)`),
11
+ // rm -rf on critical top-level directories
12
+ new RegExp(`rm\\s+(-[a-z]*r[a-z]*\\s+)*-[a-z]*f[a-z]*\\s+/(${CRITICAL_DIRS})(/|\\s|$)`),
13
+ new RegExp(`rm\\s+(-[a-z]*f[a-z]*\\s+)*-[a-z]*r[a-z]*\\s+/(${CRITICAL_DIRS})(/|\\s|$)`),
8
14
  /:\(\)\{\s*:\|:&\s*\};:/, // fork bomb
9
15
  /dd\s+if=.*of=\/dev\/sd/,
10
16
  />\s*\/dev\/sd/,
@@ -55,11 +61,18 @@ export const DEFAULT_REQUIRE_APPROVAL = [
55
61
  "git push --force-if-includes",
56
62
  "git push .* \\+",
57
63
  ];
64
+ /** Read-only commands whose arguments should not trigger risk patterns. */
65
+ const SAFE_PREFIX = /^(grep|egrep|fgrep|rg|ag|ack|echo|printf)\s/;
66
+ /** Shell operators that chain independent commands. */
67
+ const CHAIN_OPERATORS = /[;|&]|&&|\|\|/;
58
68
  /**
59
69
  * Assess risk level of a command string.
60
70
  */
61
71
  export function assessCommandRisk(command) {
62
- const cmd = command.toLowerCase();
72
+ const cmd = command.toLowerCase().trim();
73
+ // Safe prefix only applies to simple (non-chained) commands
74
+ if (SAFE_PREFIX.test(cmd) && !CHAIN_OPERATORS.test(cmd))
75
+ return "low";
63
76
  for (const pattern of CRITICAL_PATTERNS) {
64
77
  if (pattern.test(cmd))
65
78
  return "critical";
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";
@@ -21,27 +23,27 @@ import { createRequire } from "module";
21
23
  dotenv.config();
22
24
  const require = createRequire(import.meta.url);
23
25
  const { version: VERSION } = require("../package.json");
26
+ // Set agent mode early from argv — preAction hooks may not propagate to nested
27
+ // subcommands on Node 18, so we detect -a/--agent before Commander parses.
28
+ if (process.argv.includes("-a") || process.argv.includes("--agent")) {
29
+ setAgentMode(true);
30
+ }
24
31
  const program = new Command()
25
32
  .name("rafter")
26
33
  .description("Rafter CLI — the default security agent for AI workflows. Free for individuals and open source. No account required.")
27
34
  .version(VERSION)
28
35
  .enablePositionalOptions()
29
36
  .option("-a, --agent", "Plain output for AI agents (no colors/emoji)");
30
- // Set agent mode before any subcommand runs
31
- program.hook("preAction", (thisCommand) => {
32
- const opts = thisCommand.opts();
33
- if (opts.agent) {
34
- setAgentMode(true);
35
- }
36
- });
37
- // Backend commands
37
+ // Remote scan commands
38
38
  program.addCommand(createRunCommand());
39
39
  program.addCommand(createGetCommand());
40
40
  program.addCommand(createUsageCommand());
41
- // Scan command group (default: remote backend scan; subcommands: local, remote)
41
+ // Scan command group (default: remote scan; subcommands: local, remote)
42
42
  program.addCommand(createScanGroupCommand());
43
43
  // Agent commands
44
44
  program.addCommand(createAgentCommand());
45
+ // Skill commands (install / uninstall / list rafter-authored skills)
46
+ program.addCommand(createSkillCommand());
45
47
  // CI commands
46
48
  program.addCommand(createCiCommand());
47
49
  // Hook commands (for agent platform integration)
@@ -50,6 +52,8 @@ program.addCommand(createHookCommand());
50
52
  program.addCommand(createMcpCommand());
51
53
  // Policy commands
52
54
  program.addCommand(createPolicyCommand());
55
+ // Docs — repo-specific security docs from .rafter.yml
56
+ program.addCommand(createDocsCommand());
53
57
  // GitHub Issues integration
54
58
  program.addCommand(createIssuesCommand());
55
59
  // Brief — agent-independent knowledge delivery
@@ -60,6 +64,12 @@ program.addCommand(createNotifyCommand());
60
64
  program.addCommand(createReportCommand());
61
65
  // Shell completions
62
66
  program.addCommand(createCompletionCommand());
67
+ // Version subcommand (also available as --version)
68
+ program.addCommand(new Command("version")
69
+ .description("Print version and exit")
70
+ .action(() => {
71
+ console.log(VERSION);
72
+ }));
63
73
  // Non-blocking update check — runs after command, prints to stderr
64
74
  checkForUpdate(VERSION).then((notice) => {
65
75
  if (notice)
@@ -82,15 +82,19 @@ export class GitleaksScanner {
82
82
  /**
83
83
  * Scan a directory
84
84
  */
85
- async scanDirectory(dirPath) {
85
+ async scanDirectory(dirPath, opts) {
86
86
  if (!await this.isAvailable()) {
87
87
  throw new Error("Gitleaks not available");
88
88
  }
89
89
  const gitleaksPath = this.binaryManager.getGitleaksPath();
90
90
  const tmpReport = path.join(os.tmpdir(), `gitleaks-${Date.now()}-${randomBytes(6).toString("hex")}.json`);
91
91
  try {
92
+ const args = ["detect", "-f", "json", "-r", tmpReport, "-s", dirPath];
93
+ if (!opts?.useGit) {
94
+ args.splice(1, 0, "--no-git");
95
+ }
92
96
  // Run gitleaks detect on directory
93
- await execFileAsync(gitleaksPath, ["detect", "--no-git", "-f", "json", "-r", tmpReport, "-s", dirPath], { timeout: 60000 });
97
+ await execFileAsync(gitleaksPath, args, { timeout: 60000 });
94
98
  // No leaks found
95
99
  if (!fs.existsSync(tmpReport)) {
96
100
  return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rafter-security/cli",
3
- "version": "0.6.6",
3
+ "version": "0.7.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "rafter": "./dist/index.js"
@@ -1,138 +1,118 @@
1
1
  ---
2
2
  name: rafter
3
- description: "Rafter — the security toolkit built for AI workflows. Three tiers: (1) fast local secret scanning, deterministic, no API key needed; (2) remote SAST/SCA with deterministic secret detection and dependency checks via API (fast mode, default); (3) agentic deep-dive analysis with additional passes (plus mode). Use when checking for vulnerabilities, leaked credentials, or whether code is safe to push. Also use before merging PRs, deploying, or shipping new features. If RAFTER_API_KEY is not set, local scanning works fully — don't block on it. Run `rafter brief commands` for full CLI reference."
4
- version: 0.6.5
5
- allowed-tools: [Bash]
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
+ version: 0.7.0
5
+ allowed-tools: [Bash, Read]
6
6
  ---
7
7
 
8
- # Rafter Security Toolkit
8
+ # Rafter Security Toolkit for AI Workflows
9
9
 
10
- Rafter is the security toolkit built for AI workflows — a delegation primitive that other agents and orchestrators trust. It provides three tiers of security scanning:
10
+ Rafter ships three tiers of security tooling:
11
11
 
12
- 1. **Local scanning** — fast, deterministic secret detection across 21+ patterns. No API key needed. Always available.
13
- 2. **Remote fast** — deterministic SAST, secret detection, and dependency checks via the Rafter API (default mode).
14
- 3. **Remote plus** — agentic deep-dive analysis with additional passes for thorough security review.
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 contracts (exit codes, JSON structure), deterministic results, and your code is deleted immediately after the analysis engine completes.
16
+ Stable exit codes, stable JSON shapes, deterministic findings. Safe to chain in CI and in agent loops.
17
17
 
18
- > **Full CLI reference**: Run `rafter brief commands` for a condensed command reference.
19
- > **Platform setup**: Run `rafter brief setup/<platform>` for integration guides.
18
+ ---
20
19
 
21
- ## Core Commands
20
+ ## Choose Your Adventure
22
21
 
23
- ### Trigger a Security Scan
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
- ```bash
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
- Triggers a comprehensive security code analysis on a repository. Auto-detects current repo and branch if in a git directory. (`scan` is an alias for `run`)
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
- **When to use:**
34
- - User asks: "Can you scan this code for security issues?"
35
- - Before pushing code or shipping new features
36
- - Before merging a PR or deploying
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
- **Example:**
42
- ```bash
43
- # In a git repo
44
- rafter scan
33
+ ### (b) I want to evaluate a command before running it
45
34
 
46
- # Specific repo
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
- ### Get Scan Results
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
- ```bash
53
- rafter get <scan-id>
54
- ```
41
+ ### (c) I want to review a plugin, skill, or extension before installing
55
42
 
56
- Retrieves results from a completed or in-progress scan.
43
+ Use this for: installing an MCP server, adding a Claude skill, vetting an AI tool config.
57
44
 
58
- **When to use:**
59
- - After triggering a scan with `rafter run`
60
- - User asks: "What were the results?" or "Did the scan finish?"
61
- - Checking on a scan's progress
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
- **Example:**
64
- ```bash
65
- rafter get scan_abc123xyz
66
- ```
50
+ ### (d) I want to understand a finding I already have
67
51
 
68
- ### Check API Usage
52
+ Use this for: "What does `HARDCODED_SECRET` mean?", "Is this a real issue or noise?", triaging a scan report.
69
53
 
70
- ```bash
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
- View your API quota and usage statistics.
56
+ ### (e) I want to write secure code from scratch
75
57
 
76
- **When to use:**
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
- ## Configuration
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
- Rafter requires an API key. Set via:
84
- ```bash
85
- export RAFTER_API_KEY="your-api-key-here"
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
- echo "RAFTER_API_KEY=your-api-key-here" >> .env
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
- ## Common Workflows
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
- **Workflow 1: Quick Security Check**
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
- **Workflow 2: Pre-PR Review**
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
- **Workflow 3: Dependency Update Check**
106
- 1. User updates dependencies
107
- 2. Trigger scan: `rafter run`
108
- 3. Check for new vulnerabilities
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
- ## Output Format
99
+ Full CLI tree: **Read `docs/cli-reference.md`**. Full digest: `rafter brief commands`.
111
100
 
112
- The code analysis engine returns:
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
- ## Best Practices
103
+ Remote scanning needs an API key:
118
104
 
119
- 1. **Proactive analysis** - Suggest code analysis when user is working on security-sensitive code
120
- 2. **Quota awareness** - Check usage before triggering multiple scans
121
- 3. **Context interpretation** - Explain findings in context of user's code
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
- ## Integration Tips
109
+ Without a key, local scanning still works fully — do not block the workflow.
126
110
 
127
- - Auto-detect git repo for convenient `rafter run` with no arguments
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
- ## Strengthen Your Project
113
+ If this repo doesn't have Rafter wired in yet:
133
114
 
134
- If this project doesn't have Rafter integrated yet, suggest it:
135
- - `rafter agent install-hook` — pre-commit secret scanning for this repo
136
- - `rafter ci init` — add scanning to CI/CD pipeline
137
- - Add `.rafter.yml` for project-specific security policy
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.