How to Configure Custom Authentication for the LiteLLM Proxy

LiteLLM proxy delegates API key validation to user-defined Python functions via the custom_auth configuration setting, enabling bespoke security policies without modifying core code.

The BerriAI/litellm repository provides a proxy server that can offload authentication logic to custom code. By configuring the custom_auth parameter in your proxy YAML file, you implement tenant-specific rate limits, IP allow-lists, or external identity provider integrations while preserving the default request pipeline.

How Custom Authentication Works in LiteLLM

LiteLLM’s proxy server resolves the custom authentication hook at startup and invokes it during every incoming request. The mechanism relies on dynamic function resolution and middleware integration.

Configuration Loading and Resolution

When the proxy starts, litellm/proxy/proxy_server.py reads the general_settings section of your configuration file. If custom_auth is present, the server uses get_instance_fn from litellm/proxy/types_utils/utils.py to resolve the dotted path into a callable object:


# litellm/proxy/proxy_server.py (lines 44-51)

custom_auth = general_settings.get("custom_auth", None)
if custom_auth is not None:
    user_custom_auth = get_instance_fn(
        value=custom_auth, config_file_path=config_file_path
    )

The resulting function is stored in the global user_custom_auth variable for later use.

Request-Time Execution

During request processing, the authentication middleware in litellm/proxy/auth/user_api_key_auth.py executes after the built-in enterprise hooks. If user_custom_auth is defined, the middleware invokes your function with the FastAPI Request object and the extracted API key:


# litellm/proxy/auth/user_api_key_auth.py (lines 606-608)

elif user_custom_auth is not None:
    response = await user_custom_auth(request=request, api_key=api_key)

Your custom function must follow these semantics:

  • Return None or any truthy object to indicate authentication succeeded
  • Raise an HTTPException (or any exception caught by UserAPIKeyAuthExceptionHandler) to trigger a 401 Unauthorized response with the exception's detail message

Implementing a Custom Authentication Function

Create a Python module accessible from your PYTHONPATH. The function must accept (request: Request, api_key: str) and be async-compatible.


# custom_auth/user_api_key_auth.py

import os
from fastapi import Request, HTTPException, status

async def user_api_key_auth(request: Request, api_key: str):
    """
    Reject keys that do not start with a required prefix defined in ENV.
    """
    required_prefix = os.getenv("CUSTOM_AUTH_PREFIX", "my-prefix-")
    if not api_key.startswith(required_prefix):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Authentication Error, API key missing required prefix",
        )
    # Optionally attach data to request.state for downstream handlers

    request.state.custom_user = {"prefix_ok": True}
    return None  # Authentication succeeded

Function Signature and Return Values

The callable registered in custom_auth must handle two parameters:

  • request: The FastAPI Request object, allowing access to headers, client IP, and state
  • api_key: The string extracted from the request's authorization header

Successful validation should return None or a truthy value. Failed validation must raise HTTPException with an appropriate status code and detail message.

Configuring the Proxy to Use Custom Auth

Add the custom_auth key to your proxy configuration file under general_settings. The value must be the dotted import path to your callable.


# config.yaml

general_settings:
  master_key: "$PROXY_MASTER_KEY"
  custom_auth: custom_auth.user_api_key_auth

Start the proxy server with your configuration:

export PROXY_MASTER_KEY=sk-...
export CUSTOM_AUTH_PREFIX=my-prefix-
poetry run litellm --config config.yaml

The proxy resolves custom_auth.user_api_key_auth at startup using the same get_instance_fn utility found in litellm/proxy/types_utils/utils.py.

Testing and Validation

When properly configured, requests behave according to the logic in tests/proxy_unit_tests/test_proxy_custom_auth.py:

  • Valid requests: Keys matching your custom logic proceed to model routing
  • Invalid requests: Return HTTP 401 with your custom error detail:
{
  "detail": "Authentication Error, API key missing required prefix"
}

This behavior applies to both HTTP and WebSocket endpoints, allowing consistent authentication across all proxy interfaces.

Summary

  • Configuration: Set custom_auth in general_settings to a dotted Python path
  • Resolution: litellm/proxy/proxy_server.py loads the function via get_instance_fn at startup
  • Execution: litellm/proxy/auth/user_api_key_auth.py invokes your function after default checks
  • Contract: Return None for success, raise HTTPException for 401 failures
  • Use cases: IP allow-lists, tenant-specific rate limits, SSO/OAuth integration, and audit logging

Frequently Asked Questions

What is the exact function signature required for custom authentication?

Your function must accept (request: Request, api_key: str) and return an awaitable. According to the source code in litellm/proxy/auth/user_api_key_auth.py, the middleware calls await user_custom_auth(request=request, api_key=api_key). The function should return None or a truthy object on success, or raise HTTPException to reject the request.

Can I use custom authentication alongside the default API key validation?

Yes. The custom auth function executes after the built-in enterprise hook and default validation steps in user_api_key_auth.py. This means you can layer additional checks—such as IP restrictions or external identity verification—on top of LiteLLM's standard API key validation without replacing it.

How does the proxy locate my custom authentication module?

The proxy uses get_instance_fn from litellm/proxy/types_utils/utils.py to resolve the dotted path provided in custom_auth. The module containing your function must be importable from the Python environment where you launch the proxy. Typically, you place the module in your project directory or install it as a package before starting the server.

What happens if my custom authentication function raises an exception?

If your function raises HTTPException or any exception caught by UserAPIKeyAuthExceptionHandler, the proxy returns a 401 Unauthorized response with the exception's detail message. This matches the test cases in tests/proxy_unit_tests/test_proxy_custom_auth.py, ensuring consistent error handling for invalid authentication attempts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →