{"record":{"id":"d1245b0dbc3c7ca7","repo":"BerriAI/litellm","slug":"you-are-not-allowed-to-access-this-key-s-info-you","errorCode":null,"errorMessage":"You are not allowed to access this key's info. Your role={user_api_key_dict.user_role}","messagePattern":"You are not allowed to access this key's info\\. Your role=(.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"litellm/proxy/management_endpoints/key_management_endpoints.py","lineNumber":3690,"sourceCode":"            include={\"litellm_budget_table\": True},\n        )\n        if key_info is None:\n            raise ProxyException(\n                message=\"Key not found in database\",\n                type=ProxyErrorTypes.not_found_error,\n                param=\"key\",\n                code=status.HTTP_404_NOT_FOUND,\n            )\n\n        if (\n            await _can_user_query_key_info(\n                user_api_key_dict=user_api_key_dict,\n                key=key,\n                key_info=key_info,\n            )\n            is not True\n        ):\n            raise HTTPException(\n                status_code=status.HTTP_403_FORBIDDEN,\n                detail=f\"You are not allowed to access this key's info. Your role={user_api_key_dict.user_role}\",\n            )\n        ## REMOVE HASHED TOKEN INFO BEFORE RETURNING ##\n        try:\n            key_info = key_info.model_dump()\n        except Exception:\n            # if using pydantic v1\n            key_info = key_info.dict()\n        key_token_hash: Final = key_info.pop(\"token\")\n\n        model_max_budget = key_info.get(\"model_max_budget\") or {}\n        budget_table: Final = key_info.get(\"litellm_budget_table\") or {}\n        if not model_max_budget and isinstance(budget_table, dict):\n            model_max_budget = budget_table.get(\"model_max_budget\") or {}\n        if model_max_budget and key_token_hash:\n            key_info[\"model_max_budget_usage\"] = await _build_model_max_budget_usage(\n                api_key_hash=key_token_hash,","sourceCodeStart":3672,"sourceCodeEnd":3708,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/key_management_endpoints.py#L3672-L3708","documentation":"After finding the key row, GET /key/info runs _can_user_query_key_info: access is granted to proxy admins (and view-only admins), the caller whose own api_key equals the queried key, users matching the key's user_id, or members of the key's team. Everyone else gets this 403 naming their role. It prevents users from enumerating other users' key details (spend, limits, metadata).","triggerScenarios":"A normal user key calling GET /key/info?key=<someone else's key>; a user who left the team querying a team key they no longer belong to; an auditor-style service key with no team membership or admin role requesting arbitrary keys.","commonSituations":"Internal tooling built with a shared non-admin key trying to display all keys; team membership removed but cached client still queries old team keys; misunderstanding that key ownership (not just authentication) is enforced for info reads.","solutions":["Query only your own key (omit the key param — it defaults to the Authorization key).","Use a proxy admin (master) key when you legitimately need other users' key info.","For team keys, ensure the calling user is a member of that team first (POST /team/member_add)."],"exampleFix":"# before\nclient.headers[\"Authorization\"] = \"Bearer sk-regular-user\"\nclient.get(\"/key/info\", params={\"key\": \"sk-someone-else\"})\n\n# after (admin needs others' info)\nclient.headers[\"Authorization\"] = \"Bearer sk-master\"\nclient.get(\"/key/info\", params={\"key\": \"sk-someone-else\"})","handlingStrategy":"validation","validationCode":"# Only query keys you're permitted to see:\n# - your own key (omit the key param), or\n# - keys of a team you belong to (check membership first), or\n# - use a proxy-admin key for arbitrary lookups.\ndef can_query(client, role: str, own_key: str, target_key: str) -> bool:\n    return role in (\"proxy_admin\", \"proxy_admin_view_only\") or own_key == target_key","typeGuard":null,"tryCatchPattern":"try:\n    info = client.get(\"/key/info\", params={\"key\": key})\n    info.raise_for_status()\nexcept HTTPError as e:\n    if e.response.status_code == 403 and \"not allowed to access this key's info\" in e.response.text:\n        return None  # deliberately not our key; skip silently\n    raise","preventionTips":["Scope dashboards to the caller's own key or their teams' keys only.","Use a dedicated admin credential for admin-wide key reporting tools.","Remember the access rule: admin roles, key owner, key's user, or key's team members — no one else."],"tags":["authorization","rbac","key-management","litellm-proxy"],"backgroundTag":"permission-denied-403","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}