BerriAI/litellm · error · HTTPException
Microsoft Purview DLP: No proxy-authenticated user identity;
Error message
Microsoft Purview DLP: No proxy-authenticated user identity; bind user_id to the API key for blocking DLP
What it means
The 'no identity at all' variant of Purview blocking-mode identity resolution: neither a trusted API-key-bound user id nor any caller-influenceable identity field was found, so the guardrail cannot attribute the request to an Entra user and rejects it with 400. Same fix as its sibling error — identity must be provisioned on the proxy side.
Source
Thrown at litellm/proxy/guardrails/guardrail_hooks/microsoft_purview/purview_dlp.py:371
only caller-influenceable identity fields are available (fail closed).
"""
trusted_id: Final = self._resolve_trusted_user_id(data, user_api_key_dict)
if trusted_id:
return trusted_id
if self._resolve_user_id(data, user_api_key_dict):
raise HTTPException(
status_code=400,
detail={
"error": (
"Microsoft Purview DLP: No proxy-authenticated user identity; "
"bind user_id to the API key (caller-supplied metadata cannot "
"be used for blocking DLP)"
),
},
)
raise HTTPException(
status_code=400,
detail={
"error": (
"Microsoft Purview DLP: No proxy-authenticated user identity; "
"bind user_id to the API key for blocking DLP"
),
},
)
# ------------------------------------------------------------------
# Pre-call hook — DLP on prompts
# ------------------------------------------------------------------
@log_guardrail_information
async def async_pre_call_hook(
self,
user_api_key_dict: "UserAPIKeyAuth",
cache: Any,View on GitHub (pinned to 77b7c6c40c)
Solutions
- Create per-user (or per-service) virtual keys with user_id via /key/generate and use those keys for guarded routes
- If the caller legitimately has no user, still bind a stable service identity so Purview policy has an actor
- Keep master-key/admin traffic off Purview-guarded models, or give the admin key a user_id
Example fix
# before: shared key, no identity anywhere
client = OpenAI(api_key="sk-shared-no-user")
# after: dedicated key carrying identity
# curl -X POST $PROXY/key/generate -H "Authorization: Bearer $ADMIN" \
# -d '{"user_id": "svc-billing", "key_duration": null}'
client = OpenAI(api_key=BOUND_SERVICE_KEY) Defensive patterns
Strategy: validation
Validate before calling
# Fail fast in your client bootstrap: refuse to call guarded routes with unbound keys
async def assert_key_bound(proxy_admin: ProxyAdmin, key: str) -> None:
user_id = await proxy_admin.get_key_user_id(key)
if not user_id:
raise RuntimeError(
f"key {key[:8]}... has no bound user_id; Purview blocking DLP will reject it"
) Prevention
- Give every integration its own key with a user_id (real user or stable service identity)
- Keep master-key traffic off guardrail-protected models
- Alert on this 400 pattern — it always means a provisioning gap, never bad input
When it happens
Trigger: Requests through a shared/generic virtual key that was never associated with a user; direct calls with the master key; internal services calling the proxy without any user metadata
Common situations: Load tests or health checks hitting a Purview-guarded route with the admin key; service-to-service traffic with no user concept needing per-user DLP exemptions
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Microsoft Purview DLP: No proxy-authenticated user identity;
- Invalid API key
- api_key is required
- Authentication failed. Check your Arize Phoenix API key and
- CohereException - {original_exception.message}
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/df563c34e2ae8c21.
Report an issue: GitHub.