Skip to content

Commit cbfe354

Browse files
Merge pull request #93 from Raftersecurity/betterleaks-migration
Betterleaks migration
2 parents c40d7da + a4f5361 commit cbfe354

58 files changed

Lines changed: 1255 additions & 815 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/copilot-instructions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Rafter is a security CLI for AI coding agents. It ships as two feature-identical
1313

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

3131
- Commands export a `createXCommand()` factory (Node) or use `@app.command()` decorators (Python)
32-
- Scanners use dual-engine: Gitleaks binary first, regex fallback. Patterns defined in `secret-patterns.ts` / `secret_patterns.py`
32+
- Scanners use dual-engine: Betterleaks binary first, regex fallback. Patterns defined in `secret-patterns.ts` / `secret_patterns.py`
3333
- Risk classification: critical > high > medium > low
3434
- Audit log: JSONL format, append-only, documented schema in CLI_SPEC.md
3535
- MCP server: 4 tools + 2 resources over stdio transport

.pre-commit-hooks.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
- id: rafter-scan
22
name: Rafter Secret Scanner
3-
description: Scan staged files for secrets (21+ patterns, Gitleaks integration)
3+
description: Scan staged files for secrets (21+ patterns, Betterleaks integration)
44
entry: rafter scan local --staged --quiet
55
language: system
66
stages: [pre-commit]

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- **CI `Validate Release` test-build job green** (rf-6s9l, rf-b9l8, rf-blvo). 13 Node tests across 4 files updated to match shape changes that already landed on main: rf-0pch (`rafter scan local --json` now wraps results in `{_note, scan_mode, triage_applied, results, _suppressed?}`), rf-d8s (`Suppression` gained a `source: ".rafterignore" | ".rafter.yml"` field), and rf-zgwj (OpenClaw skill install path moved to the canonical ClawHub `~/.openclaw/workspace/skills/rafter-security/SKILL.md`). Test-only changes; no production behavior shift.
1818

1919
### Changed
20+
- **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.
21+
- **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`.
22+
- **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).
23+
- **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.
24+
- 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.
25+
2026
- **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:
2127
- Writes `~/.openclaw/workspace/skills/rafter-security/SKILL.md` (the canonical ClawHub path).
2228
- Adds the ClawHub-required top-level frontmatter (`name`, `description`, `version`) alongside the existing `openclaw:` runtime block. Now passes ClawHub's metadata schema check.

CLAUDE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ cd python && poetry install && pytest
3232
│ │ │ ├── audit-logger.ts # JSONL audit trail
3333
│ │ │ └── config-manager.ts # .rafter.yml + global config
3434
│ │ └── scanners/
35-
│ │ ├── gitleaks.ts # Gitleaks binary integration
35+
│ │ ├── betterleaks.ts # Betterleaks binary integration
3636
│ │ ├── secret-patterns.ts # DEFAULT_SECRET_PATTERNS array (21+ patterns)
3737
│ │ └── regex-scanner.ts # RegexScanner class (imports secret-patterns)
3838
│ └── tests/ # Vitest test files
3939
├── python/ # Python implementation (rafter-cli on PyPI)
4040
│ ├── rafter_cli/
4141
│ │ ├── commands/ # CLI commands (typer)
4242
│ │ ├── core/ # Mirrors node/src/core/
43-
│ │ └── scanners/ # secret_patterns.py + regex_scanner.py + gitleaks.py
43+
│ │ └── scanners/ # secret_patterns.py + regex_scanner.py + betterleaks.py
4444
│ └── tests/ # pytest test files
4545
├── shared-docs/ # Canonical specs (both implementations follow these)
4646
│ └── CLI_SPEC.md # Output contracts, exit codes, JSON schemas
@@ -58,7 +58,7 @@ cd python && poetry install && pytest
5858

5959
**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.
6060

61-
**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.
61+
**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.
6262

6363
**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.
6464

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ FROM node:22-alpine
1717

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

2222
WORKDIR /workspace
2323

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ rafter secrets .
5050
```sh
5151
rafter agent init --all
5252
# → Installs all detected integrations
53-
# → Downloads Gitleaks (or falls back to built-in scanner)
53+
# → Downloads Betterleaks (or falls back to built-in scanner)
5454
```
5555

5656
**3. Try to commit—hook blocks it**
@@ -184,7 +184,7 @@ This command:
184184
- Creates `~/.rafter/` config and audit log (or `./.rafter/` with `--local` for ephemeral / containerized / benchmark setups)
185185
- Auto-detects Claude Code, Codex CLI, OpenClaw, Gemini, Cursor, Windsurf, Continue.dev, and Aider
186186
- With `--with-*` or `--all`: installs Rafter skills/extensions to opted-in agents
187-
- 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)
187+
- 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.
188188

189189
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`.
190190

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

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

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

228228
### Pre-Commit Hook
229229

@@ -524,7 +524,7 @@ Exit codes are part of Rafter's output contract — CI pipelines and orchestrato
524524
~/.rafter/
525525
├── config.json # Configuration
526526
├── audit.jsonl # Security event log (JSON lines)
527-
├── bin/gitleaks # Gitleaks binary
527+
├── bin/betterleaks # Betterleaks binary
528528
├── patterns/ # Custom patterns (reserved)
529529
└── git-hooks/ # Global pre-commit hook (if --global)
530530
```

SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ rafter agent init --with-continue # MCP server
3232
rafter agent init --with-aider # MCP server
3333
rafter agent init --with-openclaw # Skills
3434

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

3939
**What init does per platform:**

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Rafter Security — GitHub Action
22
#
3-
# Deterministic secret scanning for CI. 21+ credential patterns via Gitleaks,
3+
# Deterministic secret scanning for CI. 21+ credential patterns via Betterleaks,
44
# stable exit codes (0 = clean, 1 = findings, 2 = error), structured JSON output.
55
# No API key required. No code leaves the runner.
66
#

drafts/show-hn/faq.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ Responses written in founder voice. Adapt as needed based on the actual question
44

55
---
66

7-
## "How is this different from gitleaks / trufflehog?"
7+
## "How is this different from betterleaks (or gitleaks) / trufflehog?"
88

9-
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.
9+
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.
1010

11-
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.
11+
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.
1212

1313
---
1414

drafts/show-hn/post.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ If you use Claude Code, Codex CLI, Cursor, Gemini CLI, or similar tools, your AI
44

55
**What it does:**
66

7-
- **Secret scanning**: 21+ built-in regex patterns plus optional Gitleaks integration. Deterministic for a given version. Stable exit codes for CI.
7+
- **Secret scanning**: 21+ built-in regex patterns plus optional Betterleaks integration (the gitleaks successor). Deterministic for a given version. Stable exit codes for CI.
88
- **Command interception**: Classifies commands into risk tiers (critical/high/medium/low) and enforces approval policies before execution.
99
- **Audit logging**: JSONL trail of every command your agent runs and every secret scan result.
1010
- **MCP server**: 4 tools (`scan_secrets`, `evaluate_command`, `read_audit_log`, `get_config`) so AI agents can query security status natively.

0 commit comments

Comments
 (0)