Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Rafter is a security CLI for AI coding agents. It ships as two feature-identical

- `node/src/commands/` — CLI commands (commander.js)
- `node/src/core/` — Command interceptor, audit logger, config manager
- `node/src/scanners/` — Gitleaks integration + regex-based secret scanner
- `node/src/scanners/` — Betterleaks integration + regex-based secret scanner
- `node/src/commands/agent/init.ts` — Per-platform installation logic (8 platforms)
- `python/rafter_cli/` — Mirrors the Node structure with typer
- `shared-docs/CLI_SPEC.md` — Canonical output contracts and exit codes
Expand All @@ -29,7 +29,7 @@ Rafter is a security CLI for AI coding agents. It ships as two feature-identical
## Key Patterns

- Commands export a `createXCommand()` factory (Node) or use `@app.command()` decorators (Python)
- Scanners use dual-engine: Gitleaks binary first, regex fallback. Patterns defined in `secret-patterns.ts` / `secret_patterns.py`
- Scanners use dual-engine: Betterleaks binary first, regex fallback. Patterns defined in `secret-patterns.ts` / `secret_patterns.py`
- Risk classification: critical > high > medium > low
- Audit log: JSONL format, append-only, documented schema in CLI_SPEC.md
- MCP server: 4 tools + 2 resources over stdio transport
2 changes: 1 addition & 1 deletion .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
- id: rafter-scan
name: Rafter Secret Scanner
description: Scan staged files for secrets (21+ patterns, Gitleaks integration)
description: Scan staged files for secrets (21+ patterns, Betterleaks integration)
entry: rafter scan local --staged --quiet
language: system
stages: [pre-commit]
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Changed
- **Secret-scanning engine migrated from gitleaks to betterleaks** (Node + Python, rc-ksy / rc-963). [Betterleaks](https://github.com/betterleaks/betterleaks) v1.1.2 is the gitleaks successor maintained by the same authors. JSON report shape is unchanged; what changed is the binary, the CLI subcommand (`detect --no-git -s` → `dir <path>`), the release URL, and the checksum filename.
- **Breaking:** the legacy CLI surface has been removed entirely. `--with-gitleaks`, `--engine gitleaks`, and `rafter agent update-gitleaks` now error out (unknown option / invalid engine / unknown command). Use `--with-betterleaks`, `--engine betterleaks`, and `rafter agent update-betterleaks`.
- **Soft landing for existing installs:** `rafter agent verify` and `rafter agent status` continue to detect a leftover `~/.rafter/bin/gitleaks` (or `gitleaks` on PATH) and emit "legacy gitleaks at X — run: rafter agent update-betterleaks" instead of a confusing "not found". Verify exits 0 in this case (was a hard fail before this fix).
- **Supply-chain hardening:** SHA256 hashes for the bundled `BETTERLEAKS_VERSION` are pinned in source, so the default install no longer trusts the release-page `checksums.txt` to authenticate itself. Tar/zip extraction now rejects symlink/hardlink/device entries (mitigates a malicious-release symlink-redirect that the subsequent `chmod +x` would have followed). Downloads refuse non-https URLs. The optional `--version` flag is validated against `^[A-Za-z0-9._-]+$` to neutralize URL injection. Targets passed to betterleaks are preceded by `--` so a path beginning with `-` isn't parsed as a flag.
- Internal renames: `GitleaksScanner` → `BetterleaksScanner`, `*_gitleaks` methods → `*_betterleaks`, `GITLEAKS_VERSION` → `BETTERLEAKS_VERSION`. New tests cover pinned-hash table completeness, `--version` validation, non-https refusal, and the alias-removal contract.

- **OpenClaw integration rebuilt as a ClawHub-shaped skill** (Node + Python, rf-zgwj). Previously rafter wrote a single markdown file at `~/.openclaw/skills/rafter-security.md` — a path OpenClaw never read at runtime. ClawHub auto-discovers skills from `<workspace>/skills/<name>/SKILL.md`. The new install:
- Writes `~/.openclaw/workspace/skills/rafter-security/SKILL.md` (the canonical ClawHub path).
- Adds the ClawHub-required top-level frontmatter (`name`, `description`, `version`) alongside the existing `openclaw:` runtime block. Now passes ClawHub's metadata schema check.
Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ cd python && poetry install && pytest
│ │ │ ├── audit-logger.ts # JSONL audit trail
│ │ │ └── config-manager.ts # .rafter.yml + global config
│ │ └── scanners/
│ │ ├── gitleaks.ts # Gitleaks binary integration
│ │ ├── betterleaks.ts # Betterleaks binary integration
│ │ ├── secret-patterns.ts # DEFAULT_SECRET_PATTERNS array (21+ patterns)
│ │ └── regex-scanner.ts # RegexScanner class (imports secret-patterns)
│ └── tests/ # Vitest test files
├── python/ # Python implementation (rafter-cli on PyPI)
│ ├── rafter_cli/
│ │ ├── commands/ # CLI commands (typer)
│ │ ├── core/ # Mirrors node/src/core/
│ │ └── scanners/ # secret_patterns.py + regex_scanner.py + gitleaks.py
│ │ └── scanners/ # secret_patterns.py + regex_scanner.py + betterleaks.py
│ └── tests/ # pytest test files
├── shared-docs/ # Canonical specs (both implementations follow these)
│ └── CLI_SPEC.md # Output contracts, exit codes, JSON schemas
Expand All @@ -58,7 +58,7 @@ cd python && poetry install && pytest

**Risk classification**: Commands are classified into 4 tiers (critical/high/medium/low) by pattern matching in `command-interceptor.ts`. Policy files (`.rafter.yml`) can override defaults.

**Secret scanning**: Dual-engine — tries Gitleaks binary first (higher accuracy), falls back to built-in regex patterns (21+ patterns, zero dependencies). Deterministic for a given version.
**Secret scanning**: Dual-engine — tries Betterleaks binary first (higher accuracy), falls back to built-in regex patterns (21+ patterns, zero dependencies). Deterministic for a given version. Betterleaks is the gitleaks successor maintained by the original gitleaks authors. Existing installs with a leftover `~/.rafter/bin/gitleaks` are detected by `agent verify`/`status` so users get an upgrade hint, but the legacy CLI flags (`--with-gitleaks`, `--engine gitleaks`, `update-gitleaks`) have been removed.

**MCP server**: `rafter mcp serve` exposes 4 tools (`scan_secrets`, `evaluate_command`, `read_audit_log`, `get_config`) and 2 resources (`rafter://config`, `rafter://policy`) over stdio.

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ FROM node:22-alpine

RUN apk add --no-cache git \
&& npm install -g @rafter-security/cli \
&& rafter agent init --with-gitleaks 2>/dev/null || true
&& rafter agent init --with-betterleaks

WORKDIR /workspace

Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ rafter secrets .
```sh
rafter agent init --all
# → Installs all detected integrations
# → Downloads Gitleaks (or falls back to built-in scanner)
# → Downloads Betterleaks (or falls back to built-in scanner)
```

**3. Try to commit—hook blocks it**
Expand Down Expand Up @@ -184,7 +184,7 @@ This command:
- Creates `~/.rafter/` config and audit log (or `./.rafter/` with `--local` for ephemeral / containerized / benchmark setups)
- Auto-detects Claude Code, Codex CLI, OpenClaw, Gemini, Cursor, Windsurf, Continue.dev, and Aider
- With `--with-*` or `--all`: installs Rafter skills/extensions to opted-in agents
- With `--with-gitleaks` or `--all`: downloads [Gitleaks](https://github.com/gitleaks/gitleaks) for enhanced secret scanning (falls back to built-in 21-pattern regex scanner)
- With `--with-betterleaks` or `--all`: downloads [Betterleaks](https://github.com/betterleaks/betterleaks) (the gitleaks successor maintained by the original gitleaks authors) for enhanced secret scanning. Falls back to built-in 21-pattern regex scanner.

Use `rafter agent list/enable/disable` for granular per-component control after the initial install — toggle any platform on or off without re-running `init`.

Expand All @@ -197,7 +197,7 @@ rafter secrets . # scan directory
rafter secrets ./config.js # scan specific file
rafter secrets --staged # scan git staged files only
rafter secrets --diff HEAD~1 # scan files changed since a git ref
rafter secrets --history # scan full git history (requires gitleaks engine)
rafter secrets --history # scan full git history (requires betterleaks engine)
rafter secrets --json # structured output
rafter secrets --quiet # silent unless secrets found (CI-friendly)
```
Expand All @@ -223,7 +223,7 @@ Exit code 1 if secrets found, 0 if clean.

Raw secret values are never included in output. Pipe to `jq`, feed to CI gates, or hand to any tool that reads JSON.

**Engine selection:** Uses Gitleaks when available (more patterns), falls back to built-in regex. Override with `--engine gitleaks|patterns|auto`.
**Engine selection:** Uses Betterleaks when available (more patterns), falls back to built-in regex. Override with `--engine betterleaks|patterns|auto`.

### Pre-Commit Hook

Expand Down Expand Up @@ -524,7 +524,7 @@ Exit codes are part of Rafter's output contract — CI pipelines and orchestrato
~/.rafter/
├── config.json # Configuration
├── audit.jsonl # Security event log (JSON lines)
├── bin/gitleaks # Gitleaks binary
├── bin/betterleaks # Betterleaks binary
├── patterns/ # Custom patterns (reserved)
└── git-hooks/ # Global pre-commit hook (if --global)
```
Expand Down
4 changes: 2 additions & 2 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ rafter agent init --with-continue # MCP server
rafter agent init --with-aider # MCP server
rafter agent init --with-openclaw # Skills

# Also download Gitleaks for enhanced scanning (optional, falls back to built-in 21-pattern regex)
rafter agent init --with-claude-code --with-gitleaks
# Also download Betterleaks for enhanced scanning (optional, falls back to built-in 21-pattern regex)
rafter agent init --with-claude-code --with-betterleaks
```

**What init does per platform:**
Expand Down
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Rafter Security — GitHub Action
#
# Deterministic secret scanning for CI. 21+ credential patterns via Gitleaks,
# Deterministic secret scanning for CI. 21+ credential patterns via Betterleaks,
# stable exit codes (0 = clean, 1 = findings, 2 = error), structured JSON output.
# No API key required. No code leaves the runner.
#
Expand Down
6 changes: 3 additions & 3 deletions drafts/show-hn/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ Responses written in founder voice. Adapt as needed based on the actual question

---

## "How is this different from gitleaks / trufflehog?"
## "How is this different from betterleaks (or gitleaks) / trufflehog?"

Rafter actually wraps gitleaks when it's available -- if the binary is on your PATH, we use it as the primary scanner because it's excellent. Our built-in regex engine (21+ patterns) is the fallback for zero-dependency environments.
Rafter actually wraps betterleaks (the gitleaks successor) when it's available -- if the binary is on your PATH, we use it as the primary scanner because it's excellent. Our built-in regex engine (21+ patterns) is the fallback for zero-dependency environments.

The difference is everything around the scan. Gitleaks and trufflehog are standalone secret scanners. Rafter adds command interception (blocking `curl | bash` before your agent runs it), audit logging of agent sessions, MCP integration so the agent itself can check for secrets, pre-commit hooks, and one-command setup for 8 different AI platforms. If you're just scanning repos for secrets, gitleaks is great and you don't need us. If you're running AI coding agents and want guardrails around the whole session, that's what Rafter is for.
The difference is everything around the scan. Betterleaks and trufflehog are standalone secret scanners. Rafter adds command interception (blocking `curl | bash` before your agent runs it), audit logging of agent sessions, MCP integration so the agent itself can check for secrets, pre-commit hooks, and one-command setup for 8 different AI platforms. If you're just scanning repos for secrets, betterleaks is great and you don't need us. If you're running AI coding agents and want guardrails around the whole session, that's what Rafter is for.

---

Expand Down
2 changes: 1 addition & 1 deletion drafts/show-hn/post.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ If you use Claude Code, Codex CLI, Cursor, Gemini CLI, or similar tools, your AI

**What it does:**

- **Secret scanning**: 21+ built-in regex patterns plus optional Gitleaks integration. Deterministic for a given version. Stable exit codes for CI.
- **Secret scanning**: 21+ built-in regex patterns plus optional Betterleaks integration (the gitleaks successor). Deterministic for a given version. Stable exit codes for CI.
- **Command interception**: Classifies commands into risk tiers (critical/high/medium/low) and enforces approval policies before execution.
- **Audit logging**: JSONL trail of every command your agent runs and every secret scan result.
- **MCP server**: 4 tools (`scan_secrets`, `evaluate_command`, `read_audit_log`, `get_config`) so AI agents can query security status natively.
Expand Down
4 changes: 2 additions & 2 deletions fixtures/vulnerable-repo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ validating Rafter's secret scanning and command interception.
# Scan with Rafter regex scanner
rafter scan local ./fixtures/vulnerable-repo

# Scan with Gitleaks engine
rafter scan local ./fixtures/vulnerable-repo --engine gitleaks
# Scan with Betterleaks engine
rafter scan local ./fixtures/vulnerable-repo --engine betterleaks

# Scan with built-in patterns engine (tests all 21+ patterns)
rafter scan local ./fixtures/vulnerable-repo --engine patterns
Expand Down
4 changes: 2 additions & 2 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ rafter secrets --diff main # only files changed since a ref
rafter secrets --json . # JSON output for piping to jq / orchestrators

# Install Rafter into every detected agent platform on this machine
rafter agent init --all # also downloads gitleaks binary
rafter agent init --all # also downloads betterleaks binary
rafter agent init --interactive # prompted setup
rafter agent init --with-claude-code # one specific platform

Expand Down Expand Up @@ -118,7 +118,7 @@ Full schema: [docs.rafter.so/policy](https://docs.rafter.so/policy) (or see `sha
| Continue.dev | `--with-continue` | MCP server config |
| Aider | `--with-aider` | MCP server config |

Plus `--with-gitleaks` to install the upstream Gitleaks binary for higher-recall secret detection (Rafter falls back to 21+ built-in regex patterns if absent).
Plus `--with-betterleaks` to install the upstream Betterleaks binary (the gitleaks successor) for higher-recall secret detection (Rafter falls back to 21+ built-in regex patterns if absent).

## MCP Server

Expand Down
10 changes: 5 additions & 5 deletions node/.claude/skills/rafter/docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ Example: `rafter run --repo myorg/api --branch feature/auth --mode plus --format

### `rafter scan local [path]`

Local secret scan. Deterministic, offline, no API key. Dual-engine: Gitleaks binary if present, built-in regex fallback (21+ patterns).
Local secret scan. Deterministic, offline, no API key. Dual-engine: Betterleaks binary if present, built-in regex fallback (21+ patterns).

When: pre-commit, pre-push, fast first pass before remote scan, air-gapped envs.

Useful flags: `--history` (scan git history with Gitleaks), `--format json`, `--quiet`.
Useful flags: `--history` (scan git history with Betterleaks), `--format json`, `--quiet`.

Example: `rafter scan local . --format json`

Expand Down Expand Up @@ -82,7 +82,7 @@ Alias for `rafter scan local` kept for back-compat. Prefer `rafter scan local`.

### `rafter agent status` · `rafter agent verify`

`status`: dump config, hook state, gitleaks availability, audit log location.
`status`: dump config, hook state, betterleaks availability, audit log location.
`verify`: sanity-check installation; exit non-zero if anything is broken.

### `rafter agent init [--with-<platform>]`
Expand All @@ -109,9 +109,9 @@ Snapshot current findings so only *new* ones fail future scans.

Emit a ready-to-paste instruction block for an agent's system prompt.

### `rafter agent update-gitleaks`
### `rafter agent update-betterleaks`

Download / upgrade the Gitleaks binary Rafter uses for local scans.
Download / upgrade the Betterleaks binary Rafter uses for local scans.

---

Expand Down
2 changes: 1 addition & 1 deletion node/resources/agents/rafter.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Rafter ships three CLI tiers **and** four in-repo skills. They are NOT interchan

1. **`rafter run`** (default mode) — remote SAST + SCA + secrets via the Rafter API. Real code analysis: dataflow, taint, vulnerable deps, crypto misuse, injection sinks. Needs `RAFTER_API_KEY`. **This is the default for "is this safe / secure / production worthy?".**
2. **`rafter run --mode plus`** — agentic deep-dive on suspicious patterns. Slower, higher signal. Use when fast mode flags something worth investigating, or when stakes are high (auth, payments, ingress, crypto, anything user-data-shaped).
3. **`rafter secrets [path]`** — local secrets only (regex + gitleaks for hardcoded API keys, tokens, private keys). Fast, offline, no key. **NOT a code security scan.** Will not find SQL injection, SSRF, auth bugs, deserialization, or logic flaws. Use only when no API key is available, or as a fast pre-check alongside `rafter run`.
3. **`rafter secrets [path]`** — local secrets only (regex + betterleaks for hardcoded API keys, tokens, private keys). Fast, offline, no key. **NOT a code security scan.** Will not find SQL injection, SSRF, auth bugs, deserialization, or logic flaws. Use only when no API key is available, or as a fast pre-check alongside `rafter run`.

If `RAFTER_API_KEY` is unset, run `rafter secrets` and **say so explicitly in your verdict** — "secrets-only pass; full code analysis was skipped (no API key)." Do not claim the code was "scanned" without that qualification. Never silently downgrade.

Expand Down
2 changes: 1 addition & 1 deletion node/resources/rafter-security-skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ To initialize Rafter, use **opt-in** `--with-*` flags to select integrations. Th
```bash
# Install specific integrations (opt-in)
rafter agent init --with-openclaw
rafter agent init --with-claude-code --with-gitleaks
rafter agent init --with-claude-code --with-betterleaks

# Install everything detected
rafter agent init --all
Expand Down
2 changes: 1 addition & 1 deletion node/resources/skills/rafter/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ allowed-tools: [Bash, Read]

Rafter ships three tiers. **They are not interchangeable.** The local tier is narrow; skipping remote analysis is the #1 way agents under-use rafter.

1. **Local (`rafter secrets`)** — secrets only. Regex + gitleaks for hardcoded API keys, tokens, private keys. Fast, offline, no key. **This is NOT a code security scan.** It will not find SQL injection, SSRF, auth bugs, insecure deserialization, logic flaws, or dependency vulns. If an agent's entire rafter interaction was `rafter secrets .` and it exited clean, the agent has done secret-hygiene only — not security review.
1. **Local (`rafter secrets`)** — secrets only. Regex + betterleaks for hardcoded API keys, tokens, private keys. Fast, offline, no key. **This is NOT a code security scan.** It will not find SQL injection, SSRF, auth bugs, insecure deserialization, logic flaws, or dependency vulns. If an agent's entire rafter interaction was `rafter secrets .` and it exited clean, the agent has done secret-hygiene only — not security review.
2. **Remote fast (`rafter run`, default mode)** — SAST + SCA + secrets via the Rafter API. This is the real code-analysis pass: dataflow, taint, known-vulnerable dependencies, crypto misuse, injection sinks. Needs `RAFTER_API_KEY`.
3. **Remote plus (`rafter run --mode plus`)** — agentic deep-dive: LLM-guided investigation of suspicious patterns the rules engine flags. Slower, higher signal. Code is deleted server-side after the run.

Expand Down
Loading
Loading