Skip to main content
Auth0 provides enterprise-grade authentication and authorization with support for social logins, enterprise connections, and custom identity providers.

Installation

npm install @mastra/auth-auth0

Configuration

1

Create Auth0 Application

Sign up at Auth0 and create an API application. Get your:
  • Domain (e.g., your-tenant.us.auth0.com)
  • API Identifier (Audience)
2

Set Environment Variables

.env
AUTH0_DOMAIN=your-tenant.us.auth0.com
AUTH0_AUDIENCE=https://your-api.com
3

Import and Configure

import { MastraAuthAuth0 } from '@mastra/auth-auth0';
import { Mastra } from '@mastra/core';

const auth = new MastraAuthAuth0();

const mastra = new Mastra({
  server: {
    auth,
  },
});

Configuration Options

domain
string
required
Auth0 domain. Defaults to process.env.AUTH0_DOMAIN
audience
string
required
Auth0 API identifier. Defaults to process.env.AUTH0_AUDIENCE
name
string
default:"auth0"
Provider name identifier

Usage Examples

Basic Setup

import { Mastra } from '@mastra/core';
import { MastraAuthAuth0 } from '@mastra/auth-auth0';
import { MastraServer } from '@mastra/hono';
import { Hono } from 'hono';

const mastra = new Mastra({
  server: {
    auth: new MastraAuthAuth0(),
  },
});

const app = new Hono();
const server = new MastraServer({ mastra, app });

Explicit Configuration

const auth = new MastraAuthAuth0({
  domain: 'your-tenant.us.auth0.com',
  audience: 'https://your-api.com',
  name: 'auth0-provider',
});

const mastra = new Mastra({
  server: {
    auth,
  },
});

Custom Authorization

const auth = new MastraAuthAuth0({
  authorizeUser: async (user) => {
    // Check token expiration
    if (user.exp && user.exp * 1000 < Date.now()) {
      return false;
    }

    // Check custom claims
    const permissions = user['https://your-app.com/permissions'] || [];
    return permissions.includes('api:access');
  },
});

const mastra = new Mastra({
  server: {
    auth,
  },
});

Client Integration

React with Auth0

import { Auth0Provider, useAuth0 } from '@auth0/auth0-react';

export default function App() {
  return (
    <Auth0Provider
      domain="your-tenant.us.auth0.com"
      clientId="your-client-id"
      authorizationParams={{
        redirect_uri: window.location.origin,
        audience: 'https://your-api.com',
      }}
    >
      <MyApp />
    </Auth0Provider>
  );
}

function MyApp() {
  const { isAuthenticated, loginWithRedirect, logout, user } = useAuth0();

  if (!isAuthenticated) {
    return <button onClick={() => loginWithRedirect()}>Log in</button>;
  }

  return (
    <div>
      <p>Welcome {user?.name}</p>
      <button onClick={() => logout()}>Log out</button>
      <MyMastraComponent />
    </div>
  );
}

Making Authenticated Requests

import { useAuth0 } from '@auth0/auth0-react';

function MyMastraComponent() {
  const { getAccessTokenSilently } = useAuth0();

  const callMastraAPI = async () => {
    const token = await getAccessTokenSilently({
      authorizationParams: {
        audience: 'https://your-api.com',
      },
    });

    const response = await fetch('http://localhost:4111/api/mastra/agents', {
      headers: {
        'Authorization': `Bearer ${token}`,
      },
    });

    const data = await response.json();
    console.log(data);
  };

  return <button onClick={callMastraAPI}>Call Mastra</button>;
}

Token Verification

Mastra automatically verifies Auth0 JWT tokens:
  1. Token Extraction: Bearer token from Authorization header
  2. JWKS Verification: Validates signature using Auth0’s JWKS endpoint
  3. Issuer Validation: Checks token issuer matches your domain
  4. Audience Validation: Verifies audience matches your API identifier
  5. Expiration Check: Ensures token is not expired

User Object

The authenticated user object contains JWT claims:
interface Auth0User {
  sub: string; // User ID (e.g., 'auth0|123456')
  iss: string; // Issuer (https://your-domain.auth0.com/)
  aud: string; // Audience
  exp: number; // Expiration timestamp
  iat: number; // Issued at timestamp
  azp?: string; // Authorized party (client ID)
  scope?: string; // Granted scopes
  // Custom claims with namespace
  'https://your-app.com/roles'?: string[];
  'https://your-app.com/permissions'?: string[];
}

Custom Claims

Add custom claims using Auth0 Actions:
// Auth0 Action: Add custom claims
exports.onExecutePostLogin = async (event, api) => {
  const namespace = 'https://your-app.com';
  
  api.accessToken.setCustomClaim(`${namespace}/roles`, event.user.app_metadata.roles || []);
  api.accessToken.setCustomClaim(`${namespace}/permissions`, event.user.app_metadata.permissions || []);
};
Access in authorization:
const auth = new MastraAuthAuth0({
  authorizeUser: async (user) => {
    const roles = user['https://your-app.com/roles'] || [];
    return roles.includes('admin') || roles.includes('user');
  },
});

Authentication Flow

Best Practices

Use API Identifier

Always specify an audience (API identifier) to get access tokens, not ID tokens.

Namespace Custom Claims

Use namespaced URLs for custom claims to avoid conflicts:
'https://your-app.com/roles'

Scope Management

Define and check scopes for fine-grained permissions:
scope: 'read:agents write:workflows'

Token Expiration

Configure appropriate token lifetimes in Auth0 Dashboard:
  • Access tokens: 1-24 hours
  • Refresh tokens: 7-30 days

Auth0 Features

Authentication Methods

  • Username/password
  • Social logins (Google, GitHub, etc.)
  • Enterprise connections (SAML, AD)
  • Passwordless (email, SMS)
  • Multi-factor authentication

Advanced Features

  • Actions: Customize authentication flow
  • Rules: Legacy custom logic
  • Organizations: Multi-tenant B2B support
  • RBAC: Role-based access control
  • Attack Protection: Brute force & bot detection

Troubleshooting

Invalid Audience

Ensure your API is registered in Auth0 and the audience matches:
audience: 'https://your-api.com' // Must match API identifier

CORS Errors

Add your application URL to Auth0 Dashboard:
  • Allowed Callback URLs
  • Allowed Logout URLs
  • Allowed Web Origins

Token Verification Failed

Check that:
  1. Domain is correct (no https:// prefix)
  2. Token includes required audience
  3. Token is not expired

Clerk

Modern user management alternative

better-auth

Self-hosted authentication framework

Auth0 Docs

Official Auth0 documentation

Auth0 Dashboard

Manage applications and APIs

Build docs developers (and LLMs) love