LangGraph compiles a graph. It does not authenticate the HTTP caller. The auth boundary is the route that invokes the graph. require_auth runs before ainvoke. The graph reads the subject from state. It does not read the Authorization header.
Getting started, including the runnable sample, is LangGraph.
The route is the hook
authdog = Authdog(public_key=public_key)
compiled = build_graph()
@app.post("/invoke")
async def invoke(user=Depends(authdog.require_auth)):
result = await compiled.ainvoke(
{"subject": subject_of(user), "reply": ""}
)
return {"reply": result["reply"]}Authdog comes from authdog.fastapi. require_auth is a FastAPI dependency, so a missing or rejected token never enters invoke. subject_of reads id, then sub, from the userinfo user.
Call graph.invoke or ainvoke only from a route that already depends on require_auth. A second route that invokes the compiled graph directly skips Authdog. This sample has one route.
The process that serves the graph holds PK_AUTHDOG. It does not hold AUTHDOG_CLIENT_SECRET. The caller mints the bearer elsewhere. See API keys and M2M for LangGraph.
What you should see
POST /invoke with no token returns 401. The body does not contain subject:. The same call with a bearer userinfo accepts returns {"reply":"subject:<id>"}.
Related
| Read | To learn how to |
|---|---|
| LangGraph | Run the sample |
| API keys and M2M for LangGraph | Mint the bearer the route expects |
| Authorizing tool calls for LangGraph | Stop a node the subject may not run |
| Enriching instructions for LangGraph | Pass the subject in state |