Skip to content

Repository files navigation

DECON

DECON banner

Sanitize engagement data without destroying its analytical value.

Python 3.11+ Zero runtime dependencies License MIT

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.

Quick start

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 --doctor
decon --diff scan.txt                   # inspect
decon -o scan.redacted.txt scan.txt     # write file
decon -c scan.txt                       # copy to clipboard

Operator workflow

TACMUX 2.5 export boundary

From 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.

1. Declare the engagement

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.

2. Inspect deterministic redaction

decon --profile pentest \
  --targets ~/engagements/acme.targets \
  --diff notes.md

The 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.

3. Require local Ollama review

# ~/.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.md

uncertain 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.

4. Confirm and ask

decon --strict-llm \
  --targets ~/engagements/acme.targets \
  --provider codex \
  --ask "Prioritize the attack paths and recommend the next three checks." \
  --confirm-ask notes.md

DECON 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.

Command cheat sheet

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.

Manual round trip

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 -c

Sessions and exported maps contain the original values. They are owner-only plaintext files, not encrypted vaults.

Configuration

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.

Trust model

  1. Deterministic core redacts credentials, infrastructure, configured targets, and unambiguous identifiers locally.
  2. Optional local model classifies ambiguous PII and reviews the result. It never rewrites the document or controls placeholder mappings.
  3. Outbound gate blocks remote --ask calls when an independent scanner still finds high-confidence credential material.
  4. 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.

Documentation

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.

Development

python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
pytest -q && ruff check src tests

License

MIT — see LICENSE.

About

Sanitize sensitive operational data with stable placeholders before it crosses reporting, sharing, or AI boundaries.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages