원클릭으로
api-tenant-access
Use when changing private API authorization, access checks, or tenant-scoped data paths.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when changing private API authorization, access checks, or tenant-scoped data paths.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when adding, changing, extracting, or reusing client components, including Storybook stories and controls.
Use when adding or changing forms in apps/client.
Use when changing GitHub OAuth, session cookies, SessionGuard, logout, or authenticated API request identity.
Use when adding or changing routes in apps/client.
Use when adding or changing client state, React Query data flow, immutable context values, or Zustand stores.
Use when styling apps/client with Tailwind CSS v4.
| name | api-tenant-access |
| description | Use when changing private API authorization, access checks, or tenant-scoped data paths. |
Generated from ai/registry.json. Do not edit manually.
Canonical skill: ../../../ai/skills/api-tenant-access.md.
Referenced context:
../../../ai/rules/api-tenant-access-rules.md../../../ai/architecture/tenant-access.md../../../ai/glossary/roles-and-permissions.md../../../ai/examples/good-api-access-check.mdThis file is compiled from canonical AI knowledge files. Edit canonical files under ai, then run npm run ai:sync.
ai/skills/api-tenant-access.mdUse this skill when changing private API controllers, services, authorization, membership checks, or organization/project-scoped reads and writes in apps/api.
Preserve tenant isolation by resolving parent ownership and using AccessService before tenant-owned reads or writes.
ai/rules/api-tenant-access-rules.mdai/architecture/tenant-access.mdai/glossary/roles-and-permissions.mdai/examples/good-api-access-check.mdapi-module-architecture when access work also moves behavior between controllers, facades, use cases, support services, providers, or module exports.SessionGuard and AuthenticatedRequest.AuthenticatedApiGuard plus API token tenant/scope guards.AccessService method and role allowlist for the operation.npm --workspace @capture-flag/api run test after access-sensitive changes.npm --workspace @capture-flag/api run build after controller or service changes.ai/rules/api-tenant-access-rules.mdRules for private API authorization and tenant isolation.
SessionGuard and AuthenticatedRequest on session-only private API controllers.AuthenticatedApiGuard plus API token tenant/scope guards on private management routes that also accept API tokens.request.user.id, and delegate rules to services.AccessService before returning or mutating tenant-owned data.requireProjectAccess for project-scoped reads.requireProjectRole for project-scoped writes with the narrowest allowed project roles.requireOrganizationMember or requireOrganizationRole for organization-level reads and writes.owner and admin roles can satisfy project access without explicit project membership.developer scoped to feature flag writes; do not allow it to manage segments, SDK keys, environments, configs, project members, or roles.include or nested select shapes.configId and environmentId must belong to the same projectId before SDK keys, flag values, or config state changes.ai/architecture/tenant-access.mdCapture Flag is multi-tenant from the first MVP slice. Tenant boundaries are enforced in API services.
Organization
Project
Config
Environment
SDK Key
Segment
Feature Flag
Feature Flag Environment Value
Config Environment State
Audit Log
Every operational entity must be reachable from an organization, directly or through a project.
AccessService centralizes private API access checks.
requireOrganizationMember(userId, organizationId) verifies organization membership.requireOrganizationRole(userId, organizationId, roles) verifies allowed organization roles.requireProjectAccess(userId, projectId) verifies project read access.requireProjectRole(userId, projectId, projectRoles, organizationRoles) verifies project write access.Organization owner and admin roles can satisfy project access even without explicit project membership.
Organization member and viewer roles do not satisfy project access on their own. They need an explicit project membership for project reads, and a matching project role for project writes.
owner/admin manage organization members, organization roles, and projects, but only owners can create, change, or remove owners.project_admin manages project members, configs, environments, SDK keys, segments, and flags for that project.developer manages flags only, not project members, configs, environments, SDK keys, or segments.viewer is read-only.request.user.id to the service.AccessService with the resolved organization or project.ai/glossary/roles-and-permissions.mdRole terminology used by organization and project access checks.
owner: highest organization role; manages organizations, projects, members, roles, and can satisfy project access.admin: organization administrator; manages organization members/projects except owner role changes, and can satisfy project access.member: organization member without admin shortcut.viewer: read-oriented organization member.project_admin: project-level administrator; manages project members, configs, environments, SDK keys, segments, and flags.developer: can create, update, and delete feature flags in projects where the role was granted.viewer: read-oriented project member.owner/admin or explicit project membership.requireProjectRole with narrow allowed project roles.requireOrganizationRole with narrow allowed organization roles.owner/admin: create projects, manage organization members, manage organization roles, and satisfy project-level administrative actions through the organization shortcut. Only owners can create, change, or remove owners.project_admin: manage project members, configs, environments, SDK keys, segments, and feature flags only for projects where this role was granted.developer: create, update, and delete feature flags only for projects where this role was granted.viewer: read project resources only.member/viewer without a project role cannot access project resources.ai/examples/good-api-access-check.mdSource: apps/api/src/common/access.service.ts (sha256: 3673b3603552b66434199b8f4c6ef127e465074b2ffb82fe6b39b3f1258dc694)
Why this is canonical:
AccessService.Canonical access pattern from apps/api/src/common/access.service.ts.
async requireProjectRole(
userId: string,
projectId: string,
allowedProjectRoles: readonly ProjectRole[],
allowedOrganizationRoles: readonly OrganizationRole[] = organizationManagerRoles,
) {
const access = await this.requireProjectAccess(userId, projectId);
if (allowedOrganizationRoles.includes(access.organizationRole as OrganizationRole)) {
return access;
}
if (access.projectRole && allowedProjectRoles.includes(access.projectRole as ProjectRole)) {
return access;
}
throw new ForbiddenException("Project role is not allowed for this action");
}
Services should use this after resolving the project path for the resource being changed.
const config = await this.prisma.config.findUnique({
where: { id: configId },
select: { projectId: true },
});
if (!config) {
throw new NotFoundException("Config not found");
}
await this.access.requireProjectAccess(userId, config.projectId);
The service resolves the parent project before authorizing access.