{"record":{"id":"122a995565c6f72a","repo":"BerriAI/litellm","slug":"litellm-salt-key-is-not-configured-plugin-iframe","errorCode":null,"errorMessage":"LITELLM_SALT_KEY is not configured; plugin iframe auth unavailable.","messagePattern":"LITELLM_SALT_KEY is not configured; plugin iframe auth unavailable\\.","errorType":"http","errorClass":"HTTPException","httpStatus":503,"severity":"error","filePath":"litellm/proxy/plugin_routes.py","lineNumber":234,"sourceCode":"\n@router.get(\"/api/plugins/auth-token\", tags=[\"plugins\"])\nasync def plugin_auth_token(\n    user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth),\n    plugin_name: str = \"litellm-platform-plugin\",\n) -> dict:\n    \"\"\"Issue a short-lived, audience-scoped plugin session claim.\n\n    The claim contains {user_id, user_role, plugin, exp}.  It does NOT\n    contain the caller's litellm bearer token — a compromised plugin can\n    only learn the caller's identity, not impersonate them against the proxy.\n\n    Encrypted with a key derived from HMAC(LITELLM_SALT_KEY, plugin_name),\n    so each plugin holds only its own key and cannot forge claims for others.\n\n    Requires LITELLM_SALT_KEY to be set; returns 503 otherwise.\n    \"\"\"\n    if not os.getenv(\"LITELLM_SALT_KEY\"):\n        raise HTTPException(\n            status_code=503,\n            detail=\"LITELLM_SALT_KEY is not configured; plugin iframe auth unavailable.\",\n        )\n    if plugin_name not in _plugin_registry:\n        raise HTTPException(status_code=404, detail=f\"Plugin '{plugin_name}' is not registered.\")\n    user_id: Final = getattr(user_api_key_dict, \"user_id\", None)\n    user_role: Final = getattr(user_api_key_dict, \"user_role\", None)\n    return {\"session_claim\": issue_plugin_session_claim(plugin_name, user_id, user_role)}\n\n\n@router.api_route(\n    \"/plugin-proxy/{plugin_name}/{path:path}\",\n    methods=[\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\", \"HEAD\"],\n    tags=[\"plugins\"],\n    include_in_schema=False,\n)\nasync def plugin_proxy(\n    plugin_name: str,","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/plugin_routes.py#L216-L252","documentation":"Guard in the plugin auth-token endpoint: issuing the encrypted session claim requires deriving a Fernet key from LITELLM_SALT_KEY via HMAC; with the env var unset there is no key material, so iframe auth is refused (503) rather than silently degraded.","triggerScenarios":"Thrown at litellm/proxy/plugin_routes.py:234 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Set LITELLM_SALT_KEY in the proxy environment and restart to enable plugin iframe auth."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}