Reference

Redaction

Configure centralized, field-aware redaction independently for local history, buckets, and export destinations in DefenseClaw observability v8.

Observability v8 performs redaction once, at the projection boundary between a canonical record and each destination. This lets one collected event be retained locally, sent to a trusted forensic backend with full content, and sent to a SOC backend with only sensitive substrings removed.

Fresh v8 configuration is intentionally full fidelity: the default profile is none, including local SQLite and capability-default remote exports. This can include prompts, outputs, tool arguments/results, evidence, paths, and identifiers. Choose a redacting profile for every destination whose trust boundary does not permit that data.

Grafana and the bundled local dashboards are consumers of the resulting canonical OTEL projection, not another redaction boundary. They do not mask, redact, or hide fields: every field present after DefenseClaw's central projection is displayed or linked to its exact raw event. If dashboard content must be reduced, configure the local destination's v8 profile upstream; do not rely on panel queries.

Review the effective plan before enabling export

An enabled destination with no send or routes receives every signal it supports, from every bucket, with profile none. Run defenseclaw observability plan and defenseclaw doctor to find unredacted legs.

Guided CLI workflow

Run the redaction command without a subcommand for the guided workflow:

defenseclaw setup redaction

It first prints the compiler-owned effective destination and bucket policy, then offers four simple choices: keep the current policy, remove redaction, apply one profile everywhere, or change the global baseline. The next prompt is Show advanced settings?. Choose it to work with:

  1. global collection and profile defaults;
  2. any of the 14 catalog buckets, selected by number, name, comma list, or all;
  3. built-in and custom profiles, detector groups, field classes, and modes;
  4. destination send policy and ordered first-match routes, including every route selector;
  5. related raw-data controls and immutable policy boundaries;
  6. a staged effective-policy review, or a reset of all staged changes.

The wizard does not write while you move between advanced screens. At the end it compiles the complete staged candidate, shows effective destination/route/bucket/ signal changes, calls out newly unredacted legs, and asks for confirmation.

macOS, Linux, and native Windows

The command surface and policy semantics are the same on macOS, Linux, and the native Windows x64 package. On macOS/Linux, run it from a POSIX shell:

defenseclaw setup redaction status
defenseclaw setup redaction remove-all --dry-run
defenseclaw setup redaction

On Windows, run the same commands in PowerShell, cmd, or the packaged TUI:

defenseclaw setup redaction status
defenseclaw setup redaction remove-all --dry-run
defenseclaw setup redaction

In the TUI, open Setup → Redaction Policy. Quick actions default mutations to dry-run. Show advanced settings exposes every scripted bucket, collection, custom-profile, destination, selector, and ordered-route action; Open the complete guided workflow runs the prompt-driven editor in Activity. The TUI streams prompts and accepts stdin on both POSIX terminals and native Windows.

In the macOS app, open Logs → Redaction policy…. The sheet provides effective status, one-click broad profiles, and a Show advanced settings disclosure for the same global defaults, 14 buckets, custom profiles, destinations, and ordered route selectors. Advanced mutations default to dry-run and show their exact CLI command before execution.

Every changed, non-dry-run mutation writes a timestamped pre-change backup. Its path begins with ~/.defenseclaw/backups/config.yaml.before-redaction on macOS/Linux and %USERPROFILE%\.defenseclaw\backups\config.yaml.before-redaction in the packaged Windows profile. Newly created parents and every backup file are owner-private (0700/0600 on POSIX; a protected current-user/SYSTEM DACL on Windows), and replacement is atomic and durable on both platform families. Existing safe parent-directory permissions are validated without being changed.

The simple remove-all command

To select profile none for every configurable log and trace projection:

defenseclaw setup redaction remove-all --dry-run
defenseclaw setup redaction remove-all --yes

This sets the global baseline to none and removes more-specific bucket, destination send, and route profile overrides. It deliberately leaves collection and routing unchanged. The generated local SQLite projection inherits none; the managed enterprise destination remains release-owned and locked to its managed profile. Existing stored or exported records are not rewritten.

The command governs observability log and trace projections. It does not disable the separate safety scrub applied to OS notifications or agent hook responses. Those attended surfaces may show exact ship-authored rule IDs and titles, but continue to hide free-form reasons and matched literals that could contain PII, credentials, or prompt-injection content.

remove-all permits raw governed content

remove-all can expose prompts, responses, tool arguments/results, evidence, paths, and identifiers to every configurable destination. Use it only when local history and every downstream sink share an approved trust boundary.

Scripted policy commands

The same policy surface is available without prompts:

# Inspect effective policy
defenseclaw setup redaction status
defenseclaw setup redaction status --json

# Broad baselines
defenseclaw setup redaction apply --scope all-configurable --profile strict --dry-run
defenseclaw setup redaction apply --scope defaults --profile sensitive --yes
defenseclaw setup redaction defaults set --profile content --no-traces --yes

# Bucket overrides
defenseclaw setup redaction bucket list
defenseclaw setup redaction bucket set model.io --profile content --no-logs --yes
defenseclaw setup redaction bucket reset model.io --yes

