Skip to content

theMariusK/redacto

Repository files navigation

redacto

FUSE-based cross-platform file redaction tool. Mounts a virtual filesystem overlay that mirrors a real project directory, redacting secrets on read and rehydrating them on write.

Requirements

  • Go 1.22+
  • Linux: libfuse3-dev (or fuse3 package)
  • macOS: macFUSE or FUSE-T

Build

make

Usage

Exec mode (recommended for AI agents)

# Mount, launch agent inside mount, unmount on exit
redacto /home/user/project -- gemini

# Source dir defaults to current directory if omitted
redacto -- gemini

# With explicit config
redacto --config /path/to/redact.yaml /home/user/project -- claude-code

The child process runs with its working directory set to the mount point. All file reads return redacted content; writes are rehydrated back to originals.

When using redacto with AI agents that support session resume (e.g. gemini --resume), two flags are important:

--mount-dir (required for resume)

By default redacto creates a temporary mount directory like /tmp/redacto-abc123. The agent's working directory is set to this mount point. On restart, a new temp dir is created, so the agent cannot find its previous session — most agents identify sessions by the directory they were started in.

Use --mount-dir to set a stable mount point:

redacto --mount-dir ~/redacto-mount -- gemini --resume

This ensures the agent always starts in the same directory and can locate previous sessions.

--mappings-file (needed for regex rules)

Whether you need --mappings-file depends on which rule types you use:

  • Literal rules only--mappings-file is not needed. The original/placeholder pairs are defined in your config, so rehydration works without any persisted state.
  • Regex rules--mappings-file is needed. Regex matches are discovered at runtime and the placeholder-to-original mappings are stored in memory. Without persistence, a restarted redacto cannot rehydrate placeholders from the previous session — the agent writes a hex placeholder to disk instead of the original secret, corrupting the file.

Recommended setup for session resume

redacto \
  --mount-dir ~/redacto-mount \
  --mappings-file ~/.redacto-mappings.json \
  -- gemini --resume

On shutdown, mappings are saved to the file. On startup, they are loaded back, giving full session continuity.

Mount-only mode

# Mount and wait for Ctrl+C
redacto /home/user/project /mnt/redacted

# Source dir defaults to current directory
redacto /mnt/redacted

# With auto temp mount dir
redacto --mount-dir /tmp/mymount /home/user/project

Flags

Flag Description Default
--config PATH Config YAML path ~/.redacto.yaml
--mount-dir PATH Explicit mount point auto temp dir
--no-rehydrate-writes Disable write rehydration false
--mappings-file PATH Persist regex mappings to this file for cross-session rehydration (none, opt-in)
--debug FUSE debug logging false

Config Format

Default config lives at ~/.redacto.yaml:

rules:
  # Literal rules — exact string match
  - original: "sk-ant-api03-realkey1234567890abcdef"
    placeholder: "sk-ant-api03-XXXXXXXXXXXXXXXXXXXXXXX"
  - original: "password1234"
    placeholder: "************"
  - original: "SecretCorp"
    # placeholder auto-generated (SHA-256 hex, same length)

  # Regex rules — match by pattern, placeholder auto-generated per match
  - pattern: "ghp_[A-Za-z0-9]{36}"            # GitHub personal access tokens
  - pattern: "sk-ant-api03-[A-Za-z0-9]{24}"   # Anthropic API keys
  - pattern: "AKIA[0-9A-Z]{16}"               # AWS access key IDs
  - pattern: "[A-Fa-f0-9]{40}"                # 40-char hex strings (SHA-1, tokens)

env_rules:
  - name: "ANTHROPIC_API_KEY"
    placeholder: "REDACTED"

# Commands that bypass redaction (see originals)
passthrough_commands:
  - terraform
  - kubectl

# Optional: additional extensions/paths to skip
skip_extensions: [".bin", ".dat"]
skip_paths: [".cache", "build"]

Rule types

Each rule must have exactly one of original or pattern.

Literal rules (original):

  • Exact string match
  • placeholder is optional — if omitted, a deterministic same-length hex string is auto-generated
  • If specified, original and placeholder must be the same byte length

Regex rules (pattern):

  • Uses Go regex syntax
  • placeholder is ignored — a deterministic same-length placeholder is auto-generated per match
  • Matched text is stored for rehydration (mappings accumulate for the scanner's lifetime)
  • Use --mappings-file to persist these mappings across restarts, so placeholders from a previous session can still be rehydrated

Passthrough commands

Infrastructure tools like terraform, kubectl, or aws need to see real credentials to function. The passthrough_commands config option lets you list command names that should bypass redaction:

passthrough_commands:
  - terraform
  - kubectl
  - aws
  - helm
  - gcloud

When a process whose name (or any ancestor's name) matches this list reads a file through the FUSE mount, it receives the original unredacted content. The AI agent and its tools still see redacted placeholders.

This works by inspecting the caller PID on each FUSE open() call and walking the process tree to check command names. The decision is made once at file open time and cached per PID, so there is no per-read overhead.

Works on both Linux (/proc-based) and macOS (sysctl-based).

How It Works

AI Agent (works in /mnt/redacted)          terraform, kubectl, etc.
            |                                        |
    reads/writes files                       reads/writes files
            |                                        |
            +------------ Kernel VFS (FUSE) ---------+
                                |
                    redacto daemon (Go, userspace)
                    checks caller PID on open()
                           /            \
               AI agent PID:         passthrough PID:
               Read: redact          Read: raw passthrough
               Write: rehydrate     Write: raw passthrough
                           \            /
                    Real Filesystem (/home/user/project)
  • direct_io is enabled to bypass the kernel page cache, ensuring every read/write passes through the redaction handlers
  • Binary files are skipped (by extension and null-byte detection)
  • .git, node_modules, and vendor directories are skipped by default

About

FUSE-based cross-platform file redaction tool. Mounts a virtual filesystem overlay that mirrors a real project directory, redacting secrets on read and rewriting them back on write.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors