MastraAuthBetterAuth Class
The MastraAuthBetterAuth class provides authentication for Mastra using Better Auth. It verifies incoming requests using your Better Auth instance and integrates with the Mastra server via the server.auth option.
PrerequisitesDirect link to Prerequisites
This example uses Better Auth. Make sure your Better Auth instance is configured and your environment variables are set.
# Required by Better Auth
BETTER_AUTH_SECRET=... # at least 32 chars
BETTER_AUTH_URL=http://localhost:3000
# Example DB URL used by the snippet below (adjust for your setup)
DATABASE_URL=postgres://...
Better Auth recommends setting baseURL explicitly (or via BETTER_AUTH_URL) for security and stability.
If you haven't mounted Better Auth's handler yet (so your app can sign users in / create sessions), follow the Better Auth installation guide to mount the /api/auth/* route (or your configured base path).
InstallationDirect link to Installation
Install the @mastra/auth-better-auth package:
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/auth-better-auth
pnpm add @mastra/auth-better-auth
yarn add @mastra/auth-better-auth
bun add @mastra/auth-better-auth
Usage exampleDirect link to Usage example
First, create your Better Auth instance:
import { betterAuth } from "better-auth";
export const auth = betterAuth({
database: {
provider: "postgresql",
url: process.env.DATABASE_URL!,
},
emailAndPassword: {
enabled: true,
},
baseURL: process.env.BETTER_AUTH_URL,
secret: process.env.BETTER_AUTH_SECRET,
});
Then, use it with Mastra:
import { Mastra } from "@mastra/core";
import { MastraAuthBetterAuth } from "@mastra/auth-better-auth";
import { auth } from "@/lib/auth";
const mastraAuth = new MastraAuthBetterAuth({
auth,
});
export const mastra = new Mastra({
server: {
auth: mastraAuth,
},
});
Visit MastraAuthBetterAuth for all available configuration options.
Custom authorizationDirect link to Custom authorization
const mastraAuth = new MastraAuthBetterAuth({
auth,
async authorizeUser(user) {
// Example: only allow verified emails
return user?.user?.emailVerified === true;
},
});
Route configurationDirect link to Route configuration
const mastraAuth = new MastraAuthBetterAuth({
auth,
public: ["/health", "/api/status"],
protected: ["/api/*", "/admin/*"],
});
Matching rulesDirect link to Matching rules
publicandprotectedaccept exact paths, wildcard patterns (like/api/*), and path params (like/users/:id).- For method-specific rules, use tuples like
["/api/agents", ["GET", "POST"]]. - If a route matches both
publicandprotected,publicwins and no auth is required. - If neither matches, routes are treated as protected by default (unless a route is explicitly marked
requiresAuth: false).
Client-side setupDirect link to Client-side setup
When auth is enabled, requests to Mastra's built-in routes require authentication. In practice, that means your client needs to send whatever credential your Better Auth setup uses for authenticated requests.
Cookie session (recommended)Direct link to Cookie session (recommended)
If your Better Auth setup uses cookies, configure the client to send credentials and ensure your Mastra server CORS allows credentials for cross-origin requests.
import { MastraClient } from "@mastra/client-js";
export const mastraClient = new MastraClient({
baseUrl: "http://localhost:4111",
credentials: "include",
});
If you are calling the API directly, include credentials in fetch as well:
await fetch("http://localhost:4111/api/agents/weatherAgent/generate", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify({ messages: "Weather in London" }),
});
Bearer tokenDirect link to Bearer token
If your Better Auth setup issues bearer tokens, include them in the Authorization header:
import { MastraClient } from "@mastra/client-js";
export const mastraClient = new MastraClient({
baseUrl: "http://localhost:4111",
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
Visit Mastra Client SDK for more configuration options.
Making authenticated requestsDirect link to Making authenticated requests
- React
- cURL
import { mastraClient } from "../lib/mastra-client";
export const TestAgent = () => {
async function handleClick() {
const agent = mastraClient.getAgent("weatherAgent");
const response = await agent.generate("Weather in London");
console.log(response);
}
return <button onClick={handleClick}>Test Agent</button>;
};
curl -X POST http://localhost:4111/api/agents/weatherAgent/generate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-token>" \
-d '{
"messages": "Weather in London"
}'
TroubleshootingDirect link to Troubleshooting
- 401/403 on every request: confirm your Better Auth handler is mounted and your app can create a valid session/token.
- Cookies not sent: set
credentials: "include"inMastraClientand enable CORS credentials on the Mastra server. - Authorization header missing: ensure the client attaches
Authorization: Bearer <token>when using bearer tokens. - Base URL issues: set
baseURLinbetterAuth({ ... })or setBETTER_AUTH_URL. - DB connection errors: verify
DATABASE_URLand database provider configuration.