🏗️ fermata: redaction-first security model, unified .botsecrets config

Realign fermata around redaction (PostToolUse) as the primary security
layer, with access control (PreToolUse) as supplementary write/bash
protection. Remove botignore.toml — policy rules now live in .botsecrets
[policy] section. Add fermata.toml as an alias for .botsecrets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 01:10:07 +02:00
parent 77520819f6
commit 168aefd415
17 changed files with 571 additions and 423 deletions
+24 -6
View File
@@ -6,7 +6,7 @@ Fermata is a policy gate and secret filtering engine for AI coding agents. It sh
## fermata check
Check whether one or more paths are allowed for a given operation. Fermata locates the nearest project root (a directory containing `.botignore`, `botignore.toml`, or `.git`) and evaluates the policy defined there.
Check whether one or more paths are allowed for a given operation. Fermata locates the nearest project root (a directory containing `.botsecrets`, `.botignore`, or `.git`) and evaluates the policy defined there.
**Usage**
@@ -79,7 +79,7 @@ Fermata follows a **fail-open** policy for hooks: if the payload cannot be parse
**Event types**
- **pre-tool-use** -- Runs before the tool executes. Fermata checks the requested path or command against `.botignore` / `botignore.toml` and returns an allow, deny, or ask decision to the harness.
- **pre-tool-use** -- Runs before the tool executes. Fermata checks the requested path or command against `.botsecrets [policy]` / `.botignore` and returns an allow, deny, or ask decision to the harness.
- **post-tool-use** -- Runs after the tool executes. Fermata loads `.botsecrets`, builds a manifest of known secret values, and redacts any matches from the tool output before it enters the LLM context. A heuristic scanner (regex patterns derived from gitleaks) catches undeclared secrets as a safety net.
**Examples**
@@ -102,9 +102,8 @@ Fermata does not have its own global config file. All configuration lives in you
| File | Purpose |
|------|---------|
| `.botsecrets` | TOML file for secret redaction (`[files]`, `[heuristic]`, `[keys]`) **and** access-control policy (`[policy]` section with `[policy.read]`, `[policy.write]`, `[policy.bash]`). Unified config for most projects. `fermata.toml` is accepted as an alias (same format, `.botsecrets` takes priority). |
| `.botignore` | Gitignore-syntax patterns. Blocks both reads and writes to matched paths. |
| `botignore.toml` | Per-operation rules with `[read]`, `[write]`, and `[bash]` sections. |
| `.botsecrets` | TOML file declaring which files contain secrets, custom key patterns, and heuristic scanning options. |
Fermata discovers these files by walking up from the target path (or the current working directory for `hook`) until it finds a project root.
@@ -135,6 +134,25 @@ enabled = true
The `.botignore` blocks direct reads. The `.botsecrets` catches secrets that leak through indirect paths (shell output, log files, error messages).
### Single-file setup with .botsecrets
You can consolidate both secret redaction and access policy into `.botsecrets` alone, replacing the need for a separate `.botignore`:
```toml
# .botsecrets
[files]
patterns = [".env", ".env.*"]
[heuristic]
enabled = true
[policy.read]
deny = [".env", ".env.*", "secrets/**", "credentials/**"]
[policy.bash]
deny = ["rm -rf /", "curl * | sh"]
```
### Wire fermata into Claude Code
Add both hook events to `.claude/settings.json`:
@@ -164,10 +182,10 @@ Add both hook events to `.claude/settings.json`:
### Block dangerous shell commands
Use `botignore.toml` to deny specific command patterns:
Use `.botsecrets [policy.bash]` to deny specific command patterns:
```toml
[bash]
[policy.bash]
deny = ["rm -rf /", "curl * | sh", "wget * | bash"]
```