> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # FGA(세밀한 권한 부여) :::참고 세분화된 인증은 Mastra Enterprise Edition의 일부입니다. 프로덕션 배포에는 유효한 EE 라이선스가 필요합니다.[Contact sales](https://mastra.ai/contact)자세한 내용은 ::: FGA(Fine-Grained Authorization)는 Mastra 애플리케이션에 리소스 수준의 권한 검사를 추가합니다. RBAC가 "이 역할이 이 작업을 수행할 수 있는가?"에 답한다면, FGA는 \*\*"이 사용자가 이 특정 리소스에 대해 이 작업을 수행할 수 있는가?"\*\*에 답합니다. ## FGA를 사용하는 경우 FGA는 권한이 상황에 맞는 다중 테넌트 B2B 제품을 위해 설계되었습니다. - 사용자는 Team A의 **admin**이지만 Team B에서는 **member**일 수 있습니다. - 스레드 액세스는 사용자가 속한 조직으로 제한해야 합니다. - Workflow 실행 범위는 특정 팀 또는 프로젝트로 제한해야 합니다. - Tool 액세스 권한은 사용자와 리소스 간의 관계에 따라 달라질 수 있습니다. ## 구성 인증 및 RBAC와 함께 Mastra 서버 구성에서 FGA를 구성합니다. ```typescript 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`를 사용할 때는 `MastraAuthWorkos`에서 `fetchMemberships: true`를 설정하세요. WorkOS FGA 검사가 권한 부여에 적합한 멤버십 ID를 확인하려면 사용자의 조직 멤버십이 필요합니다. Memory 권한 부여의 리소스 매핑 키로 `thread`를 사용하세요. `MastraFGAWorkos`는 기존 별칭인 `memory`도 계속 허용하지만, 새 구성에서는 `thread`를 사용하는 것이 좋습니다. `server.fga`가 구성되어 있으면 Mastra는 보호되는 작업에 FGA를 적용합니다. 보호되는 작업에 인증된 사용자가 없으면 Mastra가 해당 작업을 거부합니다. `server.fga`가 구성되어 있지 않으면 이러한 FGA 검사를 건너뛰고 Mastra의 이전 동작을 유지합니다. ### 리소스 매핑 `resourceMapping`은 요청 컨텍스트에서 FGA 리소스 유형과 ID를 확인하는 방법을 Mastra에 알려 줍니다. 키는 Mastra 리소스 유형이며, 값은 FGA 리소스 유형과 ID를 도출하는 방법을 정의합니다. ```typescript 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`: 시도한 작업에 대한 공급자별 메타데이터 `deriveId()`에서 `undefined`를 반환하면 원래 Mastra 리소스 ID를 사용합니다. 스레드 및 Memory 검사에서 Mastra는 검사할 리소스로 원시 `threadId`를 계속 전달하지만, 스레드를 소유한 `resourceId`도 `deriveId()`에 전달합니다. 따라서 스레드 권한을 `userId-teamId-orgId` 같은 복합 테넌트 ID에 매핑할 수 있습니다. ### 권한 매핑 `permissionMapping`은 Mastra 내부 권한 문자열을 FGA Provider의 권한 슬러그로 변환합니다. ```typescript import { MastraFGAPermissions } from '@mastra/core/auth/ee'; permissionMapping: { [MastraFGAPermissions.AGENTS_EXECUTE]: 'manage-workflows', // Mastra permission -> WorkOS permission slug [MastraFGAPermissions.MEMORY_READ]: 'read', } ``` 권한에 대한 매핑이 없으면 원래 문자열이 전달됩니다. `validatePermissions()`를 사용하면 Mastra가 시작 시 내보낼 수 있는 전체 권한 집합을 검증할 수 있습니다. 모든 Mastra 권한에 명시적인 Provider 권한 슬러그가 필요한 Provider에서는 이 메서드를 사용하세요. ### 저장된 리소스 범위 지정 FGA는 리소스에 대한 액세스를 승인합니다. 공유 저장소에 있는 저장된 기록은 자동으로 필터링되지 않습니다. 내장된 저장 리소스 API가 다중 테넌트 앱에서 사용되는 경우 저장 리소스 범위 지정을 활성화합니다. ```typescript const mastra = new Mastra({ server: { auth: new MastraAuthWorkos({ /* ... */ mapUserToResourceId: user => user.teamId, }), storedResources: { scope: true, }, }, }); ``` `scope: true`를 설정하면 Mastra는 요청 컨텍스트에서 `MASTRA_RESOURCE_ID_KEY`를 읽습니다. `mapUserToResourceId()`는 인증 후 이 값을 설정합니다. 저장된 리소스 핸들러는 레코드 메타데이터에 범위를 유지하고 목록 조회, 읽기, 업데이트, 게시 및 삭제 작업을 해당 범위로 필터링합니다. 범위에 사용자 정의 요청 논리가 필요한 경우 객체를 사용하십시오. ```typescript storedResources: { scope: { metadataKey: 'teamId', resolve: ({ user }) => user.teamId, requireScope: true, }, }, ``` `requireScope`가 `true`이거나 생략된 경우, 범위를 확인할 수 없으면 범위가 지정된 저장 리소스 경로가 실패합니다. ### 경로 정책 적용 범위 Mastra에는 Agent, Workflow, Tool, MCP Tool, Memory 스레드, 응답, 대화 및 저장된 리소스를 포함하는 기본 제공 리소스 경로에 대한 경로 수준 FGA 메타데이터가 포함되어 있습니다. 저장된 리소스 경로 범위에는 `/stored/agents`, `/stored/mcp-clients`, `/stored/prompt-blocks`, `/stored/scorers`, `/stored/skills`, `/stored/workspaces`가 포함됩니다. 경로 수준 `fga` 메타데이터가 있거나, Mastra가 해당 경로의 기본 제공 메타데이터를 도출할 수 있거나, Provider가 `resolveRouteFGA()`로 메타데이터를 제공하면 경로를 검사합니다. FGA 메타데이터를 확인하지 않는 보호된 경로를 거부하려면 FGA 공급자에서 경로 정책 적용 범위를 구성합니다. ```typescript 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` 메타데이터를 사용하는 것이 좋습니다. 그러면 권한 부여 정책을 경로와 함께 둘 수 있습니다. ```typescript 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()`를 사용하세요. 경로 맵은 문자열 접두사 검사보다 확장성이 뛰어납니다. ```typescript import type { FGARouteConfig, FGARouteResolver } from '@mastra/core/auth/ee'; const routeFGA = { 'GET /billing/:accountId': { resourceType: 'account', resourceIdParam: 'accountId', permission: 'billing:read', }, } satisfies Record; const resolveRouteFGA: FGARouteResolver = ({ route }) => routeFGA[`${route.method} ${route.path}`]; const fga = new MastraFGAWorkos({ /* ... */ resolveRouteFGA, }); ``` ## 시행 포인트 FGA 공급자가 구성되면 Mastra는 다음 수명 주기 지점에서 자동으로 인증을 확인합니다. | 수명 주기 지점 | 검사하는 권한 | 리소스 유형 | 리소스 ID | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------- | | Agent 실행(`generate`, `stream`) | `agents:execute` | `agent` | `agentId` | | 기본 제공 Workflow HTTP 실행 경로 및 `Workflow.execute()` | `workflows:execute` | `workflow` | `workflowId` | | 독립형 Tool 실행 | `tools:execute` | `tool` | `toolName` | | Agent Tool 실행 | `tools:execute` | `tool` | `${agentId}:${toolName}` | | MCP Tool 실행 | `tools:execute` | 기본적으로 `tool`, 또는 서버 수준 `fga.resourceMapping` 재정의 값 | 기본적으로 `JSON.stringify([serverName, toolName])`, 또는 서버 수준에서 도출한 ID | | 스레드 및 Memory 액세스 | `memory:read`, `memory:write`, `memory:delete` | `thread` | `threadId` | | 저장된 리소스 경로 | 경로 작업에 해당하는 저장된 리소스 권한 | 저장된 리소스 유형 | 경로 레코드 ID 또는 컬렉션 경로의 저장된 리소스 범위 | | HTTP 리소스 경로 | 경로별로 구성 | 경로별로 구성 | 경로별로 구성 | | OAuth로 보호되는 MCP 서버의 경우 HTTP MCP 전송은 인증된 데이터를 `extra.authInfo`로 전달합니다. FGA가 활성화된 Mastra 인스턴스에 `MCPServer`를 등록하는 경우, Mastra가 `tools/list` 및 `tools/call`을 검사하기 전에 `requestContext.get('user')`를 설정할 수 있도록 `mapAuthInfoToUser`를 구성하세요. MCP Tool 검사에 내부 Agent 및 Workflow Tool 검사와 다른 리소스 또는 권한 매핑이 필요한 경우 서버 수준의 `fga` 옵션을 사용하세요. [MCPServer 인증 컨텍스트](https://mastra.zisheng.pro/ko/reference/tools/mcp-server)를 참조하세요. | | | | | 직접 SDK로 호출하는 `createRun().start()`, `resume()`, `restart()`는 이번 릴리스에서 Core FGA가 개별적으로 검사하지 않습니다. 이러한 호출은 보호되는 경로에서 실행하거나 애플리케이션 코드에서 보호하세요. 보호되는 진입점을 직접 호출할 때는 인증된 사용자가 포함된 `requestContext`를 전달하세요. | | | | | 핵심 Agent, 내부 Workflow, Tool 및 Memory 검사도 `requestContext`와 작업 메타데이터를 FGA Provider에 전달합니다. 경로 검사는 `requestContext`를 전달합니다. 스레드 검사는 가능한 경우 소유자의 `resourceId`를 전달합니다. | | | | ## 맞춤형 FGA 공급자 FGA 백엔드를 사용하려면 `IFGAProvider`를 구현하세요. ```typescript 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 { // Your authorization logic return true } async require(user: any, params: FGACheckParams): Promise { const allowed = await this.check(user, params) if (!allowed) { throw new FGADeniedError(user, params.resource, params.permission) } } async filterAccessible( user: any, resources: T[], resourceType: string, permission: MastraFGAPermissionInput, ): Promise { // Filter resources the user can access return resources } } ``` :::참고 모든 메서드와 매개변수 및 `ActorSignal` 유형은 [`IFGAProvider` 레퍼런스](https://mastra.zisheng.pro/ko/reference/auth/fga)를 참조하세요. ::: ## 시스템 액터 자율 및 예약 Agent는 최종 사용자 없이 실행됩니다. FGA가 사용자 요청과 구별할 수 있도록 이러한 호출을 행위자 신호로 표시합니다. - `true` 또는 `{ actorKind: 'system' }`은 익명 시스템 행위자를 나타냅니다. - 객체 형태에는 행위하는 Agent를 식별하고 제한하기 위한 `agentId`, `permissions`, `scope`도 포함할 수 있습니다. 기본적으로 신뢰할 수 있는 행위자는 테넌트 범위 검사 후 사용자 중심의 `require()` 검사를 건너뜁니다. Agent별 최소 권한을 적용하려면 Provider에서 선택적 `requireActor` 메서드를 구현하세요. 이 메서드는 행위자와 `require`에 전달되는 것과 동일한 `FGACheckParams`를 받고, 거부하려면 `FGADeniedError`를 발생시킵니다. Provider가 `requireActor`를 구현하지 않으면 신뢰할 수 있는 행위자의 우회 동작이 유지되므로 이를 추가해도 이전 버전과 호환됩니다. ```typescript 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 { 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`는 호출별 신호로 취급하세요. 내구성 있는 Workflow는 실행이 시작될 때 이를 전달하지만, 재개할 때 최초 행위자를 복원하지는 않습니다. 신뢰할 수 있는 재개 작업마다 이를 명시적으로 전달하거나 Agent `defaultOptions`를 통해 새로운 행위자를 확인하세요. 현재 행위자가 없으면 사용자 권한 부여가 적용되며 사용자가 없을 경우 안전하게 실패합니다. - Mastra는 기본 제공 Agent HTTP 경로가 처리하는 실행 옵션에서 `actor`를 제거합니다. 클라이언트 입력이 아니라 예약 작업이나 Workflow 같은 서버 측 코드에서 설정하세요. - 테넌트 범위는 서버 측에서 설정하세요. 기본 제공 Agent HTTP 경로는 요청 컨텍스트에서 클라이언트가 제공한 `organizationId`를 무시하며, 신뢰할 수 있는 행위자 경로를 사용하려면 `organizationId`가 설정되어 있어야 합니다. - 내구성 있는 재개는 기존의 요청 컨텍스트 복원 및 병합 동작을 유지합니다. 그렇다고 이후 Workflow 세그먼트에서 지속된 행위자를 신뢰할 수 있게 되는 것은 아닙니다. - 테넌트 범위 검사는 신뢰할 수 있는 `organizationId`가 있는지 확인합니다. `actor.agentId`가 해당 조직에 속하는지는 확인하지 않습니다. 이 관계가 중요하다면 신뢰할 수 있는 Provider 데이터를 사용하여 `requireActor`에서 확인하세요. - `actor.permissions`는 검증되지 않은 클레임으로 취급하세요. 신뢰할 수 있는 소스에서 권한을 확인하세요. 최소 권한을 적용하는 Provider는 인라인 값을 신뢰하는 대신 매니페스트나 `agentId`를 키로 사용하는 FGA 백엔드 같은 신뢰할 수 있는 소스에서 Agent의 권한을 확인합니다. - Provider가 `requireActor`를 구현한 경우 해당 메서드의 오류는 실행을 중단합니다. Mastra는 조직만을 기준으로 한 권한 부여로 대체하지 않습니다. ## 관련된 - [`IFGAProvider`참조](https://mastra.zisheng.pro/ko/reference/auth/fga) - [인증 개요](https://mastra.zisheng.pro/ko/docs/server/auth) - [WorkOS 인증](https://mastra.zisheng.pro/ko/docs/server/auth/workos)