Studio auth
When you configure authentication on your Mastra server, Studio automatically displays a login screen and enforces access control. One configuration secures both the Studio UI and your API routes.
Without authentication, Studio and all API routes are publicly accessible.
In production, the Studio sign-in screen with a third-party provider, role-based access control (RBAC), and fine-grained authorization (FGA) require a Mastra Enterprise Edition (EE) license. Simple Auth, JWT, and authentication on API routes don't. Every feature works without a license in development. See what requires an EE license. Contact sales for more information.
Studio deployed on Mastra platform works differently. By default, the platform injects its own auth so only your organization members can sign in, and your server.auth applies to API routes only. Set MASTRA_PLATFORM_STUDIO_AUTH=disabled to opt out. See Authentication on Mastra platform.
When to use Studio AuthDirect link to When to use Studio Auth
- Multiple team members need to interact with agents, workflows, and tools through a shared Studio deployment.
- Permissions must restrict who can execute agents or edit workflows, or alternatively delete datasets.
- A login screen (SSO, email/password, or both) should gate access to your Studio deployment.
QuickstartDirect link to Quickstart
Add an auth provider to your Mastra server configuration. This example uses Simple Auth for a minimal setup:
import { Mastra } from '@mastra/core'
import { SimpleAuth } from '@mastra/core/server'
export const mastra = new Mastra({
server: {
auth: new SimpleAuth({
tokens: {
'my-api-key': {
id: 'user-1',
name: 'Alice',
role: 'admin',
},
},
}),
},
})
Once configured, Studio shows a login screen and requires authentication for all API requests. Visit the Auth docs for a full list of supported providers.
How it worksDirect link to How it works
Setting server.auth does two things at once:
- Studio UI: Displays a login screen. Depending on the provider, users sign in through SSO, email/password, or both.
- API routes: Requires authentication for all built-in routes (
/api/agents/*,/api/workflows/*, etc.) and custom routes. This applies whether requests come from Studio or direct API calls.
Studio detects available capabilities by calling the GET /api/auth/capabilities endpoint. The response tells Studio which login methods to render and, if the user is already authenticated, includes their user info and permissions.
Pass a token through the URLDirect link to Pass a token through the URL
When another application embeds or links to Studio, it can hand over an authorization token through the auth_header URL parameter. This is useful when an external host already holds a token and wants to open an authenticated Studio session without showing the login screen.
The auth_header value always populates the Authorization request header. The parameter sets that one header only, so include any scheme prefix the server expects in the value, such as Bearer.
Open Studio with the token in the query string:
https://your-studio-host/?auth_header=Bearer%20your-token
Studio handles the token as follows:
- It reads
auth_headeronce on load and sends the value as theAuthorizationheader on every API request in that session. - It removes
auth_headerfrom the address bar while preserving other query parameters and the hash. - It keeps the token in memory only and never writes it to local storage, so it doesn't persist across page reloads.
The token rides in a URL parameter, so the host application is responsible for how that URL is generated and transmitted. URL parameters can be exposed through browser history and referrer headers, plus server access logs.
Role-based access controlDirect link to Role-based access control
RBAC lets you control what each user can see and do inside Studio. It's separate from authentication: server.auth handles who the user is, while server.rbac handles what they can do.
Default rolesDirect link to Default roles
Mastra includes four default roles. Import them from @mastra/core/auth/ee:
| Role | Permissions |
|---|---|
owner | Full access (*) |
admin | Read, write, execute, publish, and share (no delete) |
member | Read and execute |
viewer | Read-only |
Enable RBACDirect link to Enable RBAC
Use StaticRBACProvider with the default roles or define your own:
import { Mastra } from '@mastra/core'
import { SimpleAuth } from '@mastra/core/server'
import { StaticRBACProvider, DEFAULT_ROLES } from '@mastra/core/auth/ee'
export const mastra = new Mastra({
server: {
auth: new SimpleAuth({
tokens: {
'admin-key': { id: 'user-1', name: 'Alice', role: 'admin' },
'viewer-key': { id: 'user-2', name: 'Bob', role: 'viewer' },
},
}),
rbac: new StaticRBACProvider({
roles: DEFAULT_ROLES,
getUserRoles: user => [user.role],
}),
},
})
When RBAC is active, Studio hides actions the user doesn't have permission for. A viewer doesn't see delete buttons. A member can't modify agent configurations.
Permission formatDirect link to Permission format
Permissions follow the pattern {resource}:{action}, with optional resource-level scoping:
| Pattern | Meaning |
|---|---|
* | Full access to everything |
*:read | Read all resources |
agents:* | All actions on agents |
agents:execute | Execute agents only |
agents:read:my-id | Read a specific agent by ID |
Resources include agents, workflows, tools, datasets, memory, scores, observability, stored-agents, mcp, and others. Actions are read, write, create, delete, execute, publish, and share.
mcp:read and mcp:execute gate the built-in MCP server and the routes of MCPServer instances you register. The default viewer role has mcp:read only, so a viewer can connect but gets an empty tool list. Each MCP tool call also needs the permission of the route it runs, such as agents:execute.
Stored agents are private to their owner by default. stored-agents:* lets a user see and edit every stored agent. stored-agents:admin lifts the owner check, but the user still needs each route's own permission, such as stored-agents:read or stored-agents:write. The default admin role doesn't include either. See stored agent visibility.
Map external provider rolesDirect link to Map external provider roles
If your identity provider already defines roles (for example, Clerk organizations or WorkOS groups), map them to Mastra permissions with roleMapping:
import { StaticRBACProvider } from '@mastra/core/auth/ee'
const rbac = new StaticRBACProvider({
roleMapping: {
'org:admin': ['*'],
'org:member': ['*:read', '*:execute'],
'org:viewer': ['*:read'],
},
getUserRoles: user => user.providerRoles,
})
Login methodsDirect link to Login methods
Studio adapts its login screen based on the auth provider:
| Provider type | Login UI |
|---|---|
| SSO only | SSO button (e.g. "Sign in with WorkOS") |
| Credentials only | Email and password form |
| Both | SSO button and email/password form |
Sign-up can be enabled or disabled per provider. When disabled, Studio hides the sign-up link and forces the sign-in form.
RelatedDirect link to Related
- Auth overview: Full list of supported auth providers.
- Studio deployment: Deploy Studio to production.
- Custom API routes: Control authentication on individual endpoints.