litellm - ✅(Solved) Fix [Bug]: Langfuse api keys leaking in metadata [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
BerriAI/litellm#23776Fetched 2026-04-08 00:49:09
View on GitHub
Comments
0
Participants
1
Timeline
8
Reactions
0
Participants
Timeline (top)
cross-referenced ×3referenced ×3labeled ×2

Fix Action

Fixed

PR fix notes

PR #23824: fix(proxy): mask sensitive fields in key/info endpoint metadata

Description (problem / solution / changelog)

Problem

When dynamically allowing langfuse callback at the key level, the langfuse credentials (public_key, secret_key) were stored in the key's metadata in plaintext and exposed via the /key/info endpoint.

Solution

Added a helper function _mask_sensitive_fields_in_key_info() that uses the existing SensitiveDataMasker class to redact sensitive fields (keys, secrets, tokens, passwords, etc.) from the metadata before returning it in the key/info response.

Changes

  • Added import for SensitiveDataMasker
  • Added _mask_sensitive_fields_in_key_info() helper function
  • Applied masking in both /key/info and /v2/key/info endpoints
  • Added comprehensive unit tests

Testing

  • All 9 new unit tests pass
  • Code passes ruff linting

Fixes #23776

Changed files

  • litellm/proxy/management_endpoints/key_management_endpoints.py (modified, +30/-0)
  • tests/test_litellm/proxy/management_endpoints/test_key_info_sensitive_data_masking.py (added, +158/-0)

PR #23832: fix(key_management): redact sensitive callback credentials in key info response

Description (problem / solution / changelog)

Relevant issues

Fixes #23776

Pre-Submission checklist

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit (verified with custom test file)
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have completed the fix

Type

🐛 Bug Fix

Changes

When dynamically enabling Langfuse callbacks at the key level, the credentials (langfuse_secret_key, langfuse_public_key, etc.) were being stored in plaintext in the key's metadata. When the /key/info endpoint was called, these credentials were returned in plaintext, exposing them to team members.

Root Cause

The key metadata stored logging callback configuration including callback_vars which contains sensitive credentials. When the /key/info endpoint returned key information, the metadata was included without sanitization.

Fix

Added _sanitize_key_metadata_for_response() function that:

  1. Identifies sensitive fields from StandardCallbackDynamicParams (API keys, secrets, tokens, credentials)
  2. Redacts sensitive values (replaces with "REDACTED") while preserving non-sensitive fields like host URLs and project names
  3. Applied sanitization in both info_key_fn and info_key_fn_v2 endpoints

Test Evidence

Created comprehensive test file test_sanitize_key_metadata.py with 8 test cases:

  • Langfuse credentials are properly redacted
  • Langsmith credentials are properly redacted
  • GCS credentials are properly redacted
  • Keys without logging config are unaffected
  • Keys without metadata are unaffected
  • Original key_info is not modified (deep copy)
  • Multiple callbacks are all sanitized
  • Callbacks without callback_vars are handled correctly

All 8 tests pass successfully.

Security Impact

This fix prevents credential leakage via the /key/info endpoint while maintaining the functionality of key-level logging callbacks.

Changed files

  • litellm/proxy/management_endpoints/key_management_endpoints.py (modified, +68/-0)

Code Example

curl -X GET "http://0.0.0.0:4000/key/info" \
-H "Authorization: Bearer sk-test-example-key-123"

---
RAW_BUFFERClick to expand / collapse

Check for existing issues

  • I have searched the existing issues and checked that my issue is not a duplicate.

What happened?

Problem: When dynamically allowing langfuse callback at the key level, the langfuse credentials get stored in the keys metadata in plaintext.

Expectation: The langfuse should not be visible in the metadata.

Impact / blocking: Team members can see langfuse keys.

Steps to Reproduce

  1. Create a key with key level langfuse logging.
<img width="632" height="555" alt="Image" src="https://github.com/user-attachments/assets/ddfafe89-617d-4b3f-b2af-9671dec93808" />
  1. Call key/info endpoint on that key
curl -X GET "http://0.0.0.0:4000/key/info" \
-H "Authorization: Bearer sk-test-example-key-123"
  1. See the langfuse key info in the metadata <img width="354" height="479" alt="Image" src="https://github.com/user-attachments/assets/b231efaf-f539-4652-9ffd-d4916c8825ab" />

Note: No api key/ secrets should be visible to anyone.

Relevant log output

What part of LiteLLM is this about?

Proxy

What LiteLLM version are you on ?

v1.82.0

Twitter / LinkedIn details

No response

extent analysis

Fix Plan

To address the issue of langfuse credentials being stored in plaintext in key metadata, we need to modify the code to encrypt or remove these credentials from the metadata.

Step-by-Step Solution

  1. Modify the key creation endpoint: Update the endpoint that creates keys with key-level langfuse logging to not store langfuse credentials in plaintext.
  2. Encrypt langfuse credentials: Implement encryption for langfuse credentials before storing them in the database or metadata.
  3. Update the key/info endpoint: Modify the key/info endpoint to exclude langfuse credentials from the response.

Example Code (Node.js)

// Import required libraries
const crypto = require('crypto');

// Function to encrypt langfuse credentials
function encryptLangfuseCredentials(langfuseKey) {
  const algorithm = 'aes-256-cbc';
  const iv = crypto.randomBytes(16);
  const key = crypto.createHash('sha256').update(process.env.ENCRYPTION_KEY).digest();
  const cipher = crypto.createCipheriv(algorithm, key, iv);
  const encrypted = Buffer.concat([cipher.update(langfuseKey), cipher.final()]);
  return iv.toString('hex') + ':' + encrypted.toString('hex');
}

// Function to decrypt langfuse credentials (for internal use only)
function decryptLangfuseCredentials(encryptedLangfuseKey) {
  const parts = encryptedLangfuseKey.split(':');
  const iv = Buffer.from(parts.shift(), 'hex');
  const encryptedBuffer = Buffer.from(parts.join(':'), 'hex');
  const algorithm = 'aes-256-cbc';
  const key = crypto.createHash('sha256').update(process.env.ENCRYPTION_KEY).digest();
  const decipher = crypto.createDecipheriv(algorithm, key, iv);
  const decrypted = Buffer.concat([decipher.update(encryptedBuffer), decipher.final()]);
  return decrypted.toString();
}

// Example usage in key creation endpoint
app.post('/key', (req, res) => {
  const langfuseKey = req.body.langfuseKey;
  const encryptedLangfuseKey = encryptLangfuseCredentials(langfuseKey);
  // Store encryptedLangfuseKey in database or metadata
});

// Example usage in key/info endpoint
app.get('/key/info', (req, res) => {
  const keyInfo = getKeyInfoFromDatabase(req.params.keyId);
  // Omit or decrypt langfuse credentials before sending the response
  delete keyInfo.langfuseKey;
  res.json(keyInfo);
});

Verification

To verify that the fix worked, create a new key with key-level langfuse logging and call the key/info endpoint. The response should not contain the langfuse credentials in plaintext.

Extra Tips

  • Ensure that the encryption key is stored securely and not exposed to unauthorized parties.
  • Consider implementing additional security measures, such as access controls and auditing, to protect sensitive data.
  • Regularly review and update the encryption algorithm and key

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

litellm - ✅(Solved) Fix [Bug]: Langfuse api keys leaking in metadata [2 pull requests, 1 participants]