Aegra supports flexible authentication through configurable auth handlers. You write a Python function that verifies credentials and returns user data — Aegra handles the rest.Documentation Index
Fetch the complete documentation index at: https://docs.aegra.dev/llms.txt
Use this file to discover all available pages before exploring further.
Quick setup
The authenticate handler
The@auth.authenticate decorator registers your authentication function. It receives the request headers and must return a dictionary with user data.
Required fields
| Field | Type | Description |
|---|---|---|
identity | string | Unique user identifier |
Optional fields
| Field | Type | Default | Description |
|---|---|---|---|
display_name | string | Same as identity | Display name |
permissions | list[str] | [] | Permission strings |
is_authenticated | bool | True | Authentication status |
role, team_id, etc.) are preserved and accessible via ctx.user in authorization handlers and via the User model in custom routes.
Denying access
Raise any exception to deny authentication:Authorization handlers
Authorization handlers give you fine-grained access control for specific resources and actions.Handler types
Handlers can:- Allow — Return
NoneorTrue(default behavior) - Deny — Return
False(returns 403 Forbidden) - Filter — Return a dictionary with filters to apply to queries
- Modify — Modify the
valuedict (e.g., inject metadata)
Resolution priority
Handlers are matched from most specific to least specific:@auth.on.threads.create— Resource + action@auth.on.threads— Resource only@auth.on.*.create— Action only@auth.on— Global fallback
Examples
Restrict deletion to admins:Handler context
Thectx parameter provides:
ctx.user— Authenticated user object (with all fields you returned fromauthenticate)ctx.resource— Resource name ("threads","assistants", etc.)ctx.action— Action name ("create","read","update","delete","search")ctx.permissions— User permissions list
Return values
| Return | Behavior |
|---|---|
None or True | Allow the request |
False | Deny with 403 Forbidden |
dict | Allow with filters (e.g., {"metadata": {"team_id": "123"}}) |
Modified value | Allow with modified request data |
Accessing user data in your graph
When auth is enabled, Aegra automatically injects the authenticated user’s data intoconfig["configurable"]["langgraph_auth_user"] before graph execution. This happens
server-side, so the client cannot tamper with it.
This works with all graph types: custom StateGraph graphs, create_react_agent,
create_agent, or any compiled graph.
From tools
- InjectedToolArg (recommended)
- ToolRuntime
InjectedToolArg tells the LLM to ignore this parameter (it won’t try to fill it).
Aegra injects the config automatically at runtime.From graph nodes
Graph nodes can accept aconfig: RunnableConfig parameter. Aegra injects
the authenticated user into config["configurable"]["langgraph_auth_user"]
before the graph executes:
The
Runtime object (from get_runtime()) does not include config.
To access config from nodes, add a config: RunnableConfig parameter to
your node function. In tools, use InjectedToolArg or ToolRuntime instead.From factory graphs
Factory graphs receive aServerRuntime
object that includes runtime.user with the authenticated user’s data. This is
available at factory time (when deciding graph structure) before the graph executes:
runtime.user object is the full User model with all fields from your
@auth.authenticate handler. Standard fields (identity, display_name,
permissions) and custom fields (role, team_id, etc.) are all accessible
as attributes or via dict-style access:
Factory graphs get user data in two places:
- Factory time (
runtime.useronServerRuntime): for structural decisions like which tools to include, which nodes to add, or which model to use. - Execution time (
config["configurable"]["langgraph_auth_user"]): available inside nodes and tools during the actual graph run (same as static graphs).
Available fields
Thelanggraph_auth_user dict contains everything your @auth.authenticate
handler returns, including any custom fields:
config["configurable"]:
config["configurable"]["user_id"]— the user’s identityconfig["configurable"]["user_display_name"]— the user’s display name
Provider examples
- JWT
- OAuth
- Firebase
Auth on custom routes
Custom routes can use authentication via therequire_auth dependency:
enable_custom_route_auth in your config:
No-auth mode
If no auth is configured, Aegra runs in no-auth mode:- All requests are allowed
- User is set to
anonymous - Authorization handlers are not called
Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
auth.path | string | — | Import path to your auth handler (./file.py:variable) |
auth.disable_studio_auth | bool | false | Disable auth for LangGraph Studio connections |
Non-interruptive design
Authorization handlers are additive by default:- If no auth is configured, requests are allowed
- If no handlers are defined, requests are allowed
- Handlers only restrict access when they explicitly deny