Implementation:Langchain ai Langgraph Auth Module
| Knowledge Sources | |
|---|---|
| Domains | Authentication, Security |
| Last Updated | 2026-02-11 16:00 GMT |
Overview
The `Auth` class provides a decorator-based framework for adding custom authentication and fine-grained, resource-level authorization to LangGraph Server applications.
Description
The Auth module is the primary entry point for securing LangGraph Server deployments. Developers create an `Auth` instance in a dedicated Python file, register an authentication handler via the `@auth.authenticate` decorator, and define authorization handlers via the `@auth.on` decorator hierarchy. The LangGraph Server loads this file at startup and invokes the handlers server-side on every incoming request.
Authentication is handled by a single async function decorated with `@auth.authenticate`. This handler receives request-level parameters (such as the `authorization` header, request path, method, headers, and query parameters) by name injection, verifies credentials, and returns a user representation -- either a simple string (user ID), a `MinimalUserDict`, or an object conforming to the `BaseUser` protocol. If authentication fails, the handler raises an `HTTPException`.
Authorization handlers are registered through the `auth.on` namespace, which provides a hierarchical decorator API: `@auth.on` for global fallback rules, `@auth.on.threads` for all thread actions, `@auth.on.threads.create` for a specific resource-action pair, and similar patterns for `assistants`, `crons`, and `store` resources. Each handler is an async function accepting `ctx` (an `AuthContext` with user info, resource, and action) and `value` (the mutable request payload typed per endpoint). Handlers return `None`/`True` to allow, `False` to deny with 403, or a `FilterType` dict to apply metadata filters. The most specific matching handler wins: action-specific overrides resource-level, which overrides global.
Internally, the module maintains `_handlers` (a dict keyed by `(resource, action)` tuples), `_global_handlers` (a list for the catch-all), and a `_handler_cache` for lookup optimization. Helper classes `_ThreadsOn`, `_AssistantsOn`, `_CronsOn`, and `_StoreOn` implement the resource-specific decorator namespaces with full type safety via generics.
Usage
Use this module when deploying LangGraph Server with custom authentication requirements. Create an `auth.py` file, instantiate `Auth()`, register your authenticate and authorize handlers, and reference the file in `langgraph.json` under `"auth": {"path": "./auth.py:my_auth"}`.
Code Reference
Source Location
- Repository: Langchain_ai_Langgraph
- File: libs/sdk-py/langgraph_sdk/auth/__init__.py
Signature
class Auth:
types = types # Reference to auth type definitions
exceptions = exceptions # Reference to auth exception definitions
def __init__(self) -> None: ...
def authenticate(self, fn: AH) -> AH:
"""Register the authentication handler. Raises ValueError if already set."""
...
# auth.on -- hierarchical authorization decorators
# auth.on(fn) -> global handler
# auth.on.threads(fn) -> all thread actions
# auth.on.threads.create(fn) -> thread create only
# auth.on.assistants / .crons / .store -> other resources
Import
from langgraph_sdk import Auth
I/O Contract
`@auth.authenticate` Handler
| Direction | Name | Type | Description |
|---|---|---|---|
| Input (injected) | authorization | None` | The `Authorization` header value |
| Input (injected) | path | `str` | The request path |
| Input (injected) | method | `str` | The HTTP method (GET, POST, etc.) |
| Input (injected) | headers | `dict[bytes, bytes]` | Raw request headers |
| Input (injected) | path_params | `dict[str, str]` | URL path parameters |
| Input (injected) | query_params | `dict[str, str]` | URL query parameters |
| Output | (return) | MinimalUserDict | BaseUser | MinimalUser` | User identity for downstream authorization |
`@auth.on` Authorization Handler
| Direction | Name | Type | Description |
|---|---|---|---|
| Input | ctx | `AuthContext` | Context with `user`, `permissions`, `resource`, and `action` |
| Input | value | `TypedDict` (varies) | Mutable request payload (e.g., `ThreadsCreate`, `RunsCreate`) |
| Output | (return) | bool | FilterType` | `None`/`True` = allow, `False` = deny (403), `FilterType` = apply filter |
Usage Examples
from langgraph_sdk import Auth
auth = Auth()
@auth.authenticate
async def authenticate(authorization: str) -> Auth.types.MinimalUserDict:
"""Verify a Bearer token and return user info."""
token = authorization.split(" ", 1)[1]
user = await verify_jwt(token)
return {
"identity": user["sub"],
"permissions": user.get("permissions", []),
"display_name": user.get("name"),
}
@auth.on
async def default_deny(ctx: Auth.types.AuthContext, value: dict) -> bool:
"""Deny all requests by default."""
return False
@auth.on.threads.create
async def allow_thread_create(
ctx: Auth.types.AuthContext,
value: Auth.on.threads.create.value,
) -> None:
"""Allow any authenticated user to create threads with owner metadata."""
value["metadata"] = value.get("metadata", {})
value["metadata"]["owner"] = ctx.user.identity
@auth.on.threads.read
async def filter_own_threads(
ctx: Auth.types.AuthContext,
value: Auth.on.threads.read.value,
) -> Auth.types.FilterType:
"""Only return threads owned by the current user."""
return {"metadata": {"owner": ctx.user.identity}}
@auth.on.store
async def restrict_store(
ctx: Auth.types.AuthContext,
value: dict,
) -> None:
"""Ensure the user can only access their own store namespace."""
assert value["namespace"][0] == ctx.user.identity, "Not authorized"