@auth.authenticate
handler, and authorization is handled by your @auth.on
handlers.
x-api-key
header@auth.authenticate
handler in LangGraph handles steps 4-6, while your @auth.on
handlers implement step 7.
@auth.authenticate
handler receives request information and should:
ctx.user
config["configuration"]["langgraph_auth_user"]
Supported Parameters
@auth.authenticate
handler can accept any of the following parameters by name:"/threads/abcd-1234-abcd-1234/runs/abcd-1234-abcd-1234/stream"
"GET"
{"thread_id": "abcd-1234-abcd-1234", "run_id": "abcd-1234-abcd-1234"}
{"stream": "true"}
"Bearer <token>"
)@auth.authenticate
are added to the run context, giving agents user-scoped credentials lets them access resources on the user’s behalf.
After authentication, the platform creates a special configuration object that is passed to your graph and all nodes via the configurable context.
This object contains information about the current user, including any custom fields you return from your @auth.authenticate
handler.
To enable an agent to act on behalf of the user, use custom authentication middleware. This will allow the agent to interact with external systems like MCP servers, external databases, and even other agents on behalf of the user.
For more information, see the Use custom auth guide.
@auth.on
handlers to control access to specific resources (e.g., threads, assistants, crons). These handlers can:
value["metadata"]
dictionary directly. See the supported actions table for the list of types the value can take for each action.@auth.on
handler for all resources and actions. If you want to have different control depending on the resource and action, you can use resource-specific handlers. See the Supported Resources section for a full list of the resources that support access control.
@auth.on
decorator.
When a request is made, the most specific handler that matches that resource and action is called. Below is an example of how to register handlers for specific resources and actions. For the following setup:
thread
would match the on_thread_create
handler but NOT the reject_unhandled_requests
handler. A request to update
a thread, however would be handled by the global handler, since we don’t have a more specific handler for that resource and action.
None
, a boolean, or a filter dictionary.
None
and True
mean “authorize access to all underling resources”False
means “deny access to all underling resources (raises a 403 exception)”{"owner": user_id}
will include only resources with metadata containing {"owner": user_id}
$eq
: Exact match (e.g., {"owner": {"$eq": user_id}}
) - this is equivalent to the shorthand above, {"owner": user_id}
$contains
: List membership (e.g., {"allowed_users": {"$contains": user_id}}
) The value here must be an element of the list. The metadata in the stored resource must be a list/container type.AND
filter. For example, {"owner": org_id, "allowed_users": {"$contains": user_id}}
will only match resources with metadata whose “owner” is org_id
and whose “allowed_users” list contains user_id
.
See the reference here for more information.
@auth.on
): Matches all resources and actions@auth.on.threads
, @auth.on.assistants
, @auth.on.crons
): Matches all actions for a specific resource@auth.on.threads.create
, @auth.on.threads.read
): Matches a specific action on a specific resource@auth.on.threads.create
takes precedence over @auth.on.threads
for thread creation.
If a more specific handler is registered, the more general handler will not be called for that resource and action.
value
parameter at Auth.types.on.<resource>.<action>.value
. For example:Resource | Handler | Description | Value Type |
---|---|---|---|
Threads | @auth.on.threads.create | Thread creation | ThreadsCreate |
@auth.on.threads.read | Thread retrieval | ThreadsRead | |
@auth.on.threads.update | Thread updates | ThreadsUpdate | |
@auth.on.threads.delete | Thread deletion | ThreadsDelete | |
@auth.on.threads.search | Listing threads | ThreadsSearch | |
@auth.on.threads.create_run | Creating or updating a run | RunsCreate | |
Assistants | @auth.on.assistants.create | Assistant creation | AssistantsCreate |
@auth.on.assistants.read | Assistant retrieval | AssistantsRead | |
@auth.on.assistants.update | Assistant updates | AssistantsUpdate | |
@auth.on.assistants.delete | Assistant deletion | AssistantsDelete | |
@auth.on.assistants.search | Listing assistants | AssistantsSearch | |
Crons | @auth.on.crons.create | Cron job creation | CronsCreate |
@auth.on.crons.read | Cron job retrieval | CronsRead | |
@auth.on.crons.update | Cron job updates | CronsUpdate | |
@auth.on.crons.delete | Cron job deletion | CronsDelete | |
@auth.on.crons.search | Listing cron jobs | CronsSearch |
create_run
handler for creating new runs because it had more arguments that you can view in the handler.