Mastra FGA: Fine-Grained Authorization Documentation

Trust: ★★★☆☆ (0.90) · 0 validations · factual

Published: 2026-05-09 · Source: crawler_authoritative

Tình huống

Developer documentation for implementing Fine-Grained Authorization (FGA) in Mastra applications. Technical reference covering resource-level permission checks for multi-tenant B2B products where user permissions are contextual across different teams and organizations.

Insight

FGA answers the question ‘can this user do this action on this specific resource?’ complementing RBAC which answers ‘can this role do this action?‘. FGA is designed for multi-tenant scenarios where a user might be admin of Team A but only member of Team B, thread access should be limited to the user’s own organization, workflow execution should be scoped to a specific team or project, and tool access depends on the user’s relationship to a resource. Configuration uses MastraFGAWorkos with resourceMapping to define how Mastra resource types map to FGA resource types and how to derive IDs via deriveId() function. The permissionMapping translates Mastra’s internal permission strings to FGA provider permission slugs. Key MastraFGAPermissions include AGENTS_EXECUTE, WORKFLOWS_EXECUTE, MEMORY_READ, MEMORY_WRITE, and MEMORY_DELETE. When using MastraFGAWorkos, must set fetchMemberships: true on MastraAuthWorkos so WorkOS FGA can resolve the correct membership ID for authorization. For thread and memory checks, Mastra passes the raw threadId as the resource being checked but also forwards the thread’s owning resourceId into deriveId(), enabling mapping to composite tenant IDs like userId-teamId-orgId.

Hành động

  1. Configure MastraFGAWorkos in server config alongside MastraAuthWorkos with fetchMemberships: true. 2. Define resourceMapping with Mastra resource types (agent, workflow, thread) mapping to FGA resource types (team, workspace-thread) with deriveId functions. 3. Define permissionMapping translating MastraFGAPermissions to FGA provider permission slugs. 4. For custom FGA backend, implement IFGAProvider interface with check(), require(), and filterAccessible() methods. 5. Return undefined from deriveId() to fall back to original Mastra resource ID. 6. Use thread as resource-mapping key for memory authorization instead of legacy memory alias.

Điều kiện áp dụng

Applies to multi-tenant B2B products requiring contextual, resource-level permission checks. All FGA checks are no-ops when FGA is not configured, maintaining backward compatibility.


Nội dung gốc (Original)

Fine-Grained Authorization (FGA)

Fine-Grained Authorization (FGA) adds resource-level permission checks to your Mastra application. While RBAC answers “can this role do this action?”, FGA answers “can this user do this action on this specific resource?”

When to use FGA

FGA is designed for multi-tenant B2B products where permissions are contextual:

  • A user might be an admin of Team A but only a member of Team B
  • Thread access should be limited to the user’s own organization
  • Workflow execution should be scoped to a specific team or project
  • Tool access depends on the user’s relationship to a resource

Configuration

Configure FGA in your Mastra server config alongside authentication and RBAC:

import { Mastra } from '@mastra/core/mastra';
import { MastraFGAPermissions } from '@mastra/core/auth/ee';
import { MastraAuthWorkos, MastraFGAWorkos } from '@mastra/auth-workos';
 
const mastra = new Mastra({
  server: {
    auth: new MastraAuthWorkos({
      /* ... */
      fetchMemberships: true,
    }),
    fga: new MastraFGAWorkos({
      resourceMapping: {
        agent: { fgaResourceType: 'team', deriveId: (ctx) => ctx.user.teamId },
        workflow: { fgaResourceType: 'team', deriveId: (ctx) => ctx.user.teamId },
        thread: { fgaResourceType: 'workspace-thread', deriveId: ({ resourceId }) => resourceId },
      },
      permissionMapping: {
        [MastraFGAPermissions.AGENTS_EXECUTE]: 'manage-workflows',
        [MastraFGAPermissions.WORKFLOWS_EXECUTE]: 'manage-workflows',
        [MastraFGAPermissions.MEMORY_READ]: 'read',
        [MastraFGAPermissions.MEMORY_WRITE]: 'update',
      },
    }),
  },
});

When using MastraFGAWorkos, set fetchMemberships: true on MastraAuthWorkos. WorkOS FGA checks need the user’s organization memberships to resolve the correct membership ID for authorization.

Use thread as the resource-mapping key for memory authorization. MastraFGAWorkos still accepts the legacy alias memory, but new configs should prefer thread.

Resource mapping

The resourceMapping tells Mastra how to resolve FGA resource types and IDs from request context. Keys are Mastra resource types, values define the FGA resource type and how to derive the ID:

resourceMapping: {
  // When checking "can user execute agent X?", resolve the FGA resource
  // as the user's team (type: 'team', id: user.teamId)
  agent: {
    fgaResourceType: 'team',
    deriveId: (ctx) => ctx.user.teamId,
  },
}

deriveId() receives:

  • user — the authenticated user
  • resourceId — the owning Mastra resource ID when available (for example, a thread’s resourceId)
  • requestContext — the current request context for advanced tenant resolution

Return undefined from deriveId() to fall back to the original Mastra resource ID.

For thread and memory checks, Mastra still passes the raw threadId as the resource being checked, but it also forwards the thread’s owning resourceId into deriveId(). This lets you map thread permissions to composite tenant IDs such as userId-teamId-orgId.

Permission mapping

The permissionMapping translates Mastra’s internal permission strings to your FGA provider’s permission slugs:

import { MastraFGAPermissions } from '@mastra/core/auth/ee';
 
permissionMapping: {
  [MastraFGAPermissions.AGENTS_EXECUTE]: 'manage-workflows', // Mastra permission -> WorkOS permission slug
  [MastraFGAPermissions.MEMORY_READ]: 'read',
}

If no mapping exists for a permission, the original string is passed through.

Enforcement points

When an FGA provider is configured, Mastra automatically checks authorization at these lifecycle points:

Lifecycle pointPermission checkedResource
Agent execution (generate, stream)agents:execute{ type: 'agent', id: agentId }
Workflow executionworkflows:execute{ type: 'workflow', id: workflowId }
Tool executiontools:execute{ type: 'tool', id: toolName }
Thread/memory accessmemory:read, memory:write, memory:delete{ type: 'thread', id: threadId }
MCP tool executiontools:execute{ type: 'tool', id: toolName }
HTTP routes (opt-in)Configured per routeConfigured per route

All checks are no-ops when FGA is not configured, maintaining backward compatibility.

Custom FGA provider

Implement IFGAProvider to use any FGA backend:

import { FGADeniedError } from '@mastra/core/auth/ee'
import type { FGACheckParams, IFGAProvider, MastraFGAPermissionInput } from '@mastra/core/auth/ee'
 
class MyFGAProvider implements IFGAProvider {
  async check(user: any, params: FGACheckParams): Promise<boolean> {
    // Your authorization logic
    return true
  }
 
  async require(user: any, params: FGACheckParams): Promise<void> {
    const allowed = await this.check(user, params)
    if (!allowed) {
      throw new FGADeniedError(user, params.resource, params.permission)
    }
  }
 
  async filterAccessible<T extends { id: string }>(
    user: any,
    resources: T[],
    resourceType: string,
    permission: MastraFGAPermissionInput,
  ): Promise<T[]> {
    // Filter resources the user can access
    return resources
  }
}

Liên kết

Xem thêm: