メインコンテンツへ移動

Fine-Grained Authorization (FGA)

注記

Fine-Grained Authorization は Mastra Enterprise Edition の一部です。本番環境へのデプロイには有効な EE ライセンスが必要です。詳しくは営業担当へのお問い合わせをご利用ください。

Fine-Grained Authorization(FGA)は、Mastra アプリケーションにリソースレベルの権限チェックを追加します。RBAC が「このロールはこのアクションを実行できるか?」に答えるのに対し、FGA は**「このユーザーは、この特定のリソースに対してこのアクションを実行できるか?」**に答えます。

FGA を使用する状況
FGA を使用する状況への直接リンク

FGA は、権限がコンテキストに応じて変わるマルチテナント B2B 製品向けに設計されています。

  • あるユーザーが Team A では admin でも、Team B では member にすぎない場合がある
  • スレッドへのアクセスを、ユーザー自身の Organization に限定する必要がある
  • Workflow の実行範囲を特定のチームまたはプロジェクトに限定する必要がある
  • Tool へのアクセスが、ユーザーとリソースの関係に依存する

設定
設定への直接リンク

Mastra サーバー設定で、認証および RBAC とともに FGA を設定します。

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,
mapUserToResourceId: user => user.teamId,
}),
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',
},
}),
storedResources: {
scope: true,
},
},
});

MastraFGAWorkos を使用する場合は、fetchMemberships: trueMastraAuthWorkos に設定します。WorkOS の FGA チェックでは、認可に使用する正しいメンバーシップ ID を解決するために、ユーザーが所属する Organization の情報が必要です。

メモリの認可では、リソースマッピングのキーに thread を使用します。MastraFGAWorkos は従来のエイリアス memory も引き続き受け付けますが、新しい設定では thread を優先してください。

server.fga を設定すると、Mastra は保護されたアクションに FGA を適用します。保護されたアクションに認証済みユーザーがいない場合、Mastra はそのアクションを拒否します。server.fga が設定されていない場合、これらの FGA チェックはスキップされ、Mastra は従来の動作を維持します。

リソースのマッピング
リソースのマッピングへの直接リンク

resourceMapping は、リクエストコンテキストから FGA のリソースタイプと ID を解決する方法を Mastra に指示します。キーは Mastra のリソースタイプで、値には FGA のリソースタイプと 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() は次の値を受け取ります。

  • user: 認証済みユーザー
  • resourceId: 利用可能な場合は、所有元の Mastra リソース ID(たとえば、スレッドの resourceId
  • requestContext: 高度なテナント解決に使用する現在のリクエストコンテキスト
  • metadata: 試行されたアクションに関する Provider 固有のメタデータ

undefinedderiveId() から返すと、元の Mastra リソース ID にフォールバックします。

スレッドとメモリのチェックでは、Mastra は引き続き未加工の threadId をチェック対象のリソースとして渡しますが、スレッドを所有する resourceIdderiveId() に転送します。これにより、スレッドの権限を userId-teamId-orgId のような複合テナント ID にマッピングできます。

権限のマッピング
権限のマッピングへの直接リンク

permissionMapping は、Mastra 内部の権限文字列を FGA Provider の権限スラッグに変換します。

import { MastraFGAPermissions } from '@mastra/core/auth/ee';

permissionMapping: {
[MastraFGAPermissions.AGENTS_EXECUTE]: 'manage-workflows', // Mastra permission -> WorkOS permission slug
[MastraFGAPermissions.MEMORY_READ]: 'read',
}

権限に対応するマッピングがない場合は、元の文字列がそのまま渡されます。

起動時に Mastra が生成する可能性のある権限一式を検証するには、validatePermissions() を使用します。すべての Mastra 権限に明示的な Provider の権限スラッグが必要な場合に使用してください。

保存済みリソースのスコープ設定
保存済みリソースのスコープ設定への直接リンク

FGA はリソースへのアクセスを認可しますが、共有ストレージ内の保存済みレコードを自動的に絞り込むわけではありません。マルチテナントアプリケーションで組み込みの保存済みリソース API を使用する場合は、保存済みリソースのスコープ設定を有効にします。

const mastra = new Mastra({
server: {
auth: new MastraAuthWorkos({
/* ... */
mapUserToResourceId: user => user.teamId,
}),
storedResources: {
scope: true,
},
},
});

scope: true を指定すると、Mastra はリクエストコンテキストから MASTRA_RESOURCE_ID_KEY を読み取ります。mapUserToResourceId() は認証後にこの値を設定します。保存済みリソースのハンドラーはスコープをレコードのメタデータに保持し、一覧取得、読み取り、更新、公開、削除の各操作をそのスコープで絞り込みます。

スコープにカスタムのリクエストロジックが必要な場合は、オブジェクトを使用します。

storedResources: {
scope: {
metadataKey: 'teamId',
resolve: ({ user }) => user.teamId,
requireScope: true,
},
},

requireScopetrue または省略されている場合、スコープを解決できないと、スコープが設定された保存済みリソースのルートは失敗します。

ルートポリシーの適用範囲
ルートポリシーの適用範囲への直接リンク

Mastra には、Agent、Workflow、Tool、MCP Tool、メモリスレッド、Response、Conversation、保存済みリソースなどの組み込みリソースルートに対するルートレベルの FGA メタデータが含まれています。保存済みリソースの対象ルートには、/stored/agents/stored/mcp-clients/stored/prompt-blocks/stored/scorers/stored/skills/stored/workspaces が含まれます。ルートレベルの fga メタデータがある場合、Mastra がそのルートの組み込みメタデータを導出できる場合、または Provider が resolveRouteFGA() でメタデータを提供する場合に、そのルートがチェックされます。

FGA メタデータを解決できない保護対象ルートを拒否するには、FGA Provider にルートポリシーの適用範囲を設定します。

const fga = new MastraFGAWorkos({
resourceMapping: {
project: { fgaResourceType: 'project' },
},
permissionMapping: {
'projects:read': 'read',
},
requireForProtectedRoutes: true,
auditProtectedRoutes: 'warn',
validatePermissions: async permissions => {
// Throw if a Mastra permission is missing from permissionMapping.
},
});

保護対象ルートに組み込みの FGA メタデータがない場合に起動を失敗させるには、auditProtectedRoutes: 'error' を設定します。requireForProtectedRoutes が有効な場合、Mastra はデフォルトでこの監査を警告としてログに記録します。

カスタムルートでは、ルートレベルの fga メタデータを優先してください。これにより、認可ポリシーをルートの近くに配置できます。

import { createRoute } from '@mastra/server/server-adapter';

export const getProjectRoute = createRoute({
method: 'GET',
path: '/projects/:projectId',
responseType: 'json',
requiresAuth: true,
fga: {
resourceType: 'project',
resourceIdParam: 'projectId',
permission: 'projects:read',
},
handler: async () => {
return { project: null };
},
});

ルート、パラメーター、リクエストコンテキストからルートメタデータを一元的に導出する必要がある場合に限り、resolveRouteFGA() を使用します。文字列のプレフィックスをチェックするよりも、ルートマップの方が拡張性に優れています。

import type { FGARouteConfig, FGARouteResolver } from '@mastra/core/auth/ee';

const routeFGA = {
'GET /billing/:accountId': {
resourceType: 'account',
resourceIdParam: 'accountId',
permission: 'billing:read',
},
} satisfies Record<string, FGARouteConfig>;

const resolveRouteFGA: FGARouteResolver = ({ route }) => routeFGA[`${route.method} ${route.path}`];

const fga = new MastraFGAWorkos({
/* ... */
resolveRouteFGA,
});

適用ポイント
適用ポイントへの直接リンク

FGA Provider を設定すると、Mastra は次のライフサイクルポイントで認可を自動的にチェックします。

ライフサイクルポイントチェックされる権限リソースタイプリソース ID
Agent の実行(generatestreamagents:executeagentagentId
組み込みの Workflow HTTP 実行ルートと Workflow.execute()workflows:executeworkflowworkflowId
スタンドアロン Tool の実行tools:executetooltoolName
Agent Tool の実行tools:executetool${agentId}:${toolName}
MCP Tool の実行tools:executeデフォルトでは tool、またはサーバーレベルの fga.resourceMapping によるオーバーライドデフォルトでは JSON.stringify([serverName, toolName])、またはサーバーレベルで導出された ID
スレッドとメモリへのアクセスmemory:readmemory:writememory:deletethreadthreadId
保存済みリソースのルートルートアクションに対応する保存済みリソースの権限保存済みリソースのタイプルートのレコード ID、またはコレクションルートの保存済みリソーススコープ
HTTP リソースルートルートごとの設定ルートごとの設定ルートごとの設定

OAuth で保護された MCP サーバーでは、HTTP MCP Transport が認証済みデータを extra.authInfo として渡します。FGA が有効な Mastra インスタンスに MCPServer を登録する場合は、mapAuthInfoToUser を設定して、Mastra が requestContext.get('user') を設定してから tools/listtools/call をチェックできるようにしてください。MCP Tool のチェックで、内部の Agent および Workflow の Tool チェックとは異なるリソースまたは権限のマッピングが必要な場合は、サーバーレベルの fga オプションを使用します。MCPServer の認証コンテキストを参照してください。

このリリースでは、createRun().start()resume()restart() を直接呼び出す SDK 呼び出しは、コア FGA によって個別にはチェックされません。これらの呼び出しは保護されたルートから実行するか、アプリケーションコードでガードしてください。保護されたエントリーポイントを直接呼び出す場合は、認証済みユーザーを含む requestContext を渡します。

コアの Agent、内部 Workflow、Tool、メモリのチェックでは、requestContext とアクションのメタデータも FGA Provider に渡します。ルートのチェックでは requestContext を渡します。スレッドのチェックでは、利用可能な場合は所有元の resourceId を渡します。

カスタム FGA Provider
カスタム FGA Providerへの直接リンク

任意の FGA バックエンドを使用するには、IFGAProvider を実装します。

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
}
}
注記

IFGAProvider リファレンスで、すべてのメソッド、パラメーター、ActorSignal 型を確認できます。

システムアクター
システムアクターへの直接リンク

自律型 Agent とスケジュール実行される Agent は、エンドユーザーなしで動作します。FGA がユーザーリクエストと区別できるよう、これらの呼び出しにアクターシグナルを付けます。

  • true または { actorKind: 'system' } は、匿名のシステムアクターを示します。
  • オブジェクト形式では、動作する Agent を識別して制約するために、agentIdpermissionsscope も指定できます。

デフォルトでは、信頼されたアクターはテナントスコープのチェック後、ユーザーを中心とした require() チェックをスキップします。Agent ごとに最小権限を適用するには、Provider にオプションの requireActor メソッドを実装します。このメソッドはアクターと FGACheckParamsrequire と同じもの)を受け取り、拒否する場合は FGADeniedError をスローします。Provider が requireActor を実装していない場合は、信頼されたアクターのバイパスが維持されるため、この機能の追加には後方互換性があります。

import { FGADeniedError } from '@mastra/core/auth/ee'
import type { ActorSignal, FGACheckParams, IFGAProvider } from '@mastra/core/auth/ee'

class MyFGAProvider implements IFGAProvider {
// ...check, require, filterAccessible...

async requireActor(actor: ActorSignal, params: FGACheckParams): Promise<void> {
const agentId = actor === true ? undefined : actor.agentId
// Resolve the agent's real grants from a trusted source keyed by agentId.
const granted = await this.grantsForAgent(agentId)
const required = Array.isArray(params.permission) ? params.permission : [params.permission]
if (!required.some(permission => granted.includes(permission))) {
throw new FGADeniedError(null, params.resource, params.permission)
}
}
}

信頼に関する要件
信頼に関する要件への直接リンク

アクターシグナルは信頼された入力であるため、サーバー側で構築してください。

  • actor は呼び出しごとのシグナルとして扱います。Durable Workflow は実行開始時にこの値を転送しますが、再開時には最初のアクターを復元しません。信頼された再開のたびに明示的に渡すか、Agent の defaultOptions で新しいアクターを解決してください。現在のアクターがない場合はユーザー認可が適用され、ユーザーがいなければ閉じる側に倒れて失敗します。
  • Mastra は、組み込みの Agent HTTP ルートが処理する実行オプションから actor を取り除きます。クライアント入力ではなく、スケジュールジョブや Workflow などのサーバー側コードで設定してください。
  • テナントスコープはサーバー側で確立します。組み込みの Agent HTTP ルートは、クライアントがリクエストコンテキストで渡した organizationId を無視し、信頼されたアクターのパスでは organizationId の設定が必須です。
  • Durable Resume では、既存のリクエストコンテキストの復元とマージ動作が維持されます。これによって、永続化されたアクターが後続の Workflow セグメントで信頼されるわけではありません。
  • テナントスコープのチェックでは、信頼された organizationId が存在することを確認します。actor.agentId がその Organization に属しているかは検証しません。この関係が重要な場合は、信頼できる Provider のデータを使用して requireActor で検証してください。
  • actor.permissions は未検証のクレームとして扱います。信頼できるソースから正式な権限を解決してください。最小権限を適用する Provider では、インラインの値を信頼せず、たとえば agentId をキーとするマニフェストや FGA バックエンドなど、信頼できるソースから Agent の正式な権限を解決します。
  • Provider が requireActor を実装すると、このメソッドのエラーによって実行が停止します。Mastra は Organization のみによる認可へフォールバックしません。