Skip to navigation

PII Redaction Configuration

View as Markdown

Configure kind = "pii_redaction" in plugins.toml. Use the reference tables to look up settings, then use the worked examples to compare input event data with the published result. For runtime placement and the middleware comparison, refer to About. For selection and preservation rules, refer to Redaction Behavior.

There are two supported configuration forms:

  • Profiles: Define one or more policies under [[components.config.profiles]]. Every enabled profile covers all supported surfaces.
  • Single policy: Omit profiles and define a policy directly under [components.config]. This form also provides surface flags.

Configuration Reference

All configuration keys use snake_case in plugins.toml and every binding. A field shown as Unset has no configured value.

Component Shape

The plugin document has root version = 1. Each [[components]] entry uses:

SettingTypeDefaultDescription
kindStringRequiredSet to pii_redaction.
enabledBooleantrueEnable or disable the whole component.

The following shared fields belong under [components.config] in either form:

SettingTypeDefaultDescription
versionInteger1PII redaction configuration schema version.
codecStringUnsetOptional fallback API format for LLM calls that do not supply an active codec. For example, use codec = "anthropic_messages" for Anthropic Messages payloads. Omit this field when your integration supplies a codec; the call’s active codec takes precedence.
profilesArray of objectsUnsetOrdered policies. Omit to use the single-policy form.
policyObjectSee detailsHandling of unknown components, unknown fields, and unsupported values.

How to choose a codec

Choose the value by the API payload format:

LLM API Formatcodec Value
OpenAI Chat Completionsopenai_chat
OpenAI Responsesopenai_responses
Anthropic Messagesanthropic_messages
OCI Generative AIoci_genai
Gemini GenerateContentgemini_generate_content

Omit codec when the managed call supplies an active codec. A configured value is only a fallback for a call without one; it cannot override an active codec. Request policies use the active codec’s resolved decode/encode capability, including runtime and opaque codecs. Normalized response projection requires a recognized built-in codec because response codec capabilities are decode-only.

For a mixed-provider gateway, rely on the active codec of each call. The LLM request-only example shows the selector boundary for an OpenAI Chat Completions request.

Configuration validation policy

Set these fields under [components.config.policy] to control configuration diagnostics. Each accepts ignore, warn, or error.

FieldDefaultMeaning
unknown_componentwarnHandling of an unknown component kind.
unknown_fieldwarnHandling of an unknown field on a known component.
unsupported_valueerrorHandling of an unsupported value on a known field.

The global plugin policy can also affect the resolved policy. Refer to Configure for precedence.

Profile Settings

These fields belong under each [[components.config.profiles]] entry:

SettingTypeDefaultDescription
enabledBooleantrueEnable or disable this entire policy.
modeStringbuiltinBackend: builtin or local_model.
priorityInteger100Execution order; lower values run first.
builtinObjectUnsetRequired for mode = "builtin". See Built-in Settings.
localObjectUnsetProvider-specific settings for local_model mode; requires a runtime-installed provider.

At least one profile must be enabled. Use either profiles or the single-policy settings; do not combine the two forms.

How profiles compose and execute

Profiles execute by ascending priority, with array order breaking ties. Relay assigns internal positional names such as profile_0; no user-supplied ID is required. Disabled profiles are still validated, but do not register callbacks. At least one profile must be enabled.

Each enabled profile covers all supported sanitization surfaces. Profiles do not accept input, output, mark, tool_input, or tool_output flags. Use the single-policy form when you need those controls.

Profile lists concatenate during configuration layering, with higher-precedence profiles placed before lower-precedence profiles. Refer to Configure for file discovery and merge rules.

Built-in Settings

Use [components.config.profiles.builtin] for a profile, or [components.config.builtin] for a single policy. The shipped builtin backend implements deterministic actions and detector presets.

SettingTypeDefaultDescription
presetStringUnsetSet to trajectory_context for broad conversational-content removal while retaining supported analytics.
actionStringremoveremove, redact, regex_replace, hash (SHA-256), or mask. Choose an action explicitly, or use preset.
target_pathsArray of strings[]Exact RFC 6901 pointers. Combined with target_path_globs.
target_path_globsArray of strings[]Pointer globs; each whole * segment matches one key or index. Recursive ** is unsupported.
patternStringUnsetRegex matcher. Use either pattern or detector, never both.
detectorStringUnsetBuilt-in matcher such as email or api_key. See Detector Presets.
replacementString[REDACTED]Replacement for redact, regex_replace, and trajectory_context.
mask_charString*Masking token for mask. Must not be empty.
unmasked_prefixNonnegative integer0 or detector defaultLeading characters preserved by mask.
unmasked_suffixNonnegative integer0 or detector defaultTrailing characters preserved by mask.
custom_mark_payload_policyStringredact_all_leavesTrajectory preset only. preserve retains unknown custom marks from trusted producers.
metric_string_attribute_allowlistMap of string arrays{}Trajectory preset only. Exact attribute names and bounded string values that typed metric marks may retain.

remove requires at least one selector. redact and regex_replace require pattern or detector. For string actions, omitting both selector lists selects every string leaf within each payload boundary. Selecting a container with a string action does not select its descendant strings.

trajectory_context defines its own policy. Do not combine it with action, pattern, detector, target selectors, or masking fields. It accepts replacement, custom_mark_payload_policy, and metric_string_attribute_allowlist.

Single-Policy Settings

When profiles is omitted, set these fields directly under [components.config]:

SettingTypeDefaultDescription
modeStringbuiltinBackend: builtin or local_model.
priorityInteger100Sanitizer priority; lower values run first.
builtinObjectUnsetRequired for builtin mode.
localObjectUnsetProvider-specific settings for local_model mode.
inputBooleantrueManaged LLM request sanitization and scope-start processing.
outputBooleantrueManaged LLM response sanitization and scope-end processing.
markBooleantrueMark data, category_profile, and metadata sanitization.
tool_inputBooleantrueTool-request observability sanitization and scope-start processing.
tool_outputBooleantrueTool result and result annotation sanitization and scope-end processing.

At least one surface flag must be enabled. These fields cannot be combined with profiles; profile entries do not accept surface flags.

Jump to Worked Examples

How surface flags apply to scope events

Scope-start processing is enabled when either input or tool_input is true; scope-end processing is enabled when either output or tool_output is true. On LLM and tool events, metadata follows the corresponding LLM or tool flag. Other scope categories use the enabled shared scope-start or scope-end hook.

Local Backend Fields

Use [components.config.profiles.local] or [components.config.local]:

SettingTypeDefaultDescription
backendStringUnsetBackend identifier resolved by the runtime’s provider.
model_idStringUnsetModel identifier reserved for local-model runtimes.
detector_profileStringUnsetDetector profile reserved for local-model runtimes.
allow_networkBooleanUnsetNetwork access setting for a runtime-provided backend.
max_latency_msNonnegative integerUnsetTarget latency budget in milliseconds.

Refer to Available Backends for runtime availability and the current local-model implementation status.

Detector Presets

Supported detectors

The built-in detector presets are grouped into three deterministic families:

Common PII

  • email
  • phone
  • ip_address
  • ipv6
  • url

Structured Secrets

  • api_key
  • uuid
  • bearer_token
  • jwt
  • credit_card

Cloud Credentials

  • aws_access_key_id
  • aws_secret_access_key
  • gcp_api_key
  • azure_storage_account_key

They are deterministic regex-backed helpers, not model inference.

Refer to Detector Matching for matching behavior and detector limitations.

CLI Editor Support

Setup and interactive editing

The CLI and primary language bindings register the component. Direct Rust applications must call nemo_relay_pii_redaction::component::register_pii_redaction_component() before validating or initializing a pii_redaction component.

For file discovery, precedence, merge behavior, and gateway conflict rules, refer to Configure.

The NeMo Relay CLI plugin editor exposes pii_redaction directly through nemo-relay plugins edit.

