Skip to main content
In the last tutorial, you added resource authorization to give users private conversations. However, you are still using hard-coded tokens for authentication, which is not secure. Now you’ll replace those tokens with real user accounts using OAuth2. You’ll keep the same Auth object and resource-level access control, but upgrade authentication to use Supabase as your identity provider. While Supabase is used in this tutorial, the concepts apply to any OAuth2 provider. You’ll learn how to:
  1. Replace test tokens with real JWT tokens
  2. Integrate with OAuth2 providers for secure user authentication
  3. Handle user sessions and metadata while maintaining our existing authorization logic

Background

OAuth2 involves three main roles:
  1. Authorization server: The identity provider (e.g., Supabase, Auth0, Google) that handles user authentication and issues tokens
  2. Application backend: Your LangGraph application. This validates tokens and serves protected resources (conversation data)
  3. Client application: The web or mobile app where users interact with your service
A standard OAuth2 flow works something like this:

Prerequisites

Before you start this tutorial, ensure you have:

1. Install dependencies

Install the required dependencies. Start in your custom-auth directory and ensure you have the langgraph-cli installed:

2. Set up the authentication provider

Next, fetch the URL of your auth server and the private key for authentication. Since you’re using Supabase for this, you can do this in the Supabase dashboard:
  1. In the left sidebar, click on t️⚙ Project Settings” and then click “API”
  2. Copy your project URL and add it to your .env file
  1. Copy your service role secret key and add it to your .env file:
  1. Copy your “anon public” key and note it down. This will be used later when you set up our client code.

3. Implement token validation

In the previous tutorials, you used the Auth object to validate hard-coded tokens and add resource ownership. Now you’ll upgrade your authentication to validate real JWT tokens from Supabase. The main changes will all be in the @auth.authenticate decorated function:
  • Instead of checking against a hard-coded list of tokens, you’ll make an HTTP request to Supabase to validate the token.
  • You’ll extract real user information (ID, email) from the validated token.
  • The existing resource authorization logic remains unchanged.
Update src/security/auth.py to implement this:
src/security/auth.py
The most important change is that we’re now validating tokens with a real authentication server. Our authentication handler has the private key for our Supabase project, which we can use to validate the user’s token and extract their information.

4. Test authentication flow

Let’s test out the new authentication flow. You can run the following code in a file or notebook. You will need to provide:
  • A valid email address
  • A Supabase project URL (from above)
  • A Supabase anon public key (also from above)
⚠️ Before continuing: Check your email and click both confirmation links. Supabase will reject /login requests until after you have confirmed your users’ email. Now test that users can only see their own data. Make sure the server is running (run langgraph dev) before proceeding. The following snippet requires the “anon public” key that you copied from the Supabase dashboard while setting up the auth provider previously.
The output should look like this:
Your authentication and authorization are working together:
  1. Users must log in to access the bot
  2. Each user can only see their own threads
All users are managed by the Supabase auth provider, so you don’t need to implement any additional user management logic.

Next steps

You’ve successfully built a production-ready authentication system for your LangGraph application! Let’s review what you’ve accomplished:
  1. Set up an authentication provider (Supabase in this case)
  2. Added real user accounts with email/password authentication
  3. Integrated JWT token validation into your Agent Server
  4. Implemented proper authorization to ensure users can only access their own data
  5. Created a foundation that’s ready to handle your next authentication challenge
Now that you have production authentication, consider:
  1. Building a web UI with your preferred framework (see the Custom Auth template for an example)
  2. Learn more about the other aspects of authentication and authorization in the conceptual guide on authentication.
  3. Customize your handlers and setup further after reading the reference docs.