Skip to main content
When your application handles API keys, tokens, or other credentials, those values can appear in LangSmith traces if they are passed as part of inputs or outputs. Use the LangSmith SDK’s built-in anonymizer to redact secrets before they are sent to the backend.
This page covers redacting secrets (API keys, tokens, credentials) from trace data via the SDK. For redacting personally identifiable information (PII) such as emails, names, or SSNs, see Prevent logging of sensitive data in traces. To redact secrets at the LLM Gateway layer, see Data policy.The coding agent tracing plugins for Claude Code, OpenAI Codex, and Cursor apply the preset below by default. No SDK code is required for those.

Use the built-in secret preset

The SDK ships a curated rule set for common credential formats. Pass create_secret_anonymizer to the Client constructor and it redacts detected secrets from run inputs, outputs, errors, and metadata before they are uploaded. Use it when you want coverage of well-known key formats without writing patterns yourself.
The create_secret_anonymizer / createSecretAnonymizer function requires:
  • Python SDK: 0.9.0 or later
  • TypeScript SDK: 0.7.11 or later
Each match is replaced with [SECRET_DETECTED]. The preset traverses up to 24 nesting levels, rather than the 10 that create_anonymizer uses, because traced payloads nest deeply. Override it with max_depth. The Python and TypeScript presets hold the same rules, so a trace redacted by one matches a trace redacted by the other.

Rules in the preset

Provider rules are anchored to a known key prefix. Contextual rules fire only when a sensitive name is paired with an assignment, which leaves ordinary code, UUIDs, and content hashes intact. A name rule requires a component boundary, so TOKEN matches api_token and mytoken but not tokenizer or tokens. Header and Bearer rules keep the header name and the scheme word, and redact only the credential that follows.

Add your own rules to the preset

Pass extra_rules to append patterns for credentials the preset does not know about, such as an internal key format. Extra rules run after the built-in ones.
A rule without a replace value falls back to [redacted], not [SECRET_DETECTED]. Set replace when you want the two to be distinguishable in a trace.

Limits of the preset

The preset favors precision over exhaustive coverage, which has consequences worth planning around:
  • Unrecognized formats reach LangSmith: a credential that matches no rule, including a random high-entropy string with no surrounding context, is uploaded as is.
  • Only four fields are redacted: the anonymizer covers inputs, outputs, error, and extra.metadata. Run names, tags, and attachments are uploaded unmodified.
  • Redaction is not access control: a redacted trace still holds the prompts, file contents, and tool results it was built from. Restrict who can read the tracing project. To omit content rather than scrub it, see Prevent logging of sensitive data in traces.

Write custom patterns

The create_anonymizer / createAnonymizer function requires:
  • Python SDK: 0.1.81 or later
  • TypeScript SDK: 0.1.33 or later
When the preset does not fit, create_anonymizer takes a list of regex patterns and replacement strings and applies only those. Pass the resulting anonymizer to the Client constructor, and it will automatically apply to all run inputs and outputs before they reach LangSmith. The following example redacts common secret formats, including OpenAI API keys, generic bearer tokens, and sk- prefixed keys:
The anonymizer serializes inputs and outputs to JSON, applies each regex pattern, then deserializes the result before sending to LangSmith. By default, it traverses up to 10 nesting levels deep. To change this, pass the max_depth parameter:

Use a custom function

If your redaction logic is more complex, pass a function instead of a list of patterns. The function receives a string and returns the redacted string:

Combine with LANGSMITH_HIDE_INPUTS

If your use case requires completely suppressing all inputs (for example, for zero-retention compliance), use LANGSMITH_HIDE_INPUTS=true instead. The anonymizer is skipped when LANGSMITH_HIDE_INPUTS or LANGSMITH_HIDE_OUTPUTS is set to true. For more options, including hiding all inputs and outputs, hiding metadata, function-level processors, and third-party PII libraries, see Prevent logging of sensitive data in traces.