PII and secrets redaction
Agent Observability provides two layers of redaction to keep sensitive data out of LLM provider requests and out of your generation history:
- SDK-side secrets redaction — your application SDK detects and redacts secrets before generation data is exported.
- Server-side guards — synchronous redaction rules and PII evaluators that run on the request path before each LLM call, and optionally sanitize stored records at ingest.
Use the SDK layer to keep credentials out of your traces. Use guards to apply organization-wide policies that scan and redact requests before they reach the model and before generation history is stored.
Before you begin
- An Agent Observability SDK is installed in your application. Refer to Get started for installation.
- For guard-based redaction, Agent Observability is enabled on your Grafana Cloud stack and receiving generation data.
Redact secrets with the SDK
The Go, Python, JavaScript, and .NET SDKs include a built-in secrets sanitizer that runs in the generation pipeline. When enabled, the sanitizer scans message content, tool calls, tool results, and system prompts before the SDK exports the generation. Detected secrets are replaced with [REDACTED:<category>] placeholders, so credentials never reach Agent Observability storage.
Secrets redaction is opt-in. Enable it by passing the sanitizer to your client configuration.
Review SDK support
Secrets redaction is available in the Go, Python, JavaScript, and .NET SDKs. Email address redaction is on by default in each SDK.
Review detected secrets
The SDK sanitizer ships with hand-curated patterns sourced from gitleaks. The same patterns are applied across Go, Python, JavaScript, and .NET.
The sanitizer applies a high-confidence pass to all assistant text and reasoning, and an extended pass (which includes the heuristic env-style assignments) to tool arguments, tool results, and system prompts. This split keeps false positives out of model reasoning while catching credentials in tool inputs.
The SDK sanitizer doesn’t detect names, addresses, government IDs, phone numbers, or other general PII. For that, use a guard.
Enable secrets redaction
Pass the sanitizer to your client configuration. Once enabled, the sanitizer runs automatically on all generation exports.
Go
import "github.com/grafana/agento11y/go/agento11y"
client := agento11y.NewClient(agento11y.Config{
GenerationSanitizer: agento11y.NewSecretRedactionSanitizer(agento11y.SecretRedactionOptions{}),
})Python
from agento11y import Client, ClientConfig, create_secret_redaction_sanitizer
client = Client(ClientConfig(
generation_sanitizer=create_secret_redaction_sanitizer(),
))JavaScript
import { Agento11yClient, createSecretRedactionSanitizer } from "@grafana/agento11y";
const client = new Agento11yClient({
generationSanitizer: createSecretRedactionSanitizer(),
});.NET
using Grafana.Agento11y;
var client = new Agento11yClient(new Agento11yClientConfig
{
GenerationSanitizer = SecretRedactionSanitizer.Create(),
});Redact user input messages
By default, the sanitizer leaves user messages untouched so that intentional user-provided context, for example, a SQL query a user pasted into a chat, isn’t redacted. To also redact secrets from user messages, opt in:
- Set
RedactInputMessages: true(Go),redact_input_messages=True(Python),redactInputMessages: true(JavaScript), orRedactInputMessages = true(.NET) on the sanitizer options. - Or set the environment variable
AGENTO11Y_REDACT_INPUT_MESSAGES=true.
Explicit options take precedence over the environment variable.
View redacted content
When the sanitizer detects a secret, it replaces the matched substring with a tagged placeholder:
Original tool argument:
{"command": "curl -H 'Authorization: Bearer ghp_aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789'"}Sanitized tool argument exported to Agent Observability:
{"command": "curl -H 'Authorization: [REDACTED:bearer-token]'"}Placeholders follow the format [REDACTED:<category>], where <category> identifies the pattern that matched, for example, aws-access-token, github-pat, openai-api-key, anthropic-api-key, email-address.
Redact secrets with server-side guards
Guards run on the request path before each LLM call and return an allow or deny decision to the SDK. Two guard types are relevant to redaction:
- Redact guards apply regex patterns to redact content in messages, system prompts, tool definitions, and tool call arguments. The SDK uses the sanitized copy for the LLM call.
- Evaluator guards with the built-in
template.piiLLM judge detect personally identifiable information based on a semantic policy rather than fixed patterns.
For the full guard configuration workflow, refer to Set up guards.
Detect PII with the template.pii evaluator
The built-in PII evaluator is an LLM judge. Because it uses semantic judgment rather than fixed patterns, it catches PII that regex misses, for example, an address written in natural language, at the cost of an additional LLM call per guarded request. To select an available provider and model, refer to Choose a judge provider.
It flags responses containing:
- Contact details, for example, email addresses or phone numbers.
- Postal addresses.
- Government-issued identifiers.
- Financial details.
- Credentials.
- Exact dates of birth.
- Combinations of attributes that identify a private individual.
Redact with redact guards
Redact guards use regex patterns you define, for example, to redact US SSNs and phone numbers. Matches are always replaced with the fixed token [REDACTED]:
On the request path, redact guards scan system prompts, message text in user, assistant, and tool messages, tool call arguments (JSON serialized), tool result content, and tool definition descriptions and input schemas. Request-path guard hooks don’t scan model thinking blocks, because changing them would invalidate the provider’s reasoning signature.
When the sigil.guards-ingest-redaction feature flag is enabled for your tenant, Agent Observability also executes enabled redact rules at ingest before saving generations and workflow steps:
- Redacted storage content includes message text, thinking blocks, tool results, tool-call and tool-result JSON, system prompts, tool schemas, conversation titles, generation error messages, raw artifacts, and workflow step state and error messages.
- Ingest applies redact rules more broadly than the request path. It ignores the rule’s selector, so it redacts every turn, and it treats match conditions it can’t check as matching.
- Stored records modified at ingest are tagged with
agento11y.redaction.ingest=trueandagento11y.redaction.rule_ids, and display a Redacted at ingest badge in conversation explore. Only ingest sets these tags. If your application sends tags with these names, ingest removes them. - If ingest can’t load your redact rules, it keeps applying the last rules it loaded. If it has none to apply, ingest fails closed with a transient error so it doesn’t store unredacted data.
For the full redact guard workflow, refer to Set up guards.
Understand coverage and limits
The SDK and guard layers cover different paths. SDK secrets redaction sanitizes generation content before it leaves your application, so credentials don’t reach Agent Observability storage or traces. Redact guards sanitize outbound request content before it reaches the LLM provider and, with ingest redaction enabled, sanitize records before storage.
Redaction doesn’t cover:
- Responses from the LLM provider on the request path — generated text isn’t scanned by the SDK sanitizer or preflight guard redactions. If a model emits sensitive data in its response, that content reaches your application unmodified. For response-side checks, attach an evaluator guard that runs after generation. With ingest redaction enabled, response text is redacted before persistence.
- Streaming responses — postflight evaluation buffers complete responses today; Agent Observability doesn’t yet support per-chunk scanning of streaming responses.
- Model thinking blocks on the request path — preflight redact guards skip thinking content to preserve provider reasoning signatures for the model. However, when ingest redaction is enabled, thinking blocks are redacted before storage.
- Tags and metadata identifiers — ingest redaction never redacts tags or IDs. If an identifier, for example, an email address in
user.id, is stored in a tag, redact rules do not alter it. - Data stored before enabling ingest redaction — turning on ingest redaction only applies to new incoming generations and workflow steps. Records stored earlier are not changed.
- What the model already received — if a caller, for example, a coding agent or custom workflow step, exports data without using the guard’s
transformed_input, ingest redaction keeps the text out of storage, but it can’t retract what was already sent to the model provider. - Reversal of redacted values — the
[REDACTED]token is permanent. Agent Observability doesn’t store a mapping back to the original value, so downstream consumers see the token. If your workflow requires the model or application to act on the original value, for example, processing a refund using the real SSN, redact in a layer that handles de-redaction separately.
If your security model requires that sensitive data never enters Agent Observability under any path, combine SDK-side sanitization for client-trusted data with server-side guards for any data that originates outside your control.
Next steps
- Set up guards to configure server-side redaction policies.
- Data handling and privacy for what Agent Observability stores and how to control retention.
- Security and access controls for authentication and authorization.


