Sanitize engagement data without destroying its analytical value.
Operator guide · Quick start · Operator workflow · Commands · Trust model · Documentation
DECON is a local-first sanitization layer for pentest, red-team, and CTF output. It replaces sensitive values with stable, typed placeholders before the data is sent to an LLM, pasted into a ticket, added to a report, or shared with a teammate.
10.42.0.15 cannot reach 10.42.0.1. Retrying 10.42.0.15...
[IPV4_REDACTED_0001] cannot reach [IPV4_REDACTED_0002]. Retrying [IPV4_REDACTED_0001]...
Repeated values retain the same placeholder, preserving topology and attack paths without exposing the originals.
Important
DECON reduces disclosure risk; it cannot prove that arbitrary text is safe. Preview sensitive material before it crosses an engagement trust boundary.
DECON requires Python 3.11+ and has no runtime dependencies.
git clone https://github.com/BLTSEC/DECON.git
cd DECON
uv tool install . # or: pipx install .
decon --init-config
decon --doctordecon --diff scan.txt # inspect
decon -o scan.redacted.txt scan.txt # write file
decon -c scan.txt # copy to clipboardFrom a TACMUX target or operations session, export the current engagement and sanitize a separate copy before reporting, sharing, or remote AI use:
handoff="$(tacmux export handoff)"
decon --profile pentest --diff "$handoff"
decon --profile pentest -o "${handoff%.md}.redacted.md" "$handoff"The TACMUX handoff is a private, unredacted point-in-time export—not a verified archive and not safe to share by default. DECON reduces disclosure risk, but its redacted output still requires operator review before it crosses a trust boundary. Keep the original export and any DECON mapping/session files on protected local storage.
Generic rules cannot infer client codenames or naming conventions. Keep a target file outside the repository:
# ~/engagements/acme.targets
domain:corp.acme.com
netbios:ACME
hostname:DC01
username:svc_backup
share:HR-Data
Add arbitrary names and labels under [custom].values_nocase in the config.
decon --profile pentest \
--targets ~/engagements/acme.targets \
--diff notes.mdThe built-in pentest profile adds standalone NT-hash detection. It is opt-in
because a bare 32-character hexadecimal value may be an MD5 checksum.
# ~/.config/decon/decon.toml
[llm]
model = "qwen3.5:9b"
host = "http://localhost:11434"# Credentials and declared targets remain deterministic. Ollama classifies
# ambiguous PII and reviews the sanitized result for missed identifiers.
decon --strict-llm \
--profile pentest \
--targets ~/engagements/acme.targets \
notes.mduncertain means redact. Strict mode emits nothing if classification or final
review fails. Raw candidate context stays on loopback unless
llm.allow_remote = true is explicitly configured.
decon --strict-llm \
--targets ~/engagements/acme.targets \
--provider codex \
--ask "Prioritize the attack paths and recommend the next three checks." \
--confirm-ask notes.mdDECON sanitizes once, displays the exact outbound user prompt and its SHA-256
digest, then sends those same in-memory bytes only after confirmation. It
restores known placeholders in the answer. Use --provider ollama to keep both
review and analysis local.
Use --ask-preview for a no-authentication, no-transmission dry run. Local LLM
decisions are probabilistic, so its output is exact for that invocation but is
not a guarantee that a separate run will produce identical bytes.
| Provider | Boundary | Authentication |
|---|---|---|
ollama |
Local | None |
codex |
Remote via Codex CLI | ChatGPT subscription (codex login) |
claude-code |
Remote via Claude Code | Claude subscription (claude auth login) |
openai |
Remote API | OPENAI_API_KEY + openai SDK |
claude |
Remote API | ANTHROPIC_API_KEY + anthropic SDK |
CLI providers use an isolated, non-persistent run by default. See LLM workflows before enabling a remote provider.
| Goal | Command |
|---|---|
| stdin → stdout | cat scan.txt | decon |
| Show substitutions | decon --dry-run scan.txt |
| Review a unified diff | decon --diff scan.txt |
| Copy sanitized output | decon -c scan.txt |
| Sanitize active tmux pane | decon --tmux -c |
| Sanitize TACMUX handoff | handoff="$(tacmux export handoff)"; decon --profile pentest -o "${handoff%.md}.redacted.md" "$handoff" |
| Sanitize clipboard input | decon --clipboard-in -o clean.txt |
| Add literal values | decon --redact "codename,jsmith" notes.md |
| Preserve safe values | decon --allow "scanme.nmap.org" scan.txt |
| Process a directory tree | decon reports/**/*.txt --output-dir clean/ |
| Confirm exact prompt, then send | decon --ask "..." --confirm-ask notes.md |
| Preview without sending | decon --ask "..." --ask-preview notes.md |
| CI/pre-commit check | decon --check report.md |
| Inspect rules | decon --list-rules |
| Validate setup | decon --doctor |
Batch files retain relative paths and share one mapping. Conservative PII and leak decisions are applied across the batch before any output is written.
Use a short-lived session when manually sharing sanitized content:
decon --session acme --session-ttl 24h -c notes.md
# Paste the response back, then restore and delete the session
decon --restore acme --consume -cSessions and exported maps contain the original values. They are owner-only plaintext files, not encrypted vaults.
decon --init-config creates ~/.config/decon/decon.toml with owner-only
permissions. A practical engagement layer looks like this:
[custom]
target_domains = ["corp.example"]
values_nocase = ["Project Nighthawk"]
allowlist = ["scanme.nmap.org"]
[audit]
enabled = true
detail = "metadata"CLI flags override configuration. Run decon --doctor after changing models,
providers, permissions, or authentication. Use decon --list-rules for the
authoritative detector list.
- Deterministic core redacts credentials, infrastructure, configured targets, and unambiguous identifiers locally.
- Optional local model classifies ambiguous PII and reviews the result. It never rewrites the document or controls placeholder mappings.
- Outbound gate blocks remote
--askcalls when an independent scanner still finds high-confidence credential material. - Provider boundary receives only the sanitized prompt, but remains an external trust boundary.
Caution
--force-ask bypasses an outbound credential block. Use it only after
inspecting the prepared prompt and confirming a false positive. It cannot
bypass a failed --strict-llm review.
Audit records are metadata-only by default. Maps, sessions, and full-detail audit logs may contain original values; never commit or share them.
| Guide | Contents |
|---|---|
| Configuration | Rules, profiles, custom patterns, typed targets |
| Mappings and sessions | Restore, TTLs, audit history |
| LLM workflows | Ollama, strict review, prompt preview, providers |
| Python library | sanitize, desanitize, ask_safely |
| Integrations | Pre-commit and NOCAP |
Run decon --help for the complete CLI reference.
python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
pytest -q && ruff check src testsMIT — see LICENSE.
