Problem Statement
Mastra has 9 auth providers (Auth0, Clerk, Firebase, Okta, Supabase, WorkOS, etc.) — all designed for human users authenticating via browser sessions, OAuth flows, or human-issued JWTs. None address agent-to-agent authentication: an autonomous agent calling your Mastra-powered API, proving its identity, and being authorized based on behavioral trust rather than static credentials.
As agentic architectures become production-critical, the auth model shifts. An agent calling your API doesn't have a browser session or an OAuth redirect URI. It presents a cryptographically signed token asserting its identity, issued by an agent identity provider. The question isn't "which human authorized this request?" — it's "which agent is this, and should I trust it?"
Today, there's no way to express this in Mastra's auth system without building it from scratch.
Proposed Solution
Add @mastra/auth-agentlair — an auth provider that verifies agent identity tokens issued by AgentLair, following the same pattern as @mastra/auth-auth0.
AgentLair issues EdDSA-signed JWTs (Agent Authentication Tokens) verifiable via a standard JWKS endpoint at https://agentlair.dev/.well-known/jwks.json. The @mastra/auth package already exports verifyJwks(), and existing providers (Auth0, WorkOS) already use jose's createRemoteJWKSet + jwtVerify — the same pattern works here.
Auth provider (~50 lines):
import { MastraAuthProvider, type MastraAuthProviderOptions } from '@mastra/auth';
import { createRemoteJWKSet, jwtVerify, type JWTPayload } from 'jose';
export interface AgentLairUser {
agentId: string;
iss: string;
trustScore?: number; // 0-1000, from AgentLair behavioral trust API
}
export interface AgentLairAuthOptions extends MastraAuthProviderOptions<AgentLairUser> {
jwksUrl?: string; // Default: https://agentlair.dev/.well-known/jwks.json
issuer?: string; // Expected issuer claim
requiredTrustScore?: number; // Minimum behavioral trust score (0-1000)
}
export class MastraAuthAgentLair extends MastraAuthProvider<AgentLairUser> {
private jwks: ReturnType<typeof createRemoteJWKSet>;
private issuer?: string;
private requiredTrustScore: number;
constructor(options: AgentLairAuthOptions = {}) {
super({ name: 'agentlair', ...options });
this.jwks = createRemoteJWKSet(
new URL(options.jwksUrl ?? 'https://agentlair.dev/.well-known/jwks.json')
);
this.issuer = options.issuer;
this.requiredTrustScore = options.requiredTrustScore ?? 0;
}
async authenticateToken(token: string): Promise<AgentLairUser | null> {
try {
const { payload } = await jwtVerify(token, this.jwks, {
issuer: this.issuer,
algorithms: ['EdDSA'],
});
return {
agentId: payload.sub!,
iss: payload.iss!,
trustScore: (payload as any).trust_score,
};
} catch {
return null;
}
}
async authorizeUser(user: AgentLairUser): Promise<boolean> {
if (this.requiredTrustScore > 0 && (user.trustScore ?? 0) < this.requiredTrustScore) {
return false;
}
return true;
}
}
Configuration:
const mastra = new Mastra({
server: {
auth: new MastraAuthAgentLair({
requiredTrustScore: 500, // Only trust agents with score >= 500
}),
},
});
Optional RBAC provider — maps behavioral trust tiers to Mastra roles:
export class MastraRBACAgentLair implements IRBACProvider<AgentLairUser> {
constructor(private config: {
tierMapping: Record<string, { minScore: number; permissions: string[] }>;
}) {}
async getRoles(user: AgentLairUser): Promise<string[]> {
const score = user.trustScore ?? 0;
return Object.entries(this.config.tierMapping)
.filter(([_, tier]) => score >= tier.minScore)
.map(([role]) => role);
}
// ... hasRole, getPermissions, etc.
}
This enables trust-tiered agent access:
server: {
auth: new MastraAuthAgentLair(),
rbac: new MastraRBACAgentLair({
tierMapping: {
'agent:untrusted': { minScore: 0, permissions: ['agents:read'] },
'agent:verified': { minScore: 500, permissions: ['agents:read', 'agents:execute'] },
'agent:trusted': { minScore: 800, permissions: ['agents:*', 'workflows:*', 'memory:read'] },
},
}),
}
Component
Integrations, Agents
Alternatives Considered
- API keys / static tokens: No identity semantics. Can't revoke per-agent, can't differentiate trust levels. Doesn't answer "who is this agent?"
- Reusing a human auth provider (Auth0/Clerk) for agents: Technically works for token verification, but the user model is wrong — agents don't have emails, profiles, or org memberships. Trust is behavioral, not declarative.
- External middleware: Possible today, but auth providers exist precisely to avoid this. Mastra's
MastraAuthProvider abstraction handles token verification, user resolution, and route protection in one place.
Example Use Case
Multi-agent system where external agents consume your Mastra-powered API:
- Agent marketplace: You expose agents via Mastra. Third-party agents call your API. You need to verify their identity and authorize based on behavioral reputation, not just a shared API key.
- Cross-org agent orchestration: Your company's agents call a partner's Mastra deployment. Both sides verify agent identity via AgentLair's JWKS, with trust scores gating access to sensitive workflows.
- Trust-gated tool access: An agent with a low trust score can read agent metadata, but only agents with verified behavioral history (score > 800) can execute workflows or write to memory.
Additional Context
- Technical fit is strong: The Auth0 provider is the closest analog — pure JWKS verification, no session management. AgentLair uses EdDSA (OKP/Ed25519) instead of RSA, but
jose handles both transparently.
- Package structure: Would follow the existing
auth/{provider}/ scaffold with @mastra/auth-agentlair package name.
- Category precedent: OpenBox recently shipped a governance integration for agent oversight — agent trust/identity is an emerging provider category alongside human auth.
- AgentLair docs: agentlair.dev
Verification
Problem Statement
Mastra has 9 auth providers (Auth0, Clerk, Firebase, Okta, Supabase, WorkOS, etc.) — all designed for human users authenticating via browser sessions, OAuth flows, or human-issued JWTs. None address agent-to-agent authentication: an autonomous agent calling your Mastra-powered API, proving its identity, and being authorized based on behavioral trust rather than static credentials.
As agentic architectures become production-critical, the auth model shifts. An agent calling your API doesn't have a browser session or an OAuth redirect URI. It presents a cryptographically signed token asserting its identity, issued by an agent identity provider. The question isn't "which human authorized this request?" — it's "which agent is this, and should I trust it?"
Today, there's no way to express this in Mastra's auth system without building it from scratch.
Proposed Solution
Add
@mastra/auth-agentlair— an auth provider that verifies agent identity tokens issued by AgentLair, following the same pattern as@mastra/auth-auth0.AgentLair issues EdDSA-signed JWTs (Agent Authentication Tokens) verifiable via a standard JWKS endpoint at
https://agentlair.dev/.well-known/jwks.json. The@mastra/authpackage already exportsverifyJwks(), and existing providers (Auth0, WorkOS) already usejose'screateRemoteJWKSet+jwtVerify— the same pattern works here.Auth provider (~50 lines):
Configuration:
Optional RBAC provider — maps behavioral trust tiers to Mastra roles:
This enables trust-tiered agent access:
Component
Integrations, Agents
Alternatives Considered
MastraAuthProviderabstraction handles token verification, user resolution, and route protection in one place.Example Use Case
Multi-agent system where external agents consume your Mastra-powered API:
Additional Context
josehandles both transparently.auth/{provider}/scaffold with@mastra/auth-agentlairpackage name.Verification