DOCUMENTATION
Get Redactifire running.
Redactifire is one Docker container. Nothing to license, nothing to phone home — point it at your logs and your LDAP, and you're sanitizing real data in minutes.
Quick start
The fastest path is Docker Compose. This starts the web UI and API on port 8000 and persists all data (jobs, policies, the Decoder Ring) in a named volume.
docker compose up -d
There's no default admin account — create one after first boot:
docker compose exec redactifire redactifire create-admin --username admin
Omit --password to be prompted interactively rather than passing it on
the command line, so it never lands in shell history. Then open
http://localhost:8000 and log in.
Prefer a local install without Docker:
pip install -e .
redactifire sanitize --input /path/to/logs --output /path/to/sanitized --policy config/policies/default.yaml
redactifire create-admin --username admin
Authentication
The web UI always requires a login. Local accounts work out of the box via
redactifire create-admin — re-running it for an existing username resets
their password, so it doubles as an "I forgot the admin password" recovery path.
LDAP/Active Directory bind auth with group-based access is also built in today, with OIDC support planned next. Local accounts remain supported regardless of which other backends are enabled.
Redaction modes
Every entity type is assigned one of these modes, either globally in a policy or
per-value as an override. Structure-preserving modes (Mask and its
keep variants) hide the value while still letting a support agent see
whether two log lines refer to the same underlying thing — Pseudonymize
replaces it with a consistent fake value instead, and Suppress removes
it entirely.
| Mode | Behavior | Example |
|---|---|---|
suppress | Replace entirely, no structure kept. | 118-42-9013 → [REDACTED] |
mask | Every group/label replaced with a same-length, same-shape placeholder. | 192.168.1.45 → xxx.xxx.xxx.xxx |
mask_keep_1 / _2 / _3 | Leftmost N octets/hextets/labels left visible (IPv4, IPv6, hostname). | 192.168.1.45 → xxx.xxx.xxx.45 |
mask_keep_last_4 | Last 4 digits visible; used for SSN, phone, credit card. | 118-42-9013 → xxx-xx-9013 |
mask_keep_area_code | Phone-specific: area code visible, rest masked. | (555) 234-1187 → (555) xxx-xxxx |
pseudonymize | Deterministic fake replacement — the same input always produces the same output, across every file in a job. | jdoe@corp.com → user1@example1.com |
Supported entity types
Built in today: email, ipv4, ipv6,
phone, username, userid, group,
hostname, sid, ssn, credit_card,
api_key, and url. username/userid/
group can be sourced live from LDAP so real directory identities are
recognized even when they never match a regex on their own.
Policy configuration
All masking behavior is YAML-driven and snapshotted per job for auditability. A policy sets the mode per entity type, plus optional allow/deny lists:
entities:
email:
mode: pseudonymize
allow_list:
- "noreply@example.com"
deny_list:
- "*@internal.corp.com"
ipv4:
mode: mask_keep_1
allow_list:
- "127.0.0.1"
ssn:
mode: suppress
hostname:
mode: mask
allow_list:
- "localhost"
To use your own policy instead of the bundled default in Docker, mount it and point
REDACTIFIRE_CONFIG_PATH at it — see the commented example in
docker-compose.yml.
LDAP integration
Point Redactifire at your directory to recognize real usernames and groups:
ldap:
enabled: true
server_uri: "ldap://your-dc.corp.com:389"
bind_dn: "cn=redactifire-svc,dc=corp,dc=com"
bind_password: "..."
base_dn: "dc=corp,dc=com"
user_id_attribute: "uid" # or "cn"
search_filter: "(objectClass=person)"
use_tls: false
For air-gapped or standalone environments without live LDAP access, set
user_list_file to a plain text file of one user ID per line instead.
Decoder Ring & audit trail
Every redaction is recorded in the Decoder Ring — a local, auditable table mapping each original value to its replacement, per job. It's sensitive by nature, so it's stored separately from sanitized output and never transmitted anywhere; that's the point of running this on your own hardware. Every job also keeps its original text and sanitized output, so you can prove exactly what was masked, long after the fact.
FAQ
Does anything leave my network? No — Redactifire is zero-outbound and air-gap capable. There's no telemetry, and nothing about your logs, policies, or mappings is ever sent anywhere by Redactifire itself.
Will the same value always redact the same way? Yes, within a job — the Global Identity Map (GIM) guarantees any entity replaced in one file gets the identical replacement in every other file in that job.
Can I exempt one specific value from an otherwise type-wide rule? Yes — allow-list a specific value (e.g. one email address a vendor needs to see) independent of the mode set for the rest of that entity type.