Skip to main content

Token Redaction in Spend Logs

Since v1.110.0

LiteLLM replaces known token-shaped secrets in stored spend log content with REDACTED_BY_LITELM. The general_settings.redact_tokens_in_spend_logs flag is on by default. Leaving it unset or setting it to true enables redaction. Set it explicitly to false to opt out.

This setting applies only to content retained with store_prompts_in_spend_logs: true. It does not enable prompt storage itself. A key or team that opts out of prompt storage still stores no request or response content.

Configuration​

Enable prompt storage in your config.yaml and restart the proxy. Token redaction applies by default, so no additional flag is needed.

general_settings:
store_prompts_in_spend_logs: true

To opt out and keep token-shaped strings in the stored content, set the flag to false.

general_settings:
store_prompts_in_spend_logs: true
redact_tokens_in_spend_logs: false

Keep your existing model and database configuration. See request and response storage for how to enable spend log content.

Stored content covered​

Redaction covers string values in the stored request body in proxy_server_request and in the stored response, including nested messages, tool results, tool-call arguments and logprobs. It also covers compaction summary text retained in the stored payload. For realtime calls, it covers the serialized messages stored in the separate messages column.

The setting filters the stored copy, not the live payload. The request sent to the provider and the response returned to the client are unchanged. It does not rewrite rows already in the database.

/v1/responses follow-ups using previous_response_id rebuild history from spend logs, so replayed turns contain the masked value, while redact_tokens_in_spend_logs: false preserves the original in new spend logs.

Token shapes​

The table lists every pattern in _TOKEN_SHAPES, plus the PEM private-key block pattern, from the implementation in PR #48968. Matching is case-sensitive. Lengths refer to the characters after the stated prefix unless the row says otherwise.

Provider or formatMatched shape
Google OAuthya29. followed by at least 20 letters, digits or characters from _.~+/-.
AWS access key IDAKIA or ASIA followed by exactly 16 uppercase letters or digits, then a word boundary. This matches the ID, not an unprefixed AWS secret access key.
OpenAI-style, Anthropic and LiteLLM keyssk- followed by letters, digits, hyphens or underscores. The suffix minimum is MINIMUM_CUSTOM_KEY_LENGTH - 3, which is 13 by default, for a minimum total length of 16. The environment variable MINIMUM_CUSTOM_KEY_LENGTH changes this threshold.
Stripesk_live_, sk_test_, rk_live_ or rk_test_ followed by at least 24 letters or digits.
Google API keyAIza followed by exactly 35 letters, digits, hyphens or underscores.
Databricksdapi followed by exactly 32 lowercase hexadecimal characters, then a word boundary.
GitHub classic and OAuth tokensghp_, gho_, ghu_, ghs_ or ghr_ followed by at least 36 letters or digits.
GitHub fine-grained personal access tokengithub_pat_ followed by exactly 82 letters, digits or underscores.
GitLab personal access tokenglpat- followed by at least 20 letters, digits, hyphens or underscores.
Linearlin_api_ followed by exactly 40 letters or digits, then a word boundary.
Slackxoxa-, xoxb-, xoxp-, xoxo-, xoxs- or xoxr- followed by at least 10 letters, digits or hyphens.
Hugging Facehf_ followed by at least 34 letters or digits.
npmnpm_ followed by exactly 36 letters or digits, then a word boundary.
PyPIpypi-AgEIcHlwaS5vcmc followed by at least 50 letters, digits, hyphens or underscores.
SendGridSG. followed by 22 letters, digits, hyphens or underscores, a dot, then 43 characters from the same set. The final segment can end in -. It must be followed by the end of the string or a character outside [A-Za-z0-9_-], using (?![A-Za-z0-9_-]) rather than a word boundary.
JWTThree dot-separated segments. The header starts with eyJ followed by at least 10 letters, digits, hyphens or underscores. The payload and signature each contain at least one character from that set. The payload does not need an eyJ prefix, so short payloads such as e30 ({}) match.
PEM private keyA complete block from -----BEGIN…PRIVATE KEY----- through -----END…PRIVATE KEY-----, including multiline content. The text between BEGIN or END and PRIVATE KEY can contain uppercase letters, spaces and hyphens, as in RSA or EC key headers. The pattern does not require matching header and footer labels or a fixed block length.

Patterns with an exact suffix length but no trailing word boundary can match the corresponding prefix of a longer string. These are shape checks, not credential validation.

How it works​

During asynchronous spend-log processing after the response is sent, LiteLLM runs a regex pass over every string retained by the spend-log content sanitizer. Matching substrings become REDACTED_BY_LITELM before long strings are truncated for database storage. Realtime messages run through the same redactor after JSON serialization. Retained compaction summaries are redacted before their separate length limit is applied.

Token patterns start where the preceding character is not a word character, or immediately after a JSON escape \n, \r or \t. Word characters include letters, digits and underscores. This start rule catches tokens at the beginning of text and after punctuation, whitespace or serialized line breaks, without matching a token prefix embedded inside another word. The PEM block pattern does not need this start rule.

This pass does not match keywords such as password, Basic or Bearer. Ordinary text without a known token shape stays untouched by this pass. Existing spend-log credential-field masking and payload truncation still apply independently.

Stored tool result example​

With redact_tokens_in_spend_logs: false, a tool result can retain a synthetic GitHub token in its stored content.

{
"type": "tool_result",
"tool_use_id": "toolu_1",
"content": "GITHUB_TOKEN=ghp_a1B2c3D4e5a1B2c3D4e5a1B2c3D4e5F6g7H8\ndone"
}

With the default behavior, or with the flag explicitly set to true, the stored copy contains the replacement and keeps the surrounding text.

{
"type": "tool_result",
"tool_use_id": "toolu_1",
"content": "GITHUB_TOKEN=REDACTED_BY_LITELM\ndone"
}

Limitations​

This flag applies only to spend logs. It does not redact OpenTelemetry, Langfuse or other logging callbacks. Configure those integrations separately.

Only the known shapes above are detected. This is not PII detection and does not find arbitrary passwords, unprefixed secrets or every possible provider credential. Ordinary text that happens to match a token shape can also be masked. Use this setting as an extra safeguard rather than a guarantee that stored content contains no secrets.

The live provider request and client response remain unchanged. To mask content before it reaches a provider, use a separate request guardrail rather than this spend-log setting.

LiteLLM Enterprise
SSO/SAML, audit logs, spend tracking, multi-team management, and guardrails, built for production.
Learn more →