{"record":{"id":"df563c34e2ae8c21","repo":"BerriAI/litellm","slug":"microsoft-purview-dlp-no-proxy-authenticated-user-df563c","errorCode":null,"errorMessage":"Microsoft Purview DLP: No proxy-authenticated user identity; bind user_id to the API key for blocking DLP","messagePattern":"Microsoft Purview DLP: No proxy-authenticated user identity; bind user_id to the API key for blocking DLP","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"litellm/proxy/guardrails/guardrail_hooks/microsoft_purview/purview_dlp.py","lineNumber":371,"sourceCode":"        only caller-influenceable identity fields are available (fail closed).\n        \"\"\"\n        trusted_id: Final = self._resolve_trusted_user_id(data, user_api_key_dict)\n        if trusted_id:\n            return trusted_id\n\n        if self._resolve_user_id(data, user_api_key_dict):\n            raise HTTPException(\n                status_code=400,\n                detail={\n                    \"error\": (\n                        \"Microsoft Purview DLP: No proxy-authenticated user identity; \"\n                        \"bind user_id to the API key (caller-supplied metadata cannot \"\n                        \"be used for blocking DLP)\"\n                    ),\n                },\n            )\n\n        raise HTTPException(\n            status_code=400,\n            detail={\n                \"error\": (\n                    \"Microsoft Purview DLP: No proxy-authenticated user identity; \"\n                    \"bind user_id to the API key for blocking DLP\"\n                ),\n            },\n        )\n\n    # ------------------------------------------------------------------\n    # Pre-call hook — DLP on prompts\n    # ------------------------------------------------------------------\n\n    @log_guardrail_information\n    async def async_pre_call_hook(\n        self,\n        user_api_key_dict: \"UserAPIKeyAuth\",\n        cache: Any,","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/guardrails/guardrail_hooks/microsoft_purview/purview_dlp.py#L353-L389","documentation":"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.","triggerScenarios":"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","commonSituations":"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","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"],"exampleFix":"# before: shared key, no identity anywhere\nclient = OpenAI(api_key=\"sk-shared-no-user\")\n\n# after: dedicated key carrying identity\n# curl -X POST $PROXY/key/generate -H \"Authorization: Bearer $ADMIN\" \\\n#   -d '{\"user_id\": \"svc-billing\", \"key_duration\": null}'\nclient = OpenAI(api_key=BOUND_SERVICE_KEY)","handlingStrategy":"validation","validationCode":"# Fail fast in your client bootstrap: refuse to call guarded routes with unbound keys\nasync def assert_key_bound(proxy_admin: ProxyAdmin, key: str) -> None:\n    user_id = await proxy_admin.get_key_user_id(key)\n    if not user_id:\n        raise RuntimeError(\n            f\"key {key[:8]}... has no bound user_id; Purview blocking DLP will reject it\"\n        )","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["microsoft-purview","guardrails","identity","authentication","api-key"],"backgroundTag":"untrusted-identity-rejected","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}