Use the editor when you want to:

  • Toggle the component on or off
  • Choose builtin or local_model
  • Add and order multiple redaction profiles
  • Enable or disable individual profiles
  • Set the LLM codec
  • Edit builtin action settings such as action, target_paths, target_path_globs, pattern, detector, replacement, and masking fields
  • Edit local.backend for a runtime-provided future local-model backend

The editor preserves unknown fields when it rewrites an existing pii_redaction component, so future or runtime-specific settings are not discarded by the interactive edit flow.

If your policy needs callback code instead of editor or configuration fields, use raw middleware.

Redaction Behavior

The Redaction Behavior page explains how a valid configuration selects, transforms, and preserves observability data:

TopicRead More
Actions and detector matchingAction Semantics and Detector Matching
Codec and event payload boundariesObservability Semantics
Exact paths, globs, and selected containersPath Semantics
Broad trajectory-content removalTrajectory Context Preset
Typed measurements and allowed dimensionsTyped Metric Marks
Interpreting match diagnosticsSelection Accounting

For backend availability, refer to Available Backends.

Worked Examples

Each tab contains a complete plugins.toml document and synthetic event data. Published payload means the value delivered to subscribers and exporters; real provider requests, tool arguments, and application results retain their execution values. Tool results and result annotations are separate payloads.

Common Actions

Replace detected email addresses while preserving surrounding text.

Configuration

version = 1
[[components]]
kind = "pii_redaction"
enabled = true
[[components.config.profiles]]
mode = "builtin"
[components.config.profiles.builtin]
action = "redact"
detector = "email"

Input event payload: tool arguments

{
"contact": "Email alice@example.com",
"attempt": 2
}

Published payload

{
"contact": "Email [REDACTED]",
"attempt": 2
}

No selectors are needed: the detector inspects every string leaf. Numeric values remain unchanged.

Targeting and Composition

Select string leaves inside content-parts arrays.

Configuration

version = 1
[[components]]
kind = "pii_redaction"
enabled = true
[[components.config.profiles]]
mode = "builtin"
[components.config.profiles.builtin]
action = "redact"
detector = "email"
target_path_globs = ["/messages/*/content/*/text"]

Input event payload: tool arguments

{
"messages": [
{
"content": [
{
"type": "text",
"text": "alice@example.com"
},
{
"type": "text",
"text": "Hello"
}
]
}
]
}

Published payload

{
"messages": [
{
"content": [
{
"type": "text",
"text": "[REDACTED]"
},
{
"type": "text",
"text": "Hello"
}
]
}
]
}

This example is a JSON-native tool payload whose keys happen to be messages and content. Each * matches one array index. Selecting only /messages/0/content would select an array and leave the email unchanged. Putting * in target_paths would match literal keys instead of array indices. Refer to Path Semantics for the matching contract.

Verify the Policy

Valid selector syntax does not guarantee that the policy changes a payload. Enable runtime diagnostics at startup and inspect pii_redaction.selector_evaluated observations for the JSON documents the built-in sanitizer processes. Recording is best effort and depends on diagnostic admission and retention.

DetailMeaning
matched_pathsSelected nodes in the original document.
eligible_string_leavesSelected string values in the original document.
affected_valuesValues actually changed or removed by the sanitizer.

For the Nested content example:

Selector ConfigurationResult
target_paths = ["/messages/*/content/*/text"]No matching array indices: * is literal in exact paths.
target_paths = ["/messages/0/content"]A container matches, but no string is selected for redact.
target_path_globs = ["/messages/*/content/*/text"]Two text leaves are selected; the email leaf changes.
Neither selector list configuredAll string leaves are eligible; the email leaf changes.

Zero counts are informational: some traffic legitimately lacks the configured path or a matching sensitive value. Diagnostic detail includes only bounded counts, never the original matched content.

Diagnostic Component Keys

Profile observations use component keys such as pii_redaction.selector.profile_0, even with a single profile. Single-policy observations use pii_redaction.selector.

For container removal, omitted selectors, and unchanged selected values, refer to Selection Accounting. The trajectory_context preset uses its semantic sanitization path rather than this selector diagnostic.