This template implements access control in a LangGraph deployment using OAuth2 with Google, managing user information in Supabase. It combines a LangGraph backend with a React frontend to create a secure chatbot where users can only access their own conversation threads.
The application consists of two main components:
- Backend: A LangGraph Cloud deployment running a chatbot with custom authentication middleware
- Frontend: A React application using Supabase Auth for user management
There are two levels of checks in this template:
- Authentication: Verifies the identity of users (via Supabase JWT)
- Authorization: Controls what resources each user can access (threads, runs, etc.)
We present the end-to-end flow in more detail in Authentication Flow and Authorization Flow below.
We will use Supabase for authentication and enable a "Sign in with Google" button for users to sign in to your deployment. To get started, follow these steps (largely adapted from Login with Google):
- Create a new project at supabase.com
- Copy your project's URL, Service Key, and JWT secret from the project settings > API screen into your
.env
file. This will let your LangGraph backend connect to your Supabase project.
cp .env.example .env
and set the following environment variables:
SUPABASE_URL=https://abcd123456789.supabase.co
SUPABASE_SERVICE_KEY=
SUPABASE_JWT_SECRET=
- Copy your project's public Anon key and URL from the same screen into the .env file of the frontend folder. This will let your React frontend connect to your Supabase project.
cd app/supabase-react
REACT_APP_SUPABASE_URL=https://ynlkmijkhkvwcqnuillj.supabase.co
REACT_APP_SUPABASE_ANON_KEY=CHANGEME
- Enable google authentication by going to Authentication > Providers in your Supabase dashboard. Copy your
Callback URL (for OAuth)
to use for the next step. Leave this tab open for step 3.
To enable "Sign in with Google", follow these steps:
- Create a Google Cloud project at console.cloud.google.com
- Enable the Google OAuth2 API
- Create OAuth 2.0 credentials:
- Application type: Web application
- Name: Your app name
- Authorized JavaScript origins:
http://localhost:3000
(for local development)- Your production frontend URL (We will update this later)
- Authorized redirect URIs:
https://<YOUR_DOMAIN>.supabase.co/auth/v1/callback
(copied from the previous step)
- Save your Client ID and Client Secret
Now, switch back to the Supabase dashboard from step 1 above (in Authentication > Providers > Google) and: 5. Paste your Google Client ID and Client Secret from step 2 in the Google OAuth credentials
- Start the LangGraph backend:
Add an API key for your LLM provider (by default, ANTHROPIC_API_KEY) to your .env
file, and then
run the local backend server:
pip install -U "langgraph-cli[inmem]" && pip install -e .
langgraph dev
Or as a one liner (if you've installed uv):
uvx --from "langgraph-cli[inmem]" --with-editable . --python 3.11 langgraph dev
- Next, start the frontend:
cd app/supabase-react
npm run start
If you've completed the steps above, you will see a "Sign in with Google" button on the home page. Once you log in, you can chat with the LangGraph backend. If you sign in with a different account, you will only be able to see your own conversation threads.
Once you've gotten the server working locally, you can proceed to deployment.
- Push your code to GitHub
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/USERNAME/REPOSITORY.git
git push -u origin main
- Deploy the LangGraph backend by signing in at smith.langchain.com going to the "LangGraph Platform" page. Once you've connected your GitHub repository, you can deploy your repository to LangGraph. Copy the environment variables from your
.env
file in to the appropriate form.
Once the deployment is complete, copy the LangGraph deployment URL. We will use this as the the REACT_APP_DEPLOYMENT_URL
variable when deploying the frontend.
- Deploy the frontend (e.g., on Vercel). Sign in at vercel.com and connect your GitHub repository. Copy the environment variables from your
app/supabase-react/.env
file, making sure to include theREACT_APP_DEPLOYMENT_URL
variable. Then deploy the frontend.
Once the deployment is complete, copy the frontend URL and add it to the list of "Authorized JavaScript origins" in your Google OAuth credentials (from step 2 above).
Additionally, you must add your frontend URL to the list of "Authorized redirect URIs" in your Supabase dashboard (from step 1 above). This can be found in the "Authentication > URL Configuration" section.
Once you've completed the steps above, you should be good to go!
This template implements JWT Bearer token authentication:
- User navigates to the your frontend application
- Browser checks authentication state via the Supabase Auth Provider checks authentication state
- If not authenticated, user is signs in via:
- OAuth2 with Google
- Email/password authentication
- This sends a request to Supabase's authentication service:
- Creates a JWT containing user claims
- Signs it with your Supabase JWT secret
- Returns only the signed token to frontend
- Frontend then attaches the signed JWT as Bearer token to API requests to the LangGraph backend
- LangGraph backend then calls your authentication middleware (
auth.py
):- Verifies JWT signature
- Validates claims against Supabase Auth service using the project secret key
The secret key (SUPABASE_JWT_SECRET
) is only known to:
- Supabase's authentication servers
- Your LangGraph backend
After a user is authenticated, the backend enforces per-user resource isolation using the add_owner
handler in auth.py
.
This handler does two things:
- For resource creation or modification, it adds the authenticated user's identity as the
owner
in that resource's metadata. This ensures that we can filter resources based on user identity. - It returns a filter dictionary that enforces access control on all operations (create, read, update, delete) on the resource, so only the owner can access it.
This means that even if a user has a valid JWT tokena and obtains another user's thread ID, they cannot:
- View the thread's messages
- Add messages to the thread
- Delete or modify the thread
The authorization is enforced at the database level, not just in the UI, making it impossible to write scripts that bypass authorization.
The backend implements custom authentication middleware that:
- Validates JWT tokens against Supabase
- Associates user identity with resources
- Enforces access control on all operations (create, read, update, delete)
Key components:
get_current_user
: Validates JWT tokens and authenticates usersadd_owner
: Adds user identity to resource metadata- Resource filtering ensures users can only access their own data
The React frontend (app/supabase-react
) handles:
- User authentication state management
- JWT token management
- Secure API calls to the LangGraph backend
- Auth Providers: Configure additional OAuth providers in Supabase
- Access Control: Modify
add_owner
to implement custom access control logic - Resource Sharing: Extend the model to support shared resources between users
For more advanced features and examples, refer to:
LangGraph Studio integrates with LangSmith for debugging and monitoring your authenticated deployment.