# Custom profiles
defenseclaw setup redaction profile set soc \
  --extends sensitive \
  --detector pii --detector credentials --detector secrets \
  --field content=detect --field evidence=detect \
  --field path=hash --field credential=remove --yes
defenseclaw setup redaction profile show soc
defenseclaw setup redaction profile remove soc --replace-with sensitive --yes

# Concise destination policy
defenseclaw setup redaction destination send splunk-production \
  --signal logs --bucket security.finding --bucket enforcement.action \
  --profile sensitive --yes
defenseclaw setup redaction destination inherit splunk-production --yes

# Ordered advanced routes
defenseclaw setup redaction route add splunk-production critical-findings \
  --position 1 --signal logs --bucket security.finding \
  --min-severity HIGH --route-action send --profile strict --yes
defenseclaw setup redaction route move splunk-production critical-findings \
  --position 2 --yes
defenseclaw setup redaction route remove splunk-production critical-findings --yes

Mutation commands accept --dry-run, --json, and --restart/--no-restart. Machine-readable mutations require either --dry-run or --yes. An omitted flag means “leave that field unchanged”; reset/inherit verbs remove the corresponding source override explicitly. JSON dry-runs report applied: false; confirmed writes emit their result only after verification and include backup_path, verified_plan_digest, and restarted.

Built-in profiles

ProfileBehaviorTypical use
nonePreserves every registered field and supplied content.Trusted local lab or tightly controlled forensic backend.
sensitiveDetects PII, credentials, and secrets inside content-like fields while retaining useful surrounding structure.Internal operations and SOC investigation.
contentRedacts whole prompt, response, tool, document, evidence, and other content bodies while preserving safe metadata/correlation.Shared production observability.
strictRemoves or transforms content, credentials, paths, reasons, evidence, and error detail aggressively.Least-data external export.
legacy-v7Immutable migration profile that reproduces the effective v7 persistent-sink projection.Automatic upgrade only.

legacy-v7 cannot be extended or redefined. It exists so automatic migration can preserve an existing installation's behavior even though fresh-v8 defaults differ.

Resolution order

For each delivered log or trace, the most specific configured profile wins:

  1. send.redaction_profile or the first matching route's redaction_profile;
  2. observability.buckets.<bucket>.redaction_profile;
  3. observability.defaults.redaction_profile;
  4. the reviewed bucket catalog default (none in catalog v1).

Metrics do not contain content fields and do not take a redaction profile.

This example keeps the fresh default for local SQLite, removes whole model content on general routes, and applies substring detection to one SOC destination:

config_version: 8
observability:
  defaults:
    redaction_profile: content
  buckets:
    compliance.activity:
      redaction_profile: sensitive
  destinations:
    - name: forensic
      kind: otlp
      protocol: grpc
      endpoint: forensic.example.com:4317
      send:
        signals: [logs, traces, metrics]
        buckets: ['*']
        redaction_profile: none
    - name: soc
      kind: splunk_hec
      endpoint: https://splunk.example.com:8088/services/collector/event
      token_env: SPLUNK_HEC_TOKEN
      send:
        signals: [logs]
        buckets: [compliance.activity, security.finding, enforcement.action]
        redaction_profile: sensitive

Because observability.defaults.redaction_profile also applies to the generated local destination, the local SQLite projection is content in this example. Omit the global default and place profiles only on remote routes if local history should remain unredacted.

Custom profiles

A custom profile extends exactly one redacting built-in profile: sensitive, content, or strict.

observability:
  redaction_profiles:
    soc:
      extends: sensitive
      detectors: [pii, credentials, secrets]
      field_classes:
        metadata: preserve
        identifier: preserve
        content: detect
        reason: detect
        evidence: detect
        error: detect
        path: hash
        credential: remove

The only operator-facing detector groups are:

GroupDetects
piiEmail addresses, phone numbers, SSNs/national identifiers, payment-card candidates, and other registered personal-data patterns.
credentialsAuthorization material, API keys/tokens, passwords, private-key material, and registered credential forms.
secretsHigh-confidence secret patterns and registered secret-bearing values not already classified as credentials.

Unknown groups fail validation. Detection is bounded and runs only on field classes whose mode resolves to detect.

Field classes and modes

Every registered telemetry field has one field class:

ClassExamples
metadatastable operation, provider, status, and policy metadata
identifiertrace, span, agent, session, evaluation, and asset identifiers
contentprompts, completions, tool arguments/results, retrieved documents
reasonverdict explanation, policy or operator reason
evidencematched snippets and derived evidence summaries
errorbounded exception and failure detail
pathfile, workspace, repository, or executable paths
credentialtokens, keys, authorization material, and secret values

Profiles assign one of these modes:

ModeResult
preserveRetain the bounded value unchanged.
detectReplace only detector matches; retain nonsensitive surrounding text.
wholeReplace the entire value with a typed redaction marker.
hashNormalize by the field-class contract and emit a keyed, nonreversible correlation token.
removeOmit the field from that destination projection.

The hash token is designed for same-install correlation, not disclosure or cross-install identity. It uses DefenseClaw-managed key material derived under the data directory. Neither the digest algorithm, key path, scan limits, nor marker format is an operator knob.

What field-aware redaction looks like

Given a model input:

Send the report to alice@example.com using token sk-live-example.

the possible projections are conceptually:

Mode/profileProjected value
noneOriginal sentence.
detect with pii,credentialsSentence retained, email and token replaced by typed correlation markers.
wholeOne marker representing the complete field; no sentence fragments retained.
removeField absent.

The exact marker and correlation token formats are generated protocol contracts; consumers should treat them as opaque strings and use the companion content-state fields when present.

Credential-bearing URL queries

URL detectors normalize query-key case and bounded percent-encoding before classifying the associated value. Partially encoded keys such as tok%65n and api%5Fkey therefore receive the same protection as token and api_key. Duplicate parameters are handled independently, while safe parameters, paths, hosts, and fragments remain available for diagnostics.

Malformed or excessively encoded query keys are never treated as proof that the value is safe. Diagnostic URL scrubbers replace the entire ambiguous query item with a redacted placeholder, or replace an unparseable URL with a safe placeholder. These transformations apply only to logs, telemetry, and audit projections; they do not rewrite an upstream request.

Multiple destinations

Redaction is resolved independently for each matching destination. It never mutates the canonical record or another destination's copy:

canonical security.finding log
  +-> local SQLite     profile none       full registered projection
  +-> Splunk HEC      profile sensitive  only sensitive substrings replaced
  +-> archive OTLP    profile content    whole governed content removed

A route may explicitly use redaction_profile: none. It needs no break-glass flag, but the effective plan always displays it as none / unredacted instead of hiding it behind “default.”

Fail-closed behavior

If a field map is valid but detection, key use, scalar transformation, or a field limit fails, the projector replaces the complete affected field with a bounded failed_closed token, continues other fields, and emits value-free health accounting. It never preserves a scanned prefix or suffix around an unsafe middle.

If classification is missing/ambiguous, container traversal is unsafe, the trusted projection context mismatches, or the complete projected record cannot be bounded and serialized, that destination receives no projection. Other destinations continue independently. Mandatory SQLite attempts a minimal content-safe failure record. The failure report never includes the rejected value, destination secret, endpoint, path, or exception text.

The selected none profile intentionally preserves registered values and does not run detectors, but schema, type, size, and serialization limits still apply. No profile or error path falls back from a configured redacting profile to raw output.

Local mandatory records are minimal and content-safe by construction. Disabling normal log collection cannot disable this SQLite-only compliance floor.

V7 compatibility (upgrades only)

The v7 privacy block's disable_redaction field and DEFENSECLAW_DISABLE_REDACTION are v7 controls. They are not v8 runtime policy knobs. During defenseclaw upgrade, the converter materializes their effective behavior into none or legacy-v7 profiles before retiring those inputs. A v8 gateway rejects legacy observability/redaction blocks with an actionable upgrade message.

DEFENSECLAW_REVEAL_PII remains an operator-display concern where supported; it does not alter the v8 destination route graph or a persistent-sink projection.

Write and activation safety

The CLI is the preferred redaction editor. Each mutation runs the strict Python source validator and the canonical Go compiler before writing. For a changed, non-dry-run write, it compares the live file with the preview digest, installs a private backup, atomically replaces config.yaml, verifies the installed effective-plan digest, and records a setup-redaction-policy audit action. The backup path is unique for each write:

<data-dir>/backups/config.yaml.before-redaction-<nanosecond-timestamp>

Comments and unrelated source formatting are retained outside the exact policy span being edited. --restart restarts the gateway after verification; without it, the gateway uses its configured hot-reload behavior.

When --no-restart explicitly stages a change while the gateway is unavailable, the CLI still verifies the installed effective-plan digest but warns on stderr that the canonical setup audit event could not be recorded. Start the gateway before the next policy change when canonical audit admission is required. JSON mutation output remains machine-readable on stdout.

For manual changes outside the CLI-owned redaction surface, edit only ~/.defenseclaw/config.yaml and stop before restart if validation fails:

umask 077
cp "$HOME/.defenseclaw/config.yaml" \
  "$HOME/.defenseclaw/config.yaml.before-redaction-edit"

defenseclaw config validate && \
defenseclaw config show --effective --section observability && \
defenseclaw observability plan && \
defenseclaw-gateway restart && \
defenseclaw doctor

Do not edit the generated reference or a compiled/effective view. Restore the backup or correct the source when validation fails. A global or bucket profile also affects local SQLite; use destination send or a route profile when only that remote trust boundary should be redacted.

Verify policy

defenseclaw config validate
defenseclaw config show --effective --section observability
defenseclaw observability plan
defenseclaw doctor

The source view shows deliberate choices. The effective/plan views show generated local SQLite policy, capability-default routes, resolved profiles, and warnings. Endpoints and secret references are masked; resolved secrets and governed content must not appear in plan, doctor, TUI, or migration output.

See also