LangChain Tutorial (Python): adding authentication for advanced developers
This tutorial shows how to add authentication to a LangChain-based Python app so only approved users can access your LLM workflow. You need this when your chain is exposed through an API, internal tool, or agent endpoint and you want to enforce user identity before any prompt hits the model.
What You'll Need
- •Python 3.10+
- •
langchain,langchain-openai,fastapi,uvicorn,python-jose[cryptography] - •An OpenAI API key set as
OPENAI_API_KEY - •Basic familiarity with LangChain chains and FastAPI
- •A JWT secret for signing tokens, stored as
JWT_SECRET
Step-by-Step
- •Start with a minimal LangChain chain that can be called from an API route. Keep the chain simple first so you can focus on auth boundaries instead of application logic.
import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-4o-mini", api_key=os.environ["OPENAI_API_KEY"])
prompt = ChatPromptTemplate.from_messages([
("system", "You are a concise assistant."),
("human", "{question}")
])
chain = prompt | llm
- •Add JWT token creation and verification helpers. In production, these tokens usually come from your IdP, but this example keeps it local so you can run it end-to-end.
from datetime import datetime, timedelta, timezone
from jose import jwt, JWTError
JWT_SECRET = os.environ["JWT_SECRET"]
JWT_ALG = "HS256"
def create_token(sub: str) -> str:
payload = {
"sub": sub,
"exp": datetime.now(timezone.utc) + timedelta(minutes=30),
}
return jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALG)
def verify_token(token: str) -> dict:
try:
return jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALG])
except JWTError as exc:
raise ValueError("Invalid or expired token") from exc
- •Build a FastAPI dependency that extracts the bearer token from the request header. This is the enforcement point: no valid token, no chain execution.
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
app = FastAPI()
security = HTTPBearer()
def require_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> dict:
try:
claims = verify_token(credentials.credentials)
return claims
except ValueError as exc:
raise HTTPException(status_code=401, detail=str(exc))
@app.get("/token/{user_id}")
def issue_token(user_id: str):
return {"access_token": create_token(user_id)}
- •Wire authentication into the LangChain endpoint and pass user context into the prompt. That way your model output can be personalized or constrained by who is calling it.
from pydantic import BaseModel
class AskRequest(BaseModel):
question: str
@app.post("/ask")
async def ask(req: AskRequest, user: dict = Depends(require_user)):
result = await chain.ainvoke({
"question": f"User {user['sub']} asks: {req.question}"
})
return {
"user": user["sub"],
"answer": result.content,
}
- •Run the app and test both authenticated and unauthenticated requests. The important part is confirming that the chain never runs unless the request has a valid bearer token.
# save this as app.py and run:
# uvicorn app:app --reload
# Example client usage:
import requests
token = requests.get("http://127.0.0.1:8000/token/alice").json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}
response = requests.post(
"http://127.0.0.1:8000/ask",
json={"question": "What is our refund policy?"},
headers=headers,
)
print(response.status_code)
print(response.json())
Testing It
First hit /ask without an Authorization header; FastAPI should return 401 Unauthorized. Then fetch a token from /token/alice and retry the same request with Bearer <token>. If everything is wired correctly, the response should include the authenticated user ID and a model-generated answer.
Also test an expired or tampered token by changing one character in the JWT string. You should get a 401 before any LangChain call happens. That confirms auth is enforced at the boundary, not inside the prompt.
Next Steps
- •Replace the demo JWT issuer with your real identity provider using OIDC or SAML-backed access tokens.
- •Add role-based access control by checking claims like
roles,scope, ortenant_idbefore calling the chain. - •Log authenticated user IDs and request metadata into your audit trail for compliance and incident review.
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