Fine-Grained Authorization (FGA)

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

Published: 2026-05-10 · Source: crawler_authoritative

Tình huống

Mastra documentation on Fine-Grained Authorization (FGA) for implementing resource-level permission checks in multi-tenant B2B applications, answering whether a specific user can perform an action on a specific resource.

Insight

FGA adds resource-level permission checks to Mastra applications, complementing RBAC by answering ‘can this user do this action on this specific resource?’ rather than just role-based permissions. The configuration uses MastraFGAWorkos provider which requires fetchMemberships: true on MastraAuthWorkos to resolve user organization memberships. The resourceMapping object maps Mastra resource types (agent, workflow, thread) to FGA resource types, with deriveId() function resolving the owning resource ID from request context — receiving user, resourceId, and requestContext. For thread/memory checks, Mastra passes the raw threadId but also forwards the thread’s owning resourceId into deriveId() for composite tenant IDs like userId-teamId-orgId. The permissionMapping translates Mastra’s internal MastraFGAPermissions enum values (AGENTS_EXECUTE, WORKFLOWS_EXECUTE, MEMORY_READ, MEMORY_WRITE) to FGA provider permission slugs. Enforcement points include agent execution (generate, stream), workflow execution, tool execution, thread/memory access (memory:read, memory:write, memory:delete), MCP tool execution, and HTTP routes (opt-in). The legacy alias memory for thread resource-mapping is still accepted but new configs should prefer thread. All FGA checks are no-ops when FGA is not configured, maintaining backward compatibility. Custom FGA providers implement IFGAProvider interface with check(), require(), and filterAccessible() methods.

Hành động

Configure FGA by adding MastraFGAWorkos to the Mastra server config with resourceMapping and permissionMapping objects. Set fetchMemberships: true on MastraAuthWorkos. In resourceMapping, map each Mastra resource type to an FGA resource type and define a deriveId() callback that extracts the owning resource ID from ctx.user.teamId or ctx.user.teamId-orgId. In permissionMapping, import MastraFGAPermissions from @mastra/core/auth/ee and map each permission to your FGA provider’s permission slug. For custom FGA backends, implement IFGAProvider interface — implement check() returning boolean, require() throwing FGADeniedError when denied, and filterAccessible() filtering accessible resources from a list. Return undefined from deriveId() to fall back to the original Mastra resource ID.

Kết quả

Mastra automatically enforces authorization checks at agent execution, workflow execution, tool execution, thread/memory access, and MCP tool execution lifecycle points. Without FGA configured, all checks are no-ops maintaining backward compatibility.

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

FGA is designed for multi-tenant B2B products where user permissions are contextual and depend on their relationship to specific resources. Requires WorkOS integration for MastraFGAWorkos or custom IFGAProvider implementation.


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: