LangGraph Tutorial (Python): adding authentication for beginners
This tutorial shows how to add a simple authentication gate to a LangGraph app in Python so only approved users can run the graph. You need this when your agent exposes sensitive actions, private data, or internal tools that should not be callable by anyone who can hit the endpoint.
What You'll Need
- •Python 3.10+
- •
langgraph - •
langchain-core - •
fastapi - •
uvicorn - •
pydantic - •A basic LangGraph project already set up
- •An API key or token source for your auth check, if you want to validate against a real identity provider later
Install the packages:
pip install langgraph langchain-core fastapi uvicorn pydantic
Step-by-Step
- •Create a tiny graph that expects an authenticated user in the state.
The key idea is simple: auth happens before the graph runs, and the user identity gets passed into the graph state.
from typing import TypedDict
from langgraph.graph import StateGraph, END
class GraphState(TypedDict):
user_id: str
message: str
response: str
def respond(state: GraphState) -> GraphState:
state["response"] = f"Hello {state['user_id']}, you said: {state['message']}"
return state
builder = StateGraph(GraphState)
builder.add_node("respond", respond)
builder.set_entry_point("respond")
builder.add_edge("respond", END)
graph = builder.compile()
- •Add a small authentication function.
For beginners, start with an API key check from the request header. In production you would replace this with JWT verification, OAuth, or your internal identity service.
from fastapi import Header, HTTPException
API_KEY = "dev-secret-key"
def authenticate(x_api_key: str | None) -> str:
if not x_api_key:
raise HTTPException(status_code=401, detail="Missing API key")
if x_api_key != API_KEY:
raise HTTPException(status_code=403, detail="Invalid API key")
return "user_123"
- •Wrap the graph behind a FastAPI endpoint.
The endpoint authenticates first, then injects the authenticateduser_idinto the LangGraph input. This keeps auth outside the graph logic, which is cleaner and easier to test.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class ChatRequest(BaseModel):
message: str
@app.post("/chat")
def chat(request: ChatRequest, x_api_key: str | None = Header(default=None)):
user_id = authenticate(x_api_key)
result = graph.invoke(
{
"user_id": user_id,
"message": request.message,
"response": "",
}
)
return {"response": result["response"]}
- •Add role-based checks if different users should access different actions.
Once you have identity, you can enforce authorization rules before calling specific nodes or branches in your graph.
def authorize(user_id: str) -> None:
allowed_users = {"user_123", "admin_001"}
if user_id not in allowed_users:
raise HTTPException(status_code=403, detail="Not allowed")
@app.post("/secure-chat")
def secure_chat(request: ChatRequest, x_api_key: str | None = Header(default=None)):
user_id = authenticate(x_api_key)
authorize(user_id)
result = graph.invoke(
{
"user_id": user_id,
"message": request.message,
"response": "",
}
)
return {"response": result["response"]}
- •Run the app and test it with curl.
This verifies that unauthenticated requests fail and valid requests reach the graph.
uvicorn app:app --reload
curl -X POST http://127.0.0.1:8000/chat \
-H "Content-Type: application/json" \
-H "x-api-key: dev-secret-key" \
-d '{"message":"Hello"}'
Testing It
Start by sending a request without the x-api-key header. You should get a 401 Missing API key response.
Then send one with the wrong key and confirm you get 403 Invalid API key. Finally, send a request with dev-secret-key and verify that the response includes the authenticated user_id.
If you want to test authorization too, call /secure-chat with a valid but unauthorized identity after changing authenticate() to return a different user ID. That should fail at the authorization step before any LangGraph node runs.
Next Steps
- •Replace the static API key check with JWT verification using your identity provider
- •Move auth logic into FastAPI dependencies so it can be reused across endpoints
- •Add per-node authorization checks when some tools or branches require higher privileges
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit