{"version":3,"sources":["../src/testing.ts","../src/testing/expect-rbac-decision.ts","../src/adapters/in-memory-rbac.storage.ts","../src/errors/http-error.mapper.ts","../src/errors/rbac.error.ts","../src/utils/assertions.ts","../src/utils/normalize.ts","../src/utils/permission-matcher.ts","../src/utils/resource-matcher.ts","../src/utils/canonicalization.ts","../src/rbac.service.ts","../src/constants.ts","../src/service/rbac-service-decision.factory.ts","../src/utils/runtime-validation.ts","../src/service/rbac-service-input.ts","../src/service/rbac-service-mutation-support.ts","../src/testing/rbac-scenario.ts","../src/testing/subjects.ts","../src/testing/test-rbac.module.ts","../src/rbac.module.ts","../src/rbac.guard.ts","../src/guard/rbac-guard-audit.ts","../src/resolvers/default-http-resource.resolver.ts","../src/resolvers/api-key-subject.resolver.ts","../src/resolvers/default-http-subject.resolver.ts","../src/resolvers/default-http-tenant.resolver.ts","../src/guard/rbac-guard-context.resolver.ts","../src/guard/rbac-guard-requirement.evaluator.ts"],"sourcesContent":["export * from './testing/index';\n","import type { RbacCanInput, RbacServiceDecision } from '../interfaces';\nimport type { RbacService } from '../rbac.service';\n\nexport async function expectAllowed(\n  rbac: RbacService,\n  input: RbacCanInput,\n): Promise<RbacServiceDecision> {\n  const decision = await rbac.can(input);\n  if (!decision.allowed) {\n    throw new Error(`Expected RBAC decision to allow, received ${decision.reason}`);\n  }\n\n  return decision;\n}\n\nexport async function expectDenied(\n  rbac: RbacService,\n  input: RbacCanInput,\n  reason?: RbacServiceDecision['reason'],\n): Promise<RbacServiceDecision> {\n  const decision = await rbac.can(input);\n  if (decision.allowed) {\n    throw new Error('Expected RBAC decision to deny, received allowed decision');\n  }\n  if (reason !== undefined && decision.reason !== reason) {\n    throw new Error(`Expected RBAC denial reason ${reason}, received ${decision.reason}`);\n  }\n\n  return decision;\n}\n\nexport async function expectDeniedReason(\n  rbac: RbacService,\n  input: RbacCanInput,\n  reason: RbacServiceDecision['reason'],\n): Promise<RbacServiceDecision> {\n  return expectDenied(rbac, input, reason);\n}\n","import { isDeepStrictEqual } from 'node:util';\nimport { RbacConfigError, RbacRoleNotFoundError } from '../errors';\nimport { normalizePermission, normalizePermissions } from '../utils';\nimport {\n  canonicalizeIdentifier,\n  canonicalizeResource,\n  canonicalizeSubject,\n  canonicalizeTenantId,\n} from '../utils/canonicalization';\nimport type {\n  AssignRoleStorageInput,\n  CreateRoleInput,\n  DeleteRoleInput,\n  FindRoleByIdInput,\n  FindRoleInput,\n  GrantPermissionInput,\n  ListBindingsStorageInput,\n  ListEffectivePermissionsInput,\n  ListEffectiveRolesInput,\n  ListRolePermissionsInput,\n  ListRolesInput,\n  RbacEffectivePermission,\n  RbacEffectiveRole,\n  RbacResourceRef,\n  RbacRole,\n  RbacRoleBinding,\n  RbacStorage,\n  RbacStorageMutationCapability,\n  RbacStorageRoleLookupCapability,\n  RevokePermissionInput,\n  RevokeRoleStorageInput,\n  UpdateRoleInput,\n  UpsertRoleInput,\n} from '../interfaces';\n\ntype TenantId = string | null;\n\nfunction normalizeTenantId(tenantId: string | null | undefined): TenantId {\n  return canonicalizeTenantId(tenantId) ?? null;\n}\n\nfunction canonicalizeUpsertRoleInput(input: UpsertRoleInput): UpsertRoleInput {\n  return 'roleId' in input\n    ? {\n        ...input,\n        roleId: canonicalizeIdentifier(input.roleId, 'roleId'),\n        ...(input.tenantId !== undefined ? { tenantId: canonicalizeTenantId(input.tenantId) } : {}),\n        ...(input.key !== undefined ? { key: canonicalizeIdentifier(input.key, 'role key') } : {}),\n        ...(input.permissions !== undefined\n          ? { permissions: normalizePermissions(input.permissions) }\n          : {}),\n      }\n    : {\n        ...input,\n        tenantId: canonicalizeTenantId(input.tenantId),\n        key: canonicalizeIdentifier(input.key, 'role key'),\n        permissions: normalizePermissions(input.permissions),\n      };\n}\n\nfunction canonicalizeAssignInput(input: AssignRoleStorageInput): AssignRoleStorageInput {\n  return {\n    ...input,\n    tenantId: canonicalizeTenantId(input.tenantId),\n    subject: canonicalizeSubject(input.subject),\n    roleId: canonicalizeIdentifier(input.roleId, 'roleId'),\n    ...(input.resource !== undefined ? { resource: canonicalizeResource(input.resource) } : {}),\n  };\n}\n\nfunction cloneDate(date: Date | null | undefined): Date | null {\n  return date ? new Date(date) : null;\n}\n\nfunction cloneValue(value: unknown): unknown {\n  if (value instanceof Date) return new Date(value);\n  if (Array.isArray(value)) return value.map(cloneValue);\n  if (value && typeof value === 'object') {\n    return Object.fromEntries(\n      Object.entries(value as Record<string, unknown>).map(([key, nestedValue]) => [\n        key,\n        cloneValue(nestedValue),\n      ]),\n    );\n  }\n\n  return value;\n}\n\nfunction cloneMetadata(\n  metadata: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n  if (metadata === undefined) return undefined;\n  if (typeof globalThis.structuredClone === 'function') {\n    return globalThis.structuredClone(metadata);\n  }\n\n  return cloneValue(metadata) as Record<string, unknown>;\n}\n\nfunction cloneRole(role: RbacRole): RbacRole {\n  return {\n    id: role.id,\n    key: role.key,\n    tenantId: normalizeTenantId(role.tenantId),\n    permissions: [...role.permissions],\n    ...(role.name !== undefined ? { name: role.name } : {}),\n    ...(role.description !== undefined ? { description: role.description } : {}),\n    ...(role.isSystem !== undefined ? { isSystem: role.isSystem } : {}),\n  };\n}\n\nfunction cloneBinding(binding: RbacRoleBinding): RbacRoleBinding {\n  const cloned: RbacRoleBinding = {\n    id: binding.id,\n    tenantId: normalizeTenantId(binding.tenantId),\n    subjectType: binding.subjectType,\n    subjectId: binding.subjectId,\n    roleId: binding.roleId,\n    resourceType: binding.resourceType ?? null,\n    resourceId: binding.resourceId ?? null,\n    expiresAt: cloneDate(binding.expiresAt),\n    revokedAt: cloneDate(binding.revokedAt),\n  };\n  const metadata = cloneMetadata(binding.metadata);\n\n  if (metadata !== undefined) {\n    cloned.metadata = metadata;\n  }\n\n  return cloned;\n}\n\nfunction bindingResource(resource: RbacResourceRef | undefined): {\n  resourceType: string | null;\n  resourceId: string | null;\n} {\n  return resource\n    ? { resourceType: resource.type, resourceId: resource.id }\n    : { resourceType: null, resourceId: null };\n}\n\nfunction isBindingActive(binding: RbacRoleBinding, now: Date): boolean {\n  if (binding.revokedAt) return false;\n  if (!binding.expiresAt) return true;\n\n  return binding.expiresAt.getTime() >= now.getTime();\n}\n\nfunction samePermissions(stored: string[], requested: string[]): boolean {\n  const left = [...stored].sort();\n  const right = [...requested].sort();\n\n  return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction roleInputChanges(role: RbacRole, input: UpsertRoleInput): boolean {\n  if (input.key !== undefined && input.key !== role.key) return true;\n  if (\n    input.tenantId !== undefined &&\n    normalizeTenantId(input.tenantId) !== normalizeTenantId(role.tenantId)\n  ) {\n    return true;\n  }\n  if (input.name !== undefined && input.name !== role.name) return true;\n  if (input.description !== undefined && input.description !== role.description) return true;\n  if (input.isSystem !== undefined && input.isSystem !== (role.isSystem ?? false)) return true;\n\n  return input.permissions !== undefined && !samePermissions(role.permissions, input.permissions);\n}\n\nexport class InMemoryRbacStorage implements RbacStorage, RbacStorageRoleLookupCapability {\n  private roleSequence = 0;\n  private bindingSequence = 0;\n  private readonly roles = new Map<string, RbacRole>();\n  private readonly bindings = new Map<string, RbacRoleBinding>();\n\n  readonly mutationResults: RbacStorageMutationCapability = {\n    createRole: async (input: CreateRoleInput) => {\n      const canonicalInput = canonicalizeUpsertRoleInput(input) as CreateRoleInput;\n      const existing = this.findStoredRole(canonicalInput.tenantId, canonicalInput.key);\n      if (existing && !roleInputChanges(existing, canonicalInput)) {\n        return { outcome: 'no-op', value: cloneRole(existing) };\n      }\n\n      const value = await this.upsertRole(canonicalInput);\n\n      return {\n        outcome: existing === undefined ? 'created' : 'updated',\n        value,\n      };\n    },\n    updateRole: async (input: UpdateRoleInput) => {\n      const canonicalInput = canonicalizeUpsertRoleInput(input) as UpdateRoleInput;\n      const existing = this.roles.get(canonicalInput.roleId);\n      if (!existing) return { outcome: 'conflict', reason: 'role_not_found' };\n      if (!roleInputChanges(existing, canonicalInput)) {\n        return { outcome: 'no-op', value: cloneRole(existing) };\n      }\n\n      const value = await this.upsertRole(canonicalInput);\n\n      return { outcome: 'updated', value };\n    },\n    deleteRole: async (input: DeleteRoleInput) => {\n      const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n      if (!this.roles.has(roleId)) return { outcome: 'no-op' };\n\n      await this.deleteRole({ roleId });\n\n      return { outcome: 'deleted' };\n    },\n    grantPermission: async (input: GrantPermissionInput) => {\n      const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n      const role = this.roles.get(roleId);\n      if (!role) return { outcome: 'conflict', reason: 'role_not_found' };\n\n      const permission = normalizePermission(input.permission);\n      if (role.permissions.includes(permission)) return { outcome: 'no-op' };\n\n      await this.grantPermission({ roleId, permission });\n\n      return { outcome: 'created' };\n    },\n    revokePermission: async (input: RevokePermissionInput) => {\n      const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n      const role = this.roles.get(roleId);\n      if (!role) return { outcome: 'conflict', reason: 'role_not_found' };\n\n      const permission = normalizePermission(input.permission);\n      if (!role.permissions.includes(permission)) return { outcome: 'no-op' };\n\n      await this.revokePermission({ roleId, permission });\n\n      return { outcome: 'deleted' };\n    },\n    assignRole: async (input: AssignRoleStorageInput) => {\n      const canonicalInput = canonicalizeAssignInput(input);\n      if (!this.roles.has(canonicalInput.roleId)) {\n        return { outcome: 'conflict', reason: 'role_not_found' };\n      }\n\n      const existing = this.findStoredBinding(canonicalInput);\n      const before = existing ? cloneBinding(existing) : undefined;\n      const value = await this.assignRole(canonicalInput);\n\n      return {\n        outcome:\n          before === undefined ? 'created' : isDeepStrictEqual(before, value) ? 'no-op' : 'updated',\n        value,\n      };\n    },\n    revokeRole: async (input: RevokeRoleStorageInput) => {\n      const bindingId = canonicalizeIdentifier(input.bindingId, 'bindingId');\n      const binding = this.bindings.get(bindingId);\n      if (!binding || binding.revokedAt) return { outcome: 'no-op' };\n\n      await this.revokeRole({ ...input, bindingId });\n\n      return { outcome: 'updated' };\n    },\n  };\n\n  findRole(input: FindRoleInput): Promise<RbacRole | null> {\n    const tenantId = normalizeTenantId(input.tenantId);\n    const key = canonicalizeIdentifier(input.key, 'role key');\n    const role = [...this.roles.values()].find(\n      (candidate) => normalizeTenantId(candidate.tenantId) === tenantId && candidate.key === key,\n    );\n\n    return Promise.resolve(role ? cloneRole(role) : null);\n  }\n\n  findRoleById(input: FindRoleByIdInput): Promise<RbacRole | null> {\n    const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n    const role = this.roles.get(roleId);\n\n    return Promise.resolve(role ? cloneRole(role) : null);\n  }\n\n  listRoles(input: ListRolesInput): Promise<RbacRole[]> {\n    const roles = [...this.roles.values()].filter((role) => {\n      if (input.tenantId === undefined) return true;\n\n      return normalizeTenantId(role.tenantId) === normalizeTenantId(input.tenantId);\n    });\n\n    return Promise.resolve(roles.map(cloneRole));\n  }\n\n  upsertRole(input: UpsertRoleInput): Promise<RbacRole> {\n    const canonicalInput = canonicalizeUpsertRoleInput(input);\n\n    if ('roleId' in canonicalInput) {\n      const existing = this.roles.get(canonicalInput.roleId);\n      const role = existing ?? {\n        id: canonicalInput.roleId,\n        key: canonicalInput.key ?? canonicalInput.roleId,\n        tenantId: normalizeTenantId(canonicalInput.tenantId),\n        permissions: normalizePermissions(canonicalInput.permissions ?? []),\n      };\n\n      const updated: RbacRole = {\n        ...role,\n        ...(canonicalInput.key !== undefined ? { key: canonicalInput.key } : {}),\n        ...(canonicalInput.tenantId !== undefined\n          ? { tenantId: normalizeTenantId(canonicalInput.tenantId) }\n          : {}),\n        ...(canonicalInput.name !== undefined ? { name: canonicalInput.name } : {}),\n        ...(canonicalInput.description !== undefined\n          ? { description: canonicalInput.description }\n          : {}),\n        ...(canonicalInput.isSystem !== undefined ? { isSystem: canonicalInput.isSystem } : {}),\n        ...(canonicalInput.permissions !== undefined\n          ? { permissions: normalizePermissions(canonicalInput.permissions) }\n          : { permissions: [...role.permissions] }),\n      };\n      const duplicateRole = this.findStoredRole(updated.tenantId, updated.key);\n\n      if (duplicateRole && duplicateRole.id !== updated.id) {\n        return Promise.reject(\n          new RbacConfigError({\n            operation: 'upsertRole',\n            reason: 'duplicate_role_key',\n            tenantId: updated.tenantId,\n            key: updated.key,\n            roleId: updated.id,\n            conflictingRoleId: duplicateRole.id,\n          }),\n        );\n      }\n\n      this.roles.set(updated.id, updated);\n\n      return Promise.resolve(cloneRole(updated));\n    }\n\n    const tenantId = normalizeTenantId(canonicalInput.tenantId);\n    const existing = [...this.roles.values()].find(\n      (role) => normalizeTenantId(role.tenantId) === tenantId && role.key === canonicalInput.key,\n    );\n    const role: RbacRole = {\n      id: existing?.id ?? this.nextRoleId(),\n      key: canonicalInput.key,\n      tenantId,\n      permissions: normalizePermissions(canonicalInput.permissions),\n      ...(canonicalInput.name !== undefined\n        ? { name: canonicalInput.name }\n        : existing?.name !== undefined\n          ? { name: existing.name }\n          : {}),\n      ...(canonicalInput.description !== undefined\n        ? { description: canonicalInput.description }\n        : existing?.description !== undefined\n          ? { description: existing.description }\n          : {}),\n      ...(canonicalInput.isSystem !== undefined\n        ? { isSystem: canonicalInput.isSystem }\n        : existing?.isSystem !== undefined\n          ? { isSystem: existing.isSystem }\n          : {}),\n    };\n\n    this.roles.set(role.id, role);\n\n    return Promise.resolve(cloneRole(role));\n  }\n\n  deleteRole(input: DeleteRoleInput): Promise<void> {\n    const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n    this.roles.delete(roleId);\n    for (const [bindingId, binding] of this.bindings.entries()) {\n      if (binding.roleId === roleId) {\n        this.bindings.delete(bindingId);\n      }\n    }\n\n    return Promise.resolve();\n  }\n\n  grantPermission(input: GrantPermissionInput): Promise<void> {\n    const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n    const role = this.roles.get(roleId);\n    if (!role) return Promise.resolve();\n\n    const permission = normalizePermission(input.permission);\n    if (role.permissions.includes(permission)) return Promise.resolve();\n\n    role.permissions = [...role.permissions, permission];\n\n    return Promise.resolve();\n  }\n\n  revokePermission(input: RevokePermissionInput): Promise<void> {\n    const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n    const role = this.roles.get(roleId);\n    if (!role) return Promise.resolve();\n\n    const permission = normalizePermission(input.permission);\n    role.permissions = role.permissions.filter((candidate) => candidate !== permission);\n\n    return Promise.resolve();\n  }\n\n  listRolePermissions(input: ListRolePermissionsInput): Promise<string[]> {\n    const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n    return Promise.resolve([...(this.roles.get(roleId)?.permissions ?? [])]);\n  }\n\n  assignRole(input: AssignRoleStorageInput): Promise<RbacRoleBinding> {\n    const canonicalInput = canonicalizeAssignInput(input);\n\n    if (!this.roles.has(canonicalInput.roleId)) {\n      return Promise.reject(new RbacRoleNotFoundError({ roleId: canonicalInput.roleId }));\n    }\n\n    const tenantId = normalizeTenantId(canonicalInput.tenantId);\n    const { resourceType, resourceId } = bindingResource(canonicalInput.resource);\n    const expiresAt = cloneDate(canonicalInput.expiresAt);\n    const now = new Date();\n    const existing = [...this.bindings.values()].find(\n      (binding) =>\n        !binding.revokedAt &&\n        normalizeTenantId(binding.tenantId) === tenantId &&\n        binding.subjectType === canonicalInput.subject.type &&\n        binding.subjectId === canonicalInput.subject.id &&\n        binding.roleId === canonicalInput.roleId &&\n        (binding.resourceType ?? null) === resourceType &&\n        (binding.resourceId ?? null) === resourceId,\n    );\n\n    if (existing) {\n      if (!isBindingActive(existing, now)) {\n        existing.expiresAt = expiresAt;\n        existing.revokedAt = null;\n        const metadata = cloneMetadata(canonicalInput.metadata);\n        if (metadata !== undefined) {\n          existing.metadata = metadata;\n        } else {\n          delete existing.metadata;\n        }\n      }\n\n      return Promise.resolve(cloneBinding(existing));\n    }\n\n    const binding: RbacRoleBinding = {\n      id: this.nextBindingId(),\n      tenantId,\n      subjectType: canonicalInput.subject.type,\n      subjectId: canonicalInput.subject.id,\n      roleId: canonicalInput.roleId,\n      resourceType,\n      resourceId,\n      expiresAt,\n      revokedAt: null,\n    };\n    const metadata = cloneMetadata(canonicalInput.metadata);\n\n    if (metadata !== undefined) {\n      binding.metadata = metadata;\n    }\n\n    this.bindings.set(binding.id, binding);\n\n    return Promise.resolve(cloneBinding(binding));\n  }\n\n  revokeRole(input: RevokeRoleStorageInput): Promise<void> {\n    const bindingId = canonicalizeIdentifier(input.bindingId, 'bindingId');\n    const binding = this.bindings.get(bindingId);\n    if (!binding || binding.revokedAt) return Promise.resolve();\n\n    binding.revokedAt = new Date(input.revokedAt ?? Date.now());\n\n    return Promise.resolve();\n  }\n\n  listBindings(input: ListBindingsStorageInput): Promise<RbacRoleBinding[]> {\n    const subject = canonicalizeSubject(input.subject);\n    const tenantId = canonicalizeTenantId(input.tenantId);\n    const bindings = [...this.bindings.values()].filter((binding) => {\n      if (binding.subjectType !== subject.type || binding.subjectId !== subject.id) {\n        return false;\n      }\n      if (input.tenantId === undefined) return true;\n\n      return normalizeTenantId(binding.tenantId) === normalizeTenantId(tenantId);\n    });\n\n    return Promise.resolve(bindings.map(cloneBinding));\n  }\n\n  listEffectiveRoles(input: ListEffectiveRolesInput): Promise<RbacEffectiveRole[]> {\n    return Promise.resolve(this.collectEffectiveRoles(input));\n  }\n\n  listEffectivePermissions(\n    input: ListEffectivePermissionsInput,\n  ): Promise<RbacEffectivePermission[]> {\n    const effectiveRoles = this.collectEffectiveRoles(input);\n\n    return Promise.resolve(\n      effectiveRoles.flatMap((effectiveRole) => {\n        const role = this.roles.get(effectiveRole.roleId);\n        if (!role) return [];\n\n        return role.permissions.map((permission) => ({\n          ...effectiveRole,\n          permission,\n        }));\n      }),\n    );\n  }\n\n  private collectEffectiveRoles(input: ListEffectiveRolesInput): RbacEffectiveRole[] {\n    const canonicalInput: ListEffectiveRolesInput = {\n      ...input,\n      subject: canonicalizeSubject(input.subject),\n      tenantId: canonicalizeTenantId(input.tenantId),\n      ...(input.resource !== undefined ? { resource: canonicalizeResource(input.resource) } : {}),\n    };\n    const now = canonicalInput.now ?? new Date();\n\n    return [...this.bindings.values()]\n      .filter((binding) => this.isEffectiveBinding(binding, canonicalInput, now))\n      .map((binding) => {\n        const role = this.roles.get(binding.roleId);\n\n        if (!role) return null;\n\n        return this.toEffectiveRole(binding, role);\n      })\n      .filter((role): role is RbacEffectiveRole => role !== null);\n  }\n\n  private isEffectiveBinding(\n    binding: RbacRoleBinding,\n    input: ListEffectiveRolesInput,\n    now: Date,\n  ): boolean {\n    if (binding.subjectType !== input.subject.type || binding.subjectId !== input.subject.id) {\n      return false;\n    }\n    if (normalizeTenantId(binding.tenantId) !== normalizeTenantId(input.tenantId)) {\n      return false;\n    }\n    if (!isBindingActive(binding, now)) {\n      return false;\n    }\n    const role = this.roles.get(binding.roleId);\n    if (!role) {\n      return false;\n    }\n    if (normalizeTenantId(role.tenantId) !== normalizeTenantId(binding.tenantId)) {\n      return false;\n    }\n\n    const bindingResourceType = binding.resourceType ?? null;\n    const bindingResourceId = binding.resourceId ?? null;\n\n    if (!input.resource) {\n      return bindingResourceType === null && bindingResourceId === null;\n    }\n\n    return (\n      (bindingResourceType === null && bindingResourceId === null) ||\n      (bindingResourceType === input.resource.type && bindingResourceId === input.resource.id)\n    );\n  }\n\n  private toEffectiveRole(binding: RbacRoleBinding, role: RbacRole): RbacEffectiveRole {\n    return {\n      roleKey: role.key,\n      roleId: role.id,\n      bindingId: binding.id,\n      tenantId: normalizeTenantId(binding.tenantId),\n      resourceType: binding.resourceType ?? null,\n      resourceId: binding.resourceId ?? null,\n      expiresAt: cloneDate(binding.expiresAt),\n    };\n  }\n\n  private findStoredRole(tenantId: string | null | undefined, key: string): RbacRole | undefined {\n    const normalizedTenantId = normalizeTenantId(tenantId);\n\n    return [...this.roles.values()].find(\n      (role) => normalizeTenantId(role.tenantId) === normalizedTenantId && role.key === key,\n    );\n  }\n\n  private findStoredBinding(input: AssignRoleStorageInput): RbacRoleBinding | undefined {\n    const tenantId = normalizeTenantId(input.tenantId);\n    const { resourceType, resourceId } = bindingResource(input.resource);\n\n    return [...this.bindings.values()].find(\n      (binding) =>\n        !binding.revokedAt &&\n        normalizeTenantId(binding.tenantId) === tenantId &&\n        binding.subjectType === input.subject.type &&\n        binding.subjectId === input.subject.id &&\n        binding.roleId === input.roleId &&\n        (binding.resourceType ?? null) === resourceType &&\n        (binding.resourceId ?? null) === resourceId,\n    );\n  }\n\n  private nextRoleId(): string {\n    let roleId: string;\n\n    do {\n      this.roleSequence += 1;\n      roleId = `role_${this.roleSequence}`;\n    } while (this.roles.has(roleId));\n\n    return roleId;\n  }\n\n  private nextBindingId(): string {\n    this.bindingSequence += 1;\n\n    return `binding_${this.bindingSequence}`;\n  }\n}\n","import {\n  ForbiddenException,\n  InternalServerErrorException,\n  UnauthorizedException,\n} from '@nestjs/common';\nimport type { RbacError } from './rbac.error';\n\nexport function mapRbacErrorToHttpException(error: RbacError) {\n  const response = { message: error.message, code: error.code };\n\n  switch (error.code) {\n    case 'RBAC_CONFIG_ERROR':\n    case 'RBAC_STORAGE_ERROR':\n      return new InternalServerErrorException(response);\n    case 'RBAC_SUBJECT_MISSING':\n      return new UnauthorizedException(response);\n    case 'RBAC_TENANT_MISSING':\n    case 'RBAC_RESOURCE_MISSING':\n    case 'RBAC_PERMISSION_DENIED':\n    case 'RBAC_ROLE_NOT_FOUND':\n    case 'RBAC_PERMISSION_NOT_FOUND':\n    case 'RBAC_BINDING_NOT_FOUND':\n      return new ForbiddenException(response);\n    default:\n      return assertNever(error.code);\n  }\n}\n\nfunction assertNever(_code: never): never {\n  void _code;\n  throw new Error('Unhandled RBAC error code');\n}\n","export type RbacErrorCode =\n  | 'RBAC_CONFIG_ERROR'\n  | 'RBAC_SUBJECT_MISSING'\n  | 'RBAC_TENANT_MISSING'\n  | 'RBAC_RESOURCE_MISSING'\n  | 'RBAC_PERMISSION_DENIED'\n  | 'RBAC_ROLE_NOT_FOUND'\n  | 'RBAC_PERMISSION_NOT_FOUND'\n  | 'RBAC_BINDING_NOT_FOUND'\n  | 'RBAC_STORAGE_ERROR';\n\nexport interface RbacErrorOptions {\n  details?: Record<string, unknown> | undefined;\n  cause?: unknown;\n}\n\nexport interface RbacErrorCauseOptions {\n  cause?: unknown;\n}\n\nexport class RbacError extends Error {\n  constructor(\n    message: string,\n    public readonly code: RbacErrorCode,\n    public readonly status?: number,\n    options: RbacErrorOptions = {},\n  ) {\n    super(message, { cause: options.cause });\n    this.name = new.target.name;\n    if (options.details !== undefined) {\n      this.details = options.details;\n    }\n  }\n\n  public readonly details?: Record<string, unknown>;\n}\n\nexport class RbacConfigError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('RBAC configuration error', 'RBAC_CONFIG_ERROR', 500, {\n      details,\n      cause: options.cause,\n    });\n  }\n}\n\nexport class RbacSubjectMissingError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('Subject missing', 'RBAC_SUBJECT_MISSING', 401, { details, cause: options.cause });\n  }\n}\n\nexport class RbacTenantMissingError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('Tenant missing', 'RBAC_TENANT_MISSING', 403, { details, cause: options.cause });\n  }\n}\n\nexport class RbacResourceMissingError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('Resource missing', 'RBAC_RESOURCE_MISSING', 403, { details, cause: options.cause });\n  }\n}\n\nexport class RbacPermissionDeniedError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('Permission denied', 'RBAC_PERMISSION_DENIED', 403, {\n      details,\n      cause: options.cause,\n    });\n  }\n}\n\nexport class RbacRoleNotFoundError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('Role not found', 'RBAC_ROLE_NOT_FOUND', 403, { details, cause: options.cause });\n  }\n}\n\n/**\n * @deprecated No package operation throws this error. It remains constructible\n * and HTTP-mappable until a separate breaking release.\n */\nexport class RbacPermissionNotFoundError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('Permission not found', 'RBAC_PERMISSION_NOT_FOUND', 403, {\n      details,\n      cause: options.cause,\n    });\n  }\n}\n\n/**\n * @deprecated No package operation throws this error. It remains constructible\n * and HTTP-mappable until a separate breaking release.\n */\nexport class RbacBindingNotFoundError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('Binding not found', 'RBAC_BINDING_NOT_FOUND', 403, { details, cause: options.cause });\n  }\n}\n\nexport class RbacStorageError extends RbacError {\n  constructor(details?: Record<string, unknown>, options: RbacErrorCauseOptions = {}) {\n    super('RBAC storage error', 'RBAC_STORAGE_ERROR', 500, { details, cause: options.cause });\n  }\n}\n","export function assertNonEmptyString(value: string | null | undefined, name: string): string {\n  if (!value || value.trim() === '') {\n    throw new Error(`${name} must be a non-empty string`);\n  }\n  return value.trim();\n}\n","const PERMISSION_RE = /^(?:\\*|[a-zA-Z0-9_-]+(?:\\.[a-zA-Z0-9_-]+)*(?:\\.\\*)?)$/;\n\nexport function normalizePermission(permission: string): string {\n  const normalized = permission.trim();\n  if (!PERMISSION_RE.test(normalized)) {\n    throw new Error(`Invalid permission: ${permission}`);\n  }\n  return normalized;\n}\n\nexport function normalizePermissions(permissions: string[]): string[] {\n  return [...new Set(permissions.map(normalizePermission))];\n}\n","import { normalizePermission } from './normalize';\n\nexport function matchesPermission(granted: string, required: string): boolean {\n  const normalizedGranted = normalizePermission(granted);\n  const normalizedRequired = normalizePermission(required);\n\n  if (normalizedGranted === '*') return true;\n  if (normalizedGranted === normalizedRequired) return true;\n  if (normalizedGranted.endsWith('.*')) {\n    const prefix = normalizedGranted.slice(0, -1);\n    return normalizedRequired.startsWith(prefix);\n  }\n  return false;\n}\n","import type { RbacResourceRef } from '../interfaces';\n\nexport interface RbacStoredResourceRef {\n  resourceType?: string | null | undefined;\n  resourceId?: string | null | undefined;\n}\n\nfunction storedResource(resource: RbacResourceRef | RbacStoredResourceRef | undefined): {\n  type: string | null;\n  id: string | null;\n} {\n  if (!resource) return { type: null, id: null };\n  if ('type' in resource) return { type: resource.type, id: resource.id };\n\n  return {\n    type: resource.resourceType ?? null,\n    id: resource.resourceId ?? null,\n  };\n}\n\nexport function matchesResource(\n  granted: RbacResourceRef | RbacStoredResourceRef | undefined,\n  required: RbacResourceRef | undefined,\n): boolean {\n  const grantedResource = storedResource(granted);\n\n  if (!required) {\n    return grantedResource.type === null && grantedResource.id === null;\n  }\n\n  return (\n    (grantedResource.type === null && grantedResource.id === null) ||\n    (grantedResource.type === required.type && grantedResource.id === required.id)\n  );\n}\n","import type { RbacResourceRef, RbacSubject } from '../interfaces';\nimport { assertNonEmptyString } from './assertions';\n\nexport function canonicalizeIdentifier(value: string, name: string): string {\n  return assertNonEmptyString(value, name);\n}\n\nexport function isCanonicalIdentifier(value: unknown): value is string {\n  return typeof value === 'string' && value.trim() !== '' && value === value.trim();\n}\n\nexport function canonicalizeTenantId(\n  tenantId: string | null | undefined,\n  name = 'tenantId',\n): string | null | undefined {\n  return tenantId == null ? tenantId : canonicalizeIdentifier(tenantId, name);\n}\n\nexport function canonicalizeSubject(subject: RbacSubject): RbacSubject {\n  const isApiKey = subject.type === 'api_key';\n  const type = canonicalizeIdentifier(subject.type, 'subject.type');\n  const id = isApiKey\n    ? preserveOpaqueIdentifier(subject.id, 'subject.id')\n    : canonicalizeIdentifier(subject.id, 'subject.id');\n  const tenantId =\n    isApiKey && typeof subject.tenantId === 'string'\n      ? preserveOpaqueIdentifier(subject.tenantId, 'subject.tenantId')\n      : canonicalizeTenantId(subject.tenantId, 'subject.tenantId');\n\n  return {\n    ...subject,\n    type,\n    id,\n    ...(tenantId !== undefined ? { tenantId } : {}),\n  };\n}\n\nexport function canonicalizeResource(resource: RbacResourceRef): RbacResourceRef {\n  return {\n    type: canonicalizeIdentifier(resource.type, 'resource.type'),\n    id: canonicalizeIdentifier(resource.id, 'resource.id'),\n  };\n}\n\nfunction preserveOpaqueIdentifier(value: string, name: string): string {\n  assertNonEmptyString(value, name);\n  return value;\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport { RBAC_OPTIONS } from './constants';\nimport {\n  RbacConfigError,\n  RbacPermissionDeniedError,\n  RbacRoleNotFoundError,\n  RbacStorageError,\n} from './errors';\nimport type {\n  AssignRoleInput,\n  AssignRoleStorageInput,\n  CreateRoleInput,\n  DeleteRoleInput,\n  GrantPermissionInput,\n  ListBindingsInput,\n  ListPermissionsInput,\n  ListRolesInput,\n  RbacCanInput,\n  RbacEffectivePermission,\n  RbacEffectiveRole,\n  RbacModuleOptions,\n  RbacResourceRef,\n  RbacRole,\n  RbacRoleBinding,\n  RbacServiceDecision,\n  RbacSubject,\n  RevokePermissionInput,\n  RevokeRoleInput,\n  UpdateRoleInput,\n} from './interfaces';\nimport { matchesPermission, matchesResource, normalizePermission } from './utils';\nimport {\n  canonicalizeIdentifier,\n  canonicalizeSubject,\n  canonicalizeTenantId,\n  isCanonicalIdentifier,\n} from './utils/canonicalization';\nimport { RbacServiceDecisionFactory } from './service/rbac-service-decision.factory';\nimport { RbacServiceInput } from './service/rbac-service-input';\nimport { RbacServiceMutationSupport } from './service/rbac-service-mutation-support';\nimport { assertFiniteDate, isRbacSubject } from './utils/runtime-validation';\n\nfunction unique(values: string[]): string[] {\n  return [...new Set(values)];\n}\n\nfunction auditResource(resource: RbacResourceRef | undefined): RbacResourceRef | undefined {\n  return resource ? { type: resource.type, id: resource.id } : undefined;\n}\n\n@Injectable()\nexport class RbacService {\n  private readonly decisions: RbacServiceDecisionFactory;\n  private readonly inputs: RbacServiceInput;\n  private readonly mutations: RbacServiceMutationSupport;\n\n  constructor(@Inject(RBAC_OPTIONS) private readonly options: RbacModuleOptions) {\n    this.decisions = new RbacServiceDecisionFactory();\n    this.inputs = new RbacServiceInput(options);\n    this.mutations = new RbacServiceMutationSupport(options);\n  }\n\n  async can(input: RbacCanInput): Promise<RbacServiceDecision> {\n    const canonicalInput = this.inputs.canonicalizeCan(input);\n    const subject = isRbacSubject(canonicalInput.subject) ? canonicalInput.subject : undefined;\n    const tenant = this.inputs.resolveTenant(canonicalInput, subject);\n\n    if (!subject) {\n      return this.decisions.create(canonicalInput, 'denied_subject_missing', {\n        allowed: false,\n        tenantId: tenant.tenantId,\n      });\n    }\n\n    if (tenant.conflict) {\n      return this.decisions.create(canonicalInput, 'denied_tenant_conflict', {\n        allowed: false,\n        subject,\n        tenantId: tenant.tenantId,\n      });\n    }\n\n    if (tenant.missing) {\n      return this.decisions.create(canonicalInput, 'denied_tenant_missing', {\n        allowed: false,\n        subject,\n        tenantId: tenant.tenantId,\n      });\n    }\n\n    if (this.inputs.isRoleCheck(canonicalInput)) {\n      return this.canRole(canonicalInput, subject, tenant.tenantId);\n    }\n\n    return this.canPermission(canonicalInput, subject, tenant.tenantId);\n  }\n\n  async assertCan(input: RbacCanInput): Promise<void> {\n    const decision = await this.can(input);\n\n    if (decision.allowed) return;\n\n    throw new RbacPermissionDeniedError({ decision: this.decisions.sanitize(decision) });\n  }\n\n  async createRole(input: CreateRoleInput): Promise<RbacRole> {\n    const canonicalInput = this.inputs.canonicalizeCreateRole(input);\n    const result = this.options.storage.mutationResults\n      ? await this.options.storage.mutationResults.createRole(canonicalInput)\n      : {\n          outcome: 'created' as const,\n          value: await this.options.storage.upsertRole(canonicalInput),\n        };\n    if (result.outcome === 'conflict') {\n      throw new RbacConfigError({ operation: 'createRole', reason: result.reason ?? 'conflict' });\n    }\n    const role = this.mutations.requireValue('createRole', result);\n    if (result.outcome === 'no-op') return role;\n    const created = result.outcome === 'created';\n    if (!created && result.outcome !== 'updated') {\n      throw new RbacConfigError({ operation: 'createRole', reason: 'invalid_mutation_outcome' });\n    }\n    await this.mutations.audit({\n      type: created ? 'rbac.role.created' : 'rbac.role.updated',\n      tenantId: role.tenantId,\n      metadata: { roleId: role.id, roleKey: role.key },\n    });\n    await this.mutations.publish({\n      type: created ? 'role.created' : 'role.updated',\n      tenantId: role.tenantId,\n      roleId: role.id,\n      roleKey: role.key,\n      permissions: role.permissions,\n    });\n\n    return role;\n  }\n\n  async updateRole(input: UpdateRoleInput): Promise<RbacRole> {\n    const canonicalInput = this.inputs.canonicalizeUpdateRole(input);\n    const result = this.options.storage.mutationResults\n      ? await this.options.storage.mutationResults.updateRole(canonicalInput)\n      : {\n          outcome: 'updated' as const,\n          value: await this.options.storage.upsertRole(canonicalInput),\n        };\n    if (result.outcome === 'conflict' && result.reason === 'role_not_found') {\n      throw new RbacRoleNotFoundError({ roleId: canonicalInput.roleId });\n    }\n    const role = this.mutations.requireValue('updateRole', result);\n    if (result.outcome === 'no-op') return role;\n    if (result.outcome !== 'updated') {\n      throw new RbacConfigError({ operation: 'updateRole', reason: 'invalid_mutation_outcome' });\n    }\n    await this.mutations.audit({\n      type: 'rbac.role.updated',\n      tenantId: role.tenantId,\n      metadata: { roleId: role.id, roleKey: role.key },\n    });\n    await this.mutations.publish({\n      type: 'role.updated',\n      tenantId: role.tenantId,\n      roleId: role.id,\n      roleKey: role.key,\n      permissions: role.permissions,\n    });\n\n    return role;\n  }\n\n  async deleteRole(input: DeleteRoleInput): Promise<void> {\n    const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n    const result = this.options.storage.mutationResults\n      ? await this.options.storage.mutationResults.deleteRole({ roleId })\n      : await this.mutations.legacy(() => this.options.storage.deleteRole({ roleId }), 'deleted');\n    if (result.outcome === 'no-op' || result.outcome === 'conflict') return;\n    if (result.outcome !== 'deleted') {\n      throw new RbacConfigError({ operation: 'deleteRole', reason: 'invalid_mutation_outcome' });\n    }\n    await this.mutations.audit({\n      type: 'rbac.role.deleted',\n      metadata: { roleId },\n    });\n    await this.mutations.publish({\n      type: 'role.deleted',\n      roleId,\n    });\n  }\n\n  async grantPermission(input: GrantPermissionInput): Promise<void> {\n    const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n    const permission = normalizePermission(input.permission);\n    const result = this.options.storage.mutationResults\n      ? await this.options.storage.mutationResults.grantPermission({ roleId, permission })\n      : await this.mutations.legacy(\n          () => this.options.storage.grantPermission({ roleId, permission }),\n          'created',\n        );\n    if (result.outcome === 'no-op' || result.outcome === 'conflict') return;\n    if (result.outcome !== 'created' && result.outcome !== 'updated') {\n      throw new RbacConfigError({\n        operation: 'grantPermission',\n        reason: 'invalid_mutation_outcome',\n      });\n    }\n    await this.mutations.audit({\n      type: 'rbac.permission.granted',\n      metadata: { roleId, permission },\n    });\n    await this.mutations.publish({\n      type: 'permission.granted',\n      roleId,\n      permissions: [permission],\n    });\n  }\n\n  async revokePermission(input: RevokePermissionInput): Promise<void> {\n    const roleId = canonicalizeIdentifier(input.roleId, 'roleId');\n    const permission = normalizePermission(input.permission);\n    const result = this.options.storage.mutationResults\n      ? await this.options.storage.mutationResults.revokePermission({ roleId, permission })\n      : await this.mutations.legacy(\n          () => this.options.storage.revokePermission({ roleId, permission }),\n          'deleted',\n        );\n    if (result.outcome === 'no-op' || result.outcome === 'conflict') return;\n    if (result.outcome !== 'deleted' && result.outcome !== 'updated') {\n      throw new RbacConfigError({\n        operation: 'revokePermission',\n        reason: 'invalid_mutation_outcome',\n      });\n    }\n    await this.mutations.audit({\n      type: 'rbac.permission.revoked',\n      metadata: { roleId, permission },\n    });\n    await this.mutations.publish({\n      type: 'permission.revoked',\n      roleId,\n      permissions: [permission],\n    });\n  }\n\n  async assignRole(input: AssignRoleInput): Promise<RbacRoleBinding> {\n    const canonicalInput = this.inputs.canonicalizeAssignRole(input);\n    const { roleId, roleKey, role } = await this.resolveAssignRoleIdentifier(canonicalInput);\n    this.inputs.validateAssignRoleBoundary(canonicalInput, role);\n    const storageInput: AssignRoleStorageInput = {\n      tenantId: canonicalInput.tenantId,\n      subject: canonicalInput.subject,\n      roleId,\n      resource: canonicalInput.resource,\n      expiresAt: canonicalInput.expiresAt,\n      metadata: canonicalInput.metadata,\n    };\n    const result = this.options.storage.mutationResults\n      ? await this.options.storage.mutationResults.assignRole(storageInput)\n      : {\n          outcome: 'created' as const,\n          value: await this.options.storage.assignRole(storageInput),\n        };\n    if (result.outcome === 'conflict' && result.reason === 'role_not_found') {\n      throw new RbacRoleNotFoundError({ roleId });\n    }\n    const binding = this.mutations.requireValue('assignRole', result);\n    if (result.outcome === 'no-op') return binding;\n    if (result.outcome !== 'created' && result.outcome !== 'updated') {\n      throw new RbacConfigError({ operation: 'assignRole', reason: 'invalid_mutation_outcome' });\n    }\n    await this.mutations.audit({\n      type: 'rbac.role.assigned',\n      tenantId: binding.tenantId,\n      subjectType: binding.subjectType,\n      subjectId: binding.subjectId,\n      metadata: {\n        bindingId: binding.id,\n        roleId: binding.roleId,\n        ...(roleKey !== undefined ? { roleKey } : {}),\n        ...(canonicalInput.resource !== undefined\n          ? { resource: auditResource(canonicalInput.resource) }\n          : {}),\n      },\n    });\n    await this.mutations.publish({\n      type: 'role.assigned',\n      tenantId: binding.tenantId,\n      subject: { type: binding.subjectType, id: binding.subjectId },\n      roleId: binding.roleId,\n      ...(roleKey !== undefined ? { roleKey } : {}),\n      ...(canonicalInput.resource !== undefined\n        ? { resource: auditResource(canonicalInput.resource) }\n        : {}),\n      bindingId: binding.id,\n    });\n\n    return binding;\n  }\n\n  async revokeRole(input: RevokeRoleInput): Promise<void> {\n    const bindingId = canonicalizeIdentifier(input.bindingId, 'bindingId');\n    if (input.revokedAt !== undefined) {\n      assertFiniteDate(input.revokedAt, 'revokeRole', 'revokedAt');\n    }\n    const storageInput = { ...input, bindingId };\n    const result = this.options.storage.mutationResults\n      ? await this.options.storage.mutationResults.revokeRole(storageInput)\n      : await this.mutations.legacy(() => this.options.storage.revokeRole(storageInput), 'updated');\n    if (result.outcome === 'no-op' || result.outcome === 'conflict') return;\n    if (result.outcome !== 'updated' && result.outcome !== 'deleted') {\n      throw new RbacConfigError({ operation: 'revokeRole', reason: 'invalid_mutation_outcome' });\n    }\n    await this.mutations.audit({\n      type: 'rbac.role.revoked',\n      metadata: { bindingId },\n    });\n    await this.mutations.publish({\n      type: 'role.revoked',\n      bindingId,\n    });\n  }\n\n  listRoles(input: ListRolesInput): Promise<RbacRole[]> {\n    return this.options.storage.listRoles({\n      ...input,\n      ...(input.tenantId !== undefined ? { tenantId: canonicalizeTenantId(input.tenantId) } : {}),\n    });\n  }\n\n  listPermissions(input: ListPermissionsInput): Promise<string[]> {\n    return this.options.storage.listRolePermissions({\n      roleId: canonicalizeIdentifier(input.roleId, 'roleId'),\n    });\n  }\n\n  listBindings(input: ListBindingsInput): Promise<RbacRoleBinding[]> {\n    return this.options.storage.listBindings({\n      ...input,\n      subject: canonicalizeSubject(input.subject),\n      ...(input.tenantId !== undefined ? { tenantId: canonicalizeTenantId(input.tenantId) } : {}),\n    });\n  }\n\n  private async canRole(\n    input: RbacCanInput & { roleKey: string },\n    subject: RbacSubject,\n    tenantId: string | null,\n  ): Promise<RbacServiceDecision> {\n    const roleKey = input.roleKey.trim();\n    if (roleKey === '') {\n      return this.decisions.create(input, 'denied_no_matching_role', {\n        allowed: false,\n        subject,\n        tenantId,\n        matchedRoleKeys: [],\n      });\n    }\n\n    const now = this.inputs.resolveNow(input);\n    try {\n      const roles = await this.listEffectiveRolesForTenant(input, subject, tenantId, now);\n      const matchedRoleKeys = unique(\n        roles.filter((role) => role.roleKey === roleKey).map((role) => role.roleKey),\n      );\n\n      return this.decisions.create(\n        input,\n        matchedRoleKeys.length > 0 ? 'allowed_by_role' : 'denied_no_matching_role',\n        {\n          allowed: matchedRoleKeys.length > 0,\n          subject,\n          tenantId,\n          roleKey,\n          matchedRoleKeys,\n        },\n      );\n    } catch (error) {\n      return this.handleStorageError(input, error, subject, tenantId);\n    }\n  }\n\n  private async canPermission(\n    input: RbacCanInput,\n    subject: RbacSubject,\n    tenantId: string | null,\n  ): Promise<RbacServiceDecision> {\n    const requirement = this.inputs.permissionRequirement(input);\n\n    if (requirement.invalid || requirement.permissions.length === 0) {\n      return this.decisions.create(input, 'denied_no_matching_permission', {\n        allowed: false,\n        subject,\n        tenantId,\n        permission: requirement.permission,\n        permissions: requirement.permissions,\n        mode: requirement.mode,\n        matchedRoleKeys: [],\n        matchedPermissions: [],\n      });\n    }\n\n    const now = this.inputs.resolveNow(input);\n    try {\n      const effectivePermissions = await this.listEffectivePermissionsForTenant(\n        input,\n        subject,\n        tenantId,\n        now,\n      );\n      const matches = this.matchPermissions(effectivePermissions, requirement.permissions);\n      const allowed =\n        requirement.mode === 'all'\n          ? requirement.permissions.every((required) => matches.byRequired.has(required))\n          : matches.matchedPermissions.length > 0;\n      const missingPermissions = requirement.permissions.filter(\n        (required) => !matches.byRequired.has(required),\n      );\n\n      return this.decisions.create(\n        input,\n        allowed ? 'allowed_by_role_permission' : 'denied_no_matching_permission',\n        {\n          allowed,\n          subject,\n          tenantId,\n          permission: requirement.permission,\n          permissions: requirement.permissions,\n          mode: requirement.mode,\n          matchedRoleKeys: matches.matchedRoleKeys,\n          matchedPermissions: matches.matchedPermissions,\n          missingPermissions,\n        },\n      );\n    } catch (error) {\n      return this.handleStorageError(input, error, subject, tenantId);\n    }\n  }\n\n  private matchPermissions(\n    effectivePermissions: RbacEffectivePermission[],\n    requiredPermissions: string[],\n  ): {\n    byRequired: Map<string, RbacEffectivePermission[]>;\n    matchedRoleKeys: string[];\n    matchedPermissions: string[];\n  } {\n    const byRequired = new Map<string, RbacEffectivePermission[]>();\n    const matchedRoleKeys: string[] = [];\n    const matchedPermissions: string[] = [];\n\n    for (const required of requiredPermissions) {\n      const matches = effectivePermissions.filter((effectivePermission) =>\n        matchesPermission(effectivePermission.permission, required),\n      );\n\n      if (matches.length > 0) {\n        byRequired.set(required, matches);\n        matchedRoleKeys.push(...matches.map((match) => match.roleKey));\n        matchedPermissions.push(...matches.map((match) => match.permission));\n      }\n    }\n\n    return {\n      byRequired,\n      matchedRoleKeys: unique(matchedRoleKeys),\n      matchedPermissions: unique(matchedPermissions),\n    };\n  }\n\n  private async resolveAssignRoleIdentifier(\n    input: AssignRoleInput,\n  ): Promise<{ roleId: string; roleKey?: string | undefined; role?: RbacRole | undefined }> {\n    if ('roleId' in input && input.roleId !== undefined) {\n      const roleId = input.roleId.trim();\n      const role = this.assignRoleNeedsResolvedRole() ? await this.findRoleById(roleId) : undefined;\n      if (this.assignRoleNeedsResolvedRole() && role === undefined) {\n        throw new RbacRoleNotFoundError({ roleId });\n      }\n\n      return { roleId, role };\n    }\n\n    const roleKey = input.roleKey.trim();\n    const role = await this.options.storage.findRole({\n      tenantId: input.tenantId,\n      key: roleKey,\n    });\n\n    if (role === null) {\n      throw new RbacRoleNotFoundError({ tenantId: input.tenantId, roleKey });\n    }\n\n    return { roleId: role.id, roleKey, role };\n  }\n\n  private assignRoleNeedsResolvedRole(): boolean {\n    const validation = this.options.writeValidation;\n\n    return (\n      validation?.rejectTenantMismatch === true ||\n      validation?.rejectGlobalRoleInTenantBinding === true\n    );\n  }\n\n  private async findRoleById(roleId: string): Promise<RbacRole | undefined> {\n    if (this.options.storage.findRoleById !== undefined) {\n      return (await this.options.storage.findRoleById({ roleId })) ?? undefined;\n    }\n\n    const roles = await this.options.storage.listRoles({});\n\n    return roles.find((role) => role.id === roleId);\n  }\n\n  private handleStorageError(\n    input: RbacCanInput,\n    error: unknown,\n    subject: RbacSubject,\n    tenantId: string | null,\n  ): Promise<RbacServiceDecision> | RbacServiceDecision {\n    if (this.options.storageErrors === 'throw') {\n      throw new RbacStorageError({ operation: 'can' }, { cause: error });\n    }\n\n    return this.decisions.create(input, 'denied_storage_error', {\n      allowed: false,\n      subject,\n      tenantId,\n    });\n  }\n\n  private async listEffectiveRolesForTenant(\n    input: RbacCanInput,\n    subject: RbacSubject,\n    tenantId: string | null,\n    now: Date,\n  ): Promise<RbacEffectiveRole[]> {\n    const tenantRoles = await this.options.storage.listEffectiveRoles({\n      subject,\n      tenantId,\n      resource: input.resource,\n      now,\n    });\n    const validTenantRoles = this.validEffectiveRecords(tenantRoles, tenantId, input.resource, now);\n\n    if (tenantId === null || this.options.tenant?.allowGlobalRolesInTenant !== true) {\n      return validTenantRoles;\n    }\n\n    const globalRoles = await this.options.storage.listEffectiveRoles({\n      subject,\n      tenantId: null,\n      resource: input.resource,\n      now,\n    });\n\n    return [\n      ...validTenantRoles,\n      ...this.validEffectiveRecords(globalRoles, null, input.resource, now),\n    ];\n  }\n\n  private async listEffectivePermissionsForTenant(\n    input: RbacCanInput,\n    subject: RbacSubject,\n    tenantId: string | null,\n    now: Date,\n  ): Promise<RbacEffectivePermission[]> {\n    const tenantPermissions = await this.options.storage.listEffectivePermissions({\n      subject,\n      tenantId,\n      resource: input.resource,\n      now,\n    });\n    const validTenantPermissions = this.validEffectiveRecords(\n      tenantPermissions,\n      tenantId,\n      input.resource,\n      now,\n    );\n\n    if (tenantId === null || this.options.tenant?.allowGlobalRolesInTenant !== true) {\n      return validTenantPermissions;\n    }\n\n    const globalPermissions = await this.options.storage.listEffectivePermissions({\n      subject,\n      tenantId: null,\n      resource: input.resource,\n      now,\n    });\n\n    return [\n      ...validTenantPermissions,\n      ...this.validEffectiveRecords(globalPermissions, null, input.resource, now),\n    ];\n  }\n\n  private validEffectiveRecords<T extends RbacEffectiveRole>(\n    records: T[],\n    tenantId: string | null,\n    resource: RbacResourceRef | undefined,\n    now: Date,\n  ): T[] {\n    return records.filter((record) => this.isValidEffectiveRecord(record, tenantId, resource, now));\n  }\n\n  private isValidEffectiveRecord(\n    record: unknown,\n    tenantId: string | null,\n    resource: RbacResourceRef | undefined,\n    now: Date,\n  ): record is RbacEffectiveRole {\n    if (record === null || typeof record !== 'object') return false;\n\n    const effectiveRecord = record as Partial<RbacEffectiveRole>;\n    if (\n      !isCanonicalIdentifier(effectiveRecord.roleKey) ||\n      !isCanonicalIdentifier(effectiveRecord.roleId) ||\n      !isCanonicalIdentifier(effectiveRecord.bindingId)\n    ) {\n      return false;\n    }\n    if ((effectiveRecord.tenantId ?? null) !== tenantId) return false;\n    if (\n      effectiveRecord.tenantId !== null &&\n      effectiveRecord.tenantId !== undefined &&\n      !isCanonicalIdentifier(effectiveRecord.tenantId)\n    ) {\n      return false;\n    }\n\n    if ('permission' in effectiveRecord) {\n      const permission = (effectiveRecord as Partial<RbacEffectivePermission>).permission;\n      if (typeof permission !== 'string') {\n        throw new Error('Stored permission must be a canonical string');\n      }\n      let normalizedPermission: string;\n      try {\n        normalizedPermission = normalizePermission(permission);\n      } catch {\n        throw new Error('Stored permission must be a canonical string');\n      }\n      if (normalizedPermission !== permission) {\n        throw new Error('Stored permission must be a canonical string');\n      }\n    }\n\n    const expiresAt = effectiveRecord.expiresAt;\n    if (expiresAt !== null && expiresAt !== undefined) {\n      if (!(expiresAt instanceof Date)) return false;\n\n      const expiresAtTime = expiresAt.getTime();\n      if (!Number.isFinite(expiresAtTime) || expiresAtTime < now.getTime()) return false;\n    }\n\n    const resourceType = effectiveRecord.resourceType ?? null;\n    const resourceId = effectiveRecord.resourceId ?? null;\n    if ((resourceType === null) !== (resourceId === null)) return false;\n    if (\n      resourceType !== null &&\n      (!isCanonicalIdentifier(resourceType) || !isCanonicalIdentifier(resourceId))\n    ) {\n      return false;\n    }\n\n    return matchesResource({ resourceType, resourceId }, resource);\n  }\n}\n","export const RBAC_OPTIONS = Symbol('RBAC_OPTIONS');\nexport const RBAC_STORAGE = Symbol('RBAC_STORAGE');\nexport const RBAC_REQUIREMENTS_METADATA = Symbol('RBAC_REQUIREMENTS_METADATA');\nexport const RBAC_SKIP_METADATA = Symbol('RBAC_SKIP_METADATA');\nexport const RBAC_SUBJECT_REQUEST_KEY = 'rbacSubject';\n","import type {\n  RbacCanInput,\n  RbacServiceDecision,\n  RbacServiceDecisionDetails,\n  RbacServiceDecisionReason,\n  RbacSubject,\n} from '../interfaces';\n\nexport type RbacDecisionOverrides = Partial<RbacServiceDecision> & {\n  allowed: boolean;\n  missingPermissions?: string[] | undefined;\n};\n\nexport class RbacServiceDecisionFactory {\n  create(\n    input: RbacCanInput,\n    reason: RbacServiceDecisionReason,\n    overrides: RbacDecisionOverrides,\n  ): RbacServiceDecision {\n    const decision = {\n      allowed: overrides.allowed,\n      reason,\n      subject: overrides.subject ?? input.subject,\n      tenantId: overrides.tenantId,\n      permission: overrides.permission ?? ('permission' in input ? input.permission : undefined),\n      permissions: overrides.permissions ?? this.rawPermissions(input),\n      roleKey: overrides.roleKey ?? ('roleKey' in input ? input.roleKey : undefined),\n      mode: overrides.mode ?? ('mode' in input ? input.mode : undefined),\n      matchedRoleKeys: overrides.matchedRoleKeys,\n      matchedPermissions: overrides.matchedPermissions,\n      resource: input.resource,\n    };\n\n    return {\n      ...decision,\n      details: overrides.details ?? this.buildDetails(decision, overrides),\n    };\n  }\n\n  sanitize(decision: RbacServiceDecision): RbacServiceDecision {\n    return {\n      ...decision,\n      subject: decision.subject ? this.sanitizeSubject(decision.subject) : undefined,\n    };\n  }\n\n  private rawPermissions(input: RbacCanInput): string[] {\n    const permissions: string[] = [];\n    if ('permission' in input && typeof input.permission === 'string') {\n      permissions.push(input.permission);\n    }\n    if ('permissions' in input && Array.isArray(input.permissions)) {\n      permissions.push(\n        ...input.permissions.filter(\n          (permission): permission is string => typeof permission === 'string',\n        ),\n      );\n    }\n\n    return permissions;\n  }\n\n  private sanitizeSubject(subject: RbacSubject): RbacSubject {\n    return {\n      type: subject.type,\n      id: subject.id,\n      ...(subject.tenantId !== undefined ? { tenantId: subject.tenantId } : {}),\n    };\n  }\n\n  private buildDetails(\n    decision: Omit<RbacServiceDecision, 'details'>,\n    overrides: RbacDecisionOverrides,\n  ): RbacServiceDecisionDetails {\n    const requirement = this.buildRequirementDetails(decision);\n    const matched = this.buildMatchedDetails(decision);\n    const missing = this.buildMissingDetails(decision, overrides);\n\n    return {\n      ...(requirement !== undefined ? { requirement } : {}),\n      ...(matched !== undefined ? { matched } : {}),\n      ...(missing !== undefined ? { missing } : {}),\n      evaluationPath: [this.evaluationStep(decision.reason)],\n      safeMessage: decision.reason,\n    };\n  }\n\n  private buildRequirementDetails(\n    decision: Omit<RbacServiceDecision, 'details'>,\n  ): NonNullable<RbacServiceDecisionDetails['requirement']> | undefined {\n    if (decision.roleKey !== undefined) {\n      return { type: 'role', roleKeys: [decision.roleKey] };\n    }\n\n    if (decision.permissions !== undefined) {\n      return {\n        type: 'permission',\n        permissions: decision.permissions,\n        mode: decision.mode ?? (decision.permissions.length > 1 ? 'all' : 'any'),\n      };\n    }\n\n    return undefined;\n  }\n\n  private buildMatchedDetails(\n    decision: Omit<RbacServiceDecision, 'details'>,\n  ): NonNullable<RbacServiceDecisionDetails['matched']> | undefined {\n    if (decision.matchedRoleKeys === undefined && decision.matchedPermissions === undefined) {\n      return undefined;\n    }\n\n    return {\n      roleKeys: decision.matchedRoleKeys ?? [],\n      ...(decision.matchedPermissions !== undefined\n        ? { permissions: decision.matchedPermissions }\n        : {}),\n    };\n  }\n\n  private buildMissingDetails(\n    decision: Omit<RbacServiceDecision, 'details'>,\n    overrides: RbacDecisionOverrides,\n  ): NonNullable<RbacServiceDecisionDetails['missing']> | undefined {\n    switch (decision.reason) {\n      case 'denied_subject_missing':\n        return { subject: true };\n      case 'denied_tenant_missing':\n        return { tenant: true };\n      case 'denied_tenant_conflict':\n        return undefined;\n      case 'denied_no_matching_role':\n        return decision.roleKey !== undefined ? { roleKeys: [decision.roleKey] } : undefined;\n      case 'denied_no_matching_permission':\n        return { permissions: overrides.missingPermissions ?? decision.permissions ?? [] };\n      default:\n        return undefined;\n    }\n  }\n\n  private evaluationStep(\n    reason: RbacServiceDecisionReason,\n  ): RbacServiceDecisionDetails['evaluationPath'][number] {\n    switch (reason) {\n      case 'allowed_by_role':\n        return { code: 'role_matched', outcome: 'allow' };\n      case 'allowed_by_role_permission':\n        return { code: 'permission_matched', outcome: 'allow' };\n      case 'denied_subject_missing':\n        return { code: 'subject_missing', outcome: 'deny' };\n      case 'denied_tenant_missing':\n        return { code: 'tenant_missing', outcome: 'deny' };\n      case 'denied_tenant_conflict':\n        return { code: 'tenant_conflict', outcome: 'deny' };\n      case 'denied_no_matching_role':\n        return { code: 'role_missing', outcome: 'deny' };\n      case 'denied_no_matching_permission':\n        return { code: 'permission_missing', outcome: 'deny' };\n      case 'denied_storage_error':\n        return { code: 'storage_error', outcome: 'deny' };\n    }\n  }\n}\n","import { RbacConfigError } from '../errors';\nimport type {\n  RbacBuiltInResourceDeclaration,\n  RbacCanInput,\n  RbacRequirement,\n  RbacRequirementMode,\n  RbacResourceRef,\n  RbacSubject,\n  RbacTenantMode,\n} from '../interfaces';\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n  typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst isNonEmptyString = (value: unknown): value is string =>\n  typeof value === 'string' && value.trim() !== '';\n\nconst isRequirementMode = (value: unknown): value is RbacRequirementMode =>\n  value === 'any' || value === 'all';\n\nconst isTenantMode = (value: unknown): value is RbacTenantMode =>\n  value === 'required' || value === 'optional' || value === 'none';\n\nconst fail = (operation: 'can' | 'guard' | 'assignRole' | 'revokeRole', field: string): never => {\n  throw new RbacConfigError({ operation, field, reason: 'invalid_runtime_shape' });\n};\n\nexport const isFiniteDate = (value: unknown): value is Date =>\n  value instanceof Date && Number.isFinite(value.getTime());\n\nexport const isRbacSubject = (value: unknown): value is RbacSubject =>\n  isRecord(value) &&\n  isNonEmptyString(value.type) &&\n  isNonEmptyString(value.id) &&\n  (value.tenantId === undefined || value.tenantId === null || isNonEmptyString(value.tenantId));\n\nexport const isRbacResourceRef = (value: unknown): value is RbacResourceRef =>\n  isRecord(value) && isNonEmptyString(value.type) && isNonEmptyString(value.id);\n\nexport function assertFiniteDate(\n  value: unknown,\n  operation: 'can' | 'assignRole' | 'revokeRole',\n  field: string,\n): asserts value is Date {\n  if (!isFiniteDate(value)) fail(operation, field);\n}\n\nexport function assertCanInput(value: unknown): asserts value is RbacCanInput {\n  const input = isRecord(value) ? value : fail('can', 'input');\n\n  if (input.subject !== undefined && !isRbacSubject(input.subject)) {\n    fail('can', 'subject');\n  }\n  if (\n    input.tenantId !== undefined &&\n    input.tenantId !== null &&\n    !isNonEmptyString(input.tenantId)\n  ) {\n    fail('can', 'tenantId');\n  }\n  if (input.tenantMode !== undefined && !isTenantMode(input.tenantMode)) {\n    fail('can', 'tenantMode');\n  }\n  if (input.resource !== undefined && !isRbacResourceRef(input.resource)) {\n    fail('can', 'resource');\n  }\n  if (input.now !== undefined) {\n    assertFiniteDate(input.now, 'can', 'now');\n  }\n\n  const hasRole = input.roleKey !== undefined;\n  const hasPermission = input.permission !== undefined || input.permissions !== undefined;\n  if (hasRole && hasPermission) {\n    throw new RbacConfigError({\n      reason: 'can() accepts exactly one requirement family per call',\n    });\n  }\n  if (!hasRole && !hasPermission) fail('can', 'requirement');\n\n  if (hasRole) {\n    if (!isNonEmptyString(input.roleKey)) fail('can', 'roleKey');\n    if (input.mode !== undefined) fail('can', 'mode');\n    return;\n  }\n\n  if (input.permission !== undefined && !isNonEmptyString(input.permission)) {\n    fail('can', 'permission');\n  }\n  if (\n    input.permissions !== undefined &&\n    (!Array.isArray(input.permissions) ||\n      input.permissions.some((permission: unknown) => !isNonEmptyString(permission)))\n  ) {\n    fail('can', 'permissions');\n  }\n  if (input.mode !== undefined && !isRequirementMode(input.mode)) {\n    fail('can', 'mode');\n  }\n}\n\nconst isResolverToken = (value: unknown): boolean =>\n  isNonEmptyString(value) || typeof value === 'symbol' || typeof value === 'function';\n\nconst isBuiltInResourceDeclaration = (\n  value: Record<string, unknown>,\n): value is RbacBuiltInResourceDeclaration => {\n  const selectorKeys = ['idParam', 'idHeader', 'idQuery'].filter((key) => key in value);\n\n  return (\n    isNonEmptyString(value.type) &&\n    selectorKeys.length === 1 &&\n    isNonEmptyString(value[selectorKeys[0] as string])\n  );\n};\n\nconst isRequirementResource = (value: unknown): boolean => {\n  if (isResolverToken(value)) return true;\n  if (!isRecord(value)) return false;\n  if ('resolverToken' in value) return isResolverToken(value.resolverToken);\n\n  return isBuiltInResourceDeclaration(value);\n};\n\nconst assertRequirement = (value: unknown, index: number): asserts value is RbacRequirement => {\n  const field = `requirements[${index}]`;\n  const requirement = isRecord(value) ? value : fail('guard', field);\n  const options = isRecord(requirement.options)\n    ? requirement.options\n    : fail('guard', `${field}.options`);\n\n  if (options.mode !== undefined && !isRequirementMode(options.mode)) {\n    fail('guard', `${field}.options.mode`);\n  }\n  if (options.tenant !== undefined && !isTenantMode(options.tenant)) {\n    fail('guard', `${field}.options.tenant`);\n  }\n  if (options.resource !== undefined && !isRequirementResource(options.resource)) {\n    fail('guard', `${field}.options.resource`);\n  }\n  if (options.reason !== undefined && typeof options.reason !== 'string') {\n    fail('guard', `${field}.options.reason`);\n  }\n\n  if (requirement.kind === 'role') {\n    if (!isNonEmptyString(requirement.roleKey)) fail('guard', `${field}.roleKey`);\n    return;\n  }\n  if (requirement.kind !== 'permission') fail('guard', `${field}.kind`);\n  if (\n    !Array.isArray(requirement.permissions) ||\n    requirement.permissions.length === 0 ||\n    requirement.permissions.some((permission: unknown) => !isNonEmptyString(permission))\n  ) {\n    fail('guard', `${field}.permissions`);\n  }\n  if (!isRequirementMode(requirement.mode)) fail('guard', `${field}.mode`);\n  if (options.mode !== undefined && options.mode !== requirement.mode) {\n    fail('guard', `${field}.mode`);\n  }\n};\n\nexport function assertRbacRequirements(value: unknown): asserts value is RbacRequirement[] {\n  const requirements = Array.isArray(value) ? value : fail('guard', 'requirements');\n  requirements.forEach((requirement: unknown, index: number) =>\n    assertRequirement(requirement, index),\n  );\n}\n","import { RbacConfigError } from '../errors';\nimport type {\n  AssignRoleInput,\n  CreateRoleInput,\n  RbacCanInput,\n  RbacModuleOptions,\n  RbacRequirementMode,\n  RbacRole,\n  RbacSubject,\n  UpdateRoleInput,\n} from '../interfaces';\nimport { assertNonEmptyString, normalizePermission, normalizePermissions } from '../utils';\nimport {\n  canonicalizeIdentifier,\n  canonicalizeResource,\n  canonicalizeSubject,\n  canonicalizeTenantId,\n} from '../utils/canonicalization';\nimport {\n  assertCanInput,\n  assertFiniteDate,\n  isRbacResourceRef,\n  isRbacSubject,\n} from '../utils/runtime-validation';\n\nexport interface ResolvedTenant {\n  tenantId: string | null;\n  missing: boolean;\n  conflict: boolean;\n}\n\nexport interface PermissionRequirement {\n  permission?: string | undefined;\n  permissions: string[];\n  mode: RbacRequirementMode;\n  invalid: boolean;\n}\n\nconst isNonEmptyString = (value: unknown): value is string =>\n  typeof value === 'string' && value.trim() !== '';\n\nexport class RbacServiceInput {\n  constructor(private readonly options: RbacModuleOptions) {}\n\n  canonicalizeCan(input: RbacCanInput): RbacCanInput {\n    assertCanInput(input);\n    const base = {\n      ...input,\n      ...(input.subject !== undefined ? { subject: canonicalizeSubject(input.subject) } : {}),\n      ...(input.tenantId !== undefined ? { tenantId: canonicalizeTenantId(input.tenantId) } : {}),\n      ...(input.resource !== undefined ? { resource: canonicalizeResource(input.resource) } : {}),\n    };\n\n    if ('roleKey' in input && input.roleKey !== undefined) {\n      return {\n        ...base,\n        roleKey: canonicalizeIdentifier(input.roleKey, 'roleKey'),\n      } as RbacCanInput;\n    }\n\n    return {\n      ...base,\n      ...('permission' in input && input.permission !== undefined\n        ? { permission: normalizePermission(input.permission) }\n        : {}),\n      ...('permissions' in input && input.permissions !== undefined\n        ? { permissions: normalizePermissions(input.permissions) }\n        : {}),\n    } as RbacCanInput;\n  }\n\n  canonicalizeCreateRole(input: CreateRoleInput): CreateRoleInput {\n    this.validateOptionalTenantId(input.tenantId);\n    assertNonEmptyString(input.key, 'role key');\n    normalizePermissions(input.permissions);\n\n    return {\n      ...input,\n      tenantId: canonicalizeTenantId(input.tenantId),\n      key: canonicalizeIdentifier(input.key, 'role key'),\n      permissions: normalizePermissions(input.permissions),\n    };\n  }\n\n  canonicalizeUpdateRole(input: UpdateRoleInput): UpdateRoleInput {\n    assertNonEmptyString(input.roleId, 'roleId');\n    this.validateOptionalTenantId(input.tenantId);\n    if (input.key !== undefined) assertNonEmptyString(input.key, 'role key');\n    if (input.permissions !== undefined) normalizePermissions(input.permissions);\n\n    return {\n      ...input,\n      roleId: canonicalizeIdentifier(input.roleId, 'roleId'),\n      ...(input.tenantId !== undefined ? { tenantId: canonicalizeTenantId(input.tenantId) } : {}),\n      ...(input.key !== undefined ? { key: canonicalizeIdentifier(input.key, 'role key') } : {}),\n      ...(input.permissions !== undefined\n        ? { permissions: normalizePermissions(input.permissions) }\n        : {}),\n    };\n  }\n\n  canonicalizeAssignRole(input: AssignRoleInput): AssignRoleInput {\n    this.validateAssignRole(input);\n    const base = {\n      tenantId: canonicalizeTenantId(input.tenantId),\n      subject: canonicalizeSubject(input.subject),\n      ...(input.resource !== undefined ? { resource: canonicalizeResource(input.resource) } : {}),\n      ...(input.expiresAt !== undefined ? { expiresAt: input.expiresAt } : {}),\n      ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n    };\n\n    if ('roleId' in input && input.roleId !== undefined) {\n      return { ...base, roleId: canonicalizeIdentifier(input.roleId, 'roleId') };\n    }\n\n    return { ...base, roleKey: canonicalizeIdentifier(input.roleKey, 'roleKey') };\n  }\n\n  resolveTenant(input: RbacCanInput, subject: RbacSubject | undefined): ResolvedTenant {\n    const mode =\n      input.tenantMode ?? (this.options.tenant?.requiredByDefault ? 'required' : 'optional');\n    const explicitTenantId = this.normalizeTenantForComparison(input.tenantId);\n    const subjectTenantId = this.normalizeTenantForComparison(subject?.tenantId);\n    const conflict =\n      explicitTenantId !== undefined &&\n      explicitTenantId !== null &&\n      subjectTenantId !== undefined &&\n      explicitTenantId !== subjectTenantId;\n\n    if (mode === 'none') return { tenantId: null, missing: false, conflict };\n    if (input.tenantId === null) {\n      return { tenantId: null, missing: mode === 'required', conflict: false };\n    }\n\n    const rawTenantId = input.tenantId !== undefined ? input.tenantId : subject?.tenantId;\n    const tenantId = isNonEmptyString(rawTenantId) ? rawTenantId.trim() : null;\n\n    return { tenantId, missing: mode === 'required' && tenantId === null, conflict };\n  }\n\n  permissionRequirement(input: RbacCanInput): PermissionRequirement {\n    const permission = 'permission' in input ? input.permission : undefined;\n    const rawPermissions = this.rawPermissions(input);\n    const mode = input.mode ?? (rawPermissions.length > 1 ? 'all' : 'any');\n\n    try {\n      return {\n        permission: permission ? normalizePermission(permission) : undefined,\n        permissions: normalizePermissions(rawPermissions),\n        mode,\n        invalid: false,\n      };\n    } catch {\n      return {\n        permission: typeof permission === 'string' ? permission : undefined,\n        permissions: rawPermissions.filter(\n          (candidate): candidate is string => typeof candidate === 'string',\n        ),\n        mode,\n        invalid: true,\n      };\n    }\n  }\n\n  isRoleCheck(input: RbacCanInput): input is RbacCanInput & { roleKey: string } {\n    return 'roleKey' in input && typeof input.roleKey === 'string';\n  }\n\n  resolveNow(input: RbacCanInput): Date {\n    const now = input.now ?? this.options.now?.() ?? new Date();\n    assertFiniteDate(now, 'can', 'now');\n    return now;\n  }\n\n  validateAssignRoleBoundary(input: AssignRoleInput, role: RbacRole | undefined): void {\n    const validation = this.options.writeValidation;\n    if (\n      validation?.rejectResourceWithoutTenant === true &&\n      input.resource !== undefined &&\n      input.tenantId == null\n    ) {\n      throw new RbacConfigError({\n        operation: 'assignRole',\n        reason: 'resource_binding_requires_tenant',\n      });\n    }\n    if (role === undefined) return;\n\n    const roleTenantId = role.tenantId ?? null;\n    const bindingTenantId = input.tenantId ?? null;\n    if (\n      validation?.rejectTenantMismatch === true &&\n      roleTenantId !== null &&\n      roleTenantId !== bindingTenantId\n    ) {\n      throw new RbacConfigError({\n        operation: 'assignRole',\n        reason: 'role_tenant_mismatch',\n        roleId: role.id,\n        roleTenantId,\n        bindingTenantId,\n      });\n    }\n    if (\n      validation?.rejectGlobalRoleInTenantBinding === true &&\n      roleTenantId === null &&\n      bindingTenantId !== null\n    ) {\n      throw new RbacConfigError({\n        operation: 'assignRole',\n        reason: 'global_role_tenant_binding_rejected',\n        roleId: role.id,\n        bindingTenantId,\n      });\n    }\n  }\n\n  private rawPermissions(input: RbacCanInput): string[] {\n    const permissions: string[] = [];\n    if ('permission' in input && typeof input.permission === 'string') {\n      permissions.push(input.permission);\n    }\n    if ('permissions' in input && Array.isArray(input.permissions)) {\n      permissions.push(\n        ...input.permissions.filter(\n          (permission): permission is string => typeof permission === 'string',\n        ),\n      );\n    }\n    return permissions;\n  }\n\n  private normalizeTenantForComparison(\n    tenantId: string | null | undefined,\n  ): string | null | undefined {\n    if (tenantId === null) return null;\n    if (isNonEmptyString(tenantId)) return tenantId.trim();\n    return undefined;\n  }\n\n  private validateAssignRole(input: AssignRoleInput): void {\n    this.validateOptionalTenantId(input.tenantId);\n    if (!isRbacSubject(input.subject)) {\n      throw new RbacConfigError({\n        operation: 'assignRole',\n        field: 'subject',\n        reason: 'invalid_runtime_shape',\n      });\n    }\n    this.validateAssignRoleSubjectTenant(input);\n    const hasRoleId = 'roleId' in input && input.roleId !== undefined;\n    const hasRoleKey = 'roleKey' in input && input.roleKey !== undefined;\n    if (hasRoleId === hasRoleKey) {\n      throw new RbacConfigError({\n        reason: 'assignRole() accepts exactly one role identifier per call',\n      });\n    }\n    if (hasRoleId) assertNonEmptyString(input.roleId, 'roleId');\n    if (hasRoleKey) assertNonEmptyString(input.roleKey, 'roleKey');\n    if (input.resource !== undefined && !isRbacResourceRef(input.resource)) {\n      throw new RbacConfigError({\n        operation: 'assignRole',\n        field: 'resource',\n        reason: 'invalid_runtime_shape',\n      });\n    }\n    if (input.expiresAt !== undefined && input.expiresAt !== null) {\n      assertFiniteDate(input.expiresAt, 'assignRole', 'expiresAt');\n    }\n  }\n\n  private validateAssignRoleSubjectTenant(input: AssignRoleInput): void {\n    if (\n      this.options.writeValidation?.rejectTenantMismatch !== true ||\n      input.subject.tenantId === undefined\n    ) {\n      return;\n    }\n\n    const subjectTenantId = input.subject.tenantId?.trim() ?? null;\n    const bindingTenantId = input.tenantId?.trim() ?? null;\n    if (subjectTenantId === bindingTenantId) return;\n\n    throw new RbacConfigError({\n      operation: 'assignRole',\n      reason: 'subject_tenant_mismatch',\n      subjectTenantId,\n      bindingTenantId,\n    });\n  }\n\n  private validateOptionalTenantId(tenantId: string | null | undefined, name = 'tenantId'): void {\n    if (tenantId !== null && tenantId !== undefined) assertNonEmptyString(tenantId, name);\n  }\n}\n","import { RbacConfigError } from '../errors';\nimport type {\n  RbacAuditEvent,\n  RbacModuleOptions,\n  RbacMutationResult,\n  RbacPolicyChangeEvent,\n} from '../interfaces';\n\nexport class RbacServiceMutationSupport {\n  constructor(private readonly options: RbacModuleOptions) {}\n\n  requireValue<T>(operation: string, result: RbacMutationResult<T>): T {\n    if (result.value !== undefined) return result.value;\n\n    throw new RbacConfigError({\n      operation,\n      reason: result.reason ?? 'mutation_result_missing_value',\n      outcome: result.outcome,\n    });\n  }\n\n  async legacy(\n    mutation: () => Promise<void>,\n    outcome: 'created' | 'updated' | 'deleted',\n  ): Promise<RbacMutationResult> {\n    await mutation();\n    return { outcome };\n  }\n\n  async audit(event: RbacAuditEvent): Promise<void> {\n    try {\n      await this.options.auditLogger?.log(event);\n    } catch {\n      // Audit logging must not change RBAC write or authorization behavior.\n    }\n  }\n\n  async publish(event: Omit<RbacPolicyChangeEvent, 'occurredAt'>): Promise<void> {\n    try {\n      await this.options.changePublisher?.publish({\n        occurredAt: this.options.now?.() ?? new Date(),\n        ...event,\n      });\n    } catch {\n      // Change hooks are for cache/outbox integration and must not alter write results.\n    }\n  }\n}\n","import { InMemoryRbacStorage } from '../adapters';\nimport type {\n  AssignRoleInput,\n  CreateRoleInput,\n  RbacCanInput,\n  RbacModuleOptions,\n  RbacServiceDecision,\n  RbacServiceDecisionReason,\n} from '../interfaces';\nimport { RbacService } from '../rbac.service';\n\nexport interface RbacScenarioInput {\n  roles?: CreateRoleInput[] | undefined;\n  bindings?: AssignRoleInput[] | undefined;\n  options?: Omit<RbacModuleOptions, 'storage'> | undefined;\n}\n\nexport interface RbacScenario {\n  storage: InMemoryRbacStorage;\n  rbac: RbacService;\n}\n\nexport type RbacMatrixCase = RbacCanInput & {\n  allowed: boolean;\n  reason?: RbacServiceDecisionReason | undefined;\n  label?: string | undefined;\n};\n\nfunction describeMatrixInput(input: RbacCanInput): string {\n  const parts: string[] = [];\n  if ('permission' in input && input.permission !== undefined) {\n    parts.push(`permission=${input.permission}`);\n  }\n  if ('permissions' in input && input.permissions !== undefined) {\n    parts.push(`permissions=${input.permissions.join(',')}`);\n  }\n  if ('roleKey' in input && input.roleKey !== undefined) {\n    parts.push(`roleKey=${input.roleKey}`);\n  }\n  if (input.tenantId !== undefined) {\n    parts.push(`tenantId=${input.tenantId ?? 'null'}`);\n  }\n  if (input.resource !== undefined) {\n    parts.push(`resource=${input.resource.type}:${input.resource.id}`);\n  }\n\n  return parts.length > 0 ? parts.join(' ') : 'empty RBAC input';\n}\n\nexport async function createRbacScenario(input: RbacScenarioInput = {}): Promise<RbacScenario> {\n  const storage = new InMemoryRbacStorage();\n  const rbac = new RbacService({ ...input.options, storage });\n\n  for (const role of input.roles ?? []) {\n    await rbac.createRole(role);\n  }\n  for (const binding of input.bindings ?? []) {\n    await rbac.assignRole(binding);\n  }\n\n  return { storage, rbac };\n}\n\nexport async function expectRbacMatrix(\n  rbac: RbacService,\n  cases: RbacMatrixCase[],\n): Promise<RbacServiceDecision[]> {\n  const decisions: RbacServiceDecision[] = [];\n\n  for (const [index, matrixCase] of cases.entries()) {\n    const { allowed, reason, label, ...input } = matrixCase;\n    const decision = await rbac.can(input);\n    decisions.push(decision);\n    const caseName = label ?? `case ${index + 1}`;\n    const inputDescription = describeMatrixInput(input);\n\n    if (decision.allowed !== allowed) {\n      throw new Error(\n        `RBAC matrix ${caseName} expected ${allowed ? 'allow' : 'deny'} for ${inputDescription}, received ${decision.reason}`,\n      );\n    }\n    if (!allowed && reason !== undefined && decision.reason !== reason) {\n      throw new Error(\n        `RBAC matrix ${caseName} expected denial reason ${reason} for ${inputDescription}, received ${decision.reason}`,\n      );\n    }\n  }\n\n  return decisions;\n}\n","import type { RbacSubject } from '../interfaces';\n\nexport const rbacUser = (id: string, tenantId?: string | null): RbacSubject => ({\n  type: 'user',\n  id,\n  ...(tenantId !== undefined ? { tenantId } : {}),\n});\n\nexport const rbacApiKey = (id: string, tenantId?: string | null): RbacSubject => ({\n  type: 'api_key',\n  id,\n  ...(tenantId !== undefined ? { tenantId } : {}),\n});\n\nexport const rbacServiceAccount = (id: string, tenantId?: string | null): RbacSubject => ({\n  type: 'service_account',\n  id,\n  ...(tenantId !== undefined ? { tenantId } : {}),\n});\n\nexport const user = rbacUser;\nexport const apiKey = rbacApiKey;\nexport const serviceAccount = rbacServiceAccount;\n","import { DynamicModule, Module } from '@nestjs/common';\nimport { InMemoryRbacStorage } from '../adapters';\nimport type { RbacModuleOptions, RbacStorage, RbacSubject } from '../interfaces';\nimport { RbacModule } from '../rbac.module';\n\nexport interface TestRbacModuleOptions\n  extends Omit<RbacModuleOptions, 'storage' | 'subjectResolver'> {\n  storage?: RbacStorage | undefined;\n  subject?: RbacSubject | undefined;\n  subjectResolver?: RbacModuleOptions['subjectResolver'] | undefined;\n}\n\n@Module({})\nexport class TestRbacModule {\n  static forRoot(options: TestRbacModuleOptions = {}): DynamicModule {\n    const { storage, subject, subjectResolver, ...rbacOptions } = options;\n\n    return RbacModule.forRoot({\n      ...rbacOptions,\n      storage: storage ?? new InMemoryRbacStorage(),\n      subjectResolver: subjectResolver ?? (subject !== undefined ? () => subject : undefined),\n    });\n  }\n}\n","import { DynamicModule, Module, type Provider } from '@nestjs/common';\nimport { RBAC_OPTIONS, RBAC_STORAGE } from './constants';\nimport { RbacGuard } from './rbac.guard';\nimport { RbacService } from './rbac.service';\nimport type { RbacModuleAsyncOptions, RbacModuleOptions } from './interfaces';\n\nconst rbacStorageProvider: Provider = {\n  provide: RBAC_STORAGE,\n  useFactory: (options: RbacModuleOptions) => options.storage,\n  inject: [RBAC_OPTIONS],\n};\n\nconst rbacExports = [RBAC_OPTIONS, RBAC_STORAGE, RbacService, RbacGuard];\n\n@Module({})\nexport class RbacModule {\n  static forRoot(options: RbacModuleOptions): DynamicModule {\n    return {\n      module: RbacModule,\n      providers: [\n        { provide: RBAC_OPTIONS, useValue: options },\n        rbacStorageProvider,\n        RbacService,\n        RbacGuard,\n      ],\n      exports: rbacExports,\n    };\n  }\n\n  static forRootAsync(options: RbacModuleAsyncOptions): DynamicModule {\n    return {\n      module: RbacModule,\n      ...(options.imports !== undefined ? { imports: options.imports } : {}),\n      providers: [\n        {\n          provide: RBAC_OPTIONS,\n          useFactory: options.useFactory,\n          inject: options.inject ?? [],\n        },\n        rbacStorageProvider,\n        RbacService,\n        RbacGuard,\n      ],\n      exports: rbacExports,\n    };\n  }\n}\n","import { Inject, Injectable, type CanActivate, type ExecutionContext } from '@nestjs/common';\nimport { ModuleRef, Reflector } from '@nestjs/core';\nimport {\n  RBAC_OPTIONS,\n  RBAC_REQUIREMENTS_METADATA,\n  RBAC_SKIP_METADATA,\n  RBAC_SUBJECT_REQUEST_KEY,\n} from './constants';\nimport { mapRbacErrorToHttpException, RbacPermissionDeniedError } from './errors';\nimport { RbacGuardAudit } from './guard/rbac-guard-audit';\nimport { RbacGuardContextResolver } from './guard/rbac-guard-context.resolver';\nimport { RbacGuardRequirementEvaluator } from './guard/rbac-guard-requirement.evaluator';\nimport type { RbacModuleOptions } from './interfaces';\nimport { RbacService } from './rbac.service';\n\ntype HttpRequest = Record<string, unknown>;\n\n/** Nest HTTP authorization guard. Other transports should call `RbacService` from their adapter. */\n@Injectable()\nexport class RbacGuard implements CanActivate {\n  private readonly audit: RbacGuardAudit;\n  private readonly contextResolver: RbacGuardContextResolver;\n  private readonly requirementEvaluator: RbacGuardRequirementEvaluator;\n\n  constructor(\n    private readonly reflector: Reflector,\n    rbac: RbacService,\n    @Inject(RBAC_OPTIONS) private readonly options: RbacModuleOptions,\n    moduleRef: ModuleRef,\n  ) {\n    this.audit = new RbacGuardAudit(options);\n    this.contextResolver = new RbacGuardContextResolver(options, moduleRef, this.audit);\n    this.requirementEvaluator = new RbacGuardRequirementEvaluator(\n      rbac,\n      options,\n      this.audit,\n      this.contextResolver,\n    );\n  }\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const targets = [context.getHandler(), context.getClass()];\n    const skip = this.reflector.getAllAndOverride<unknown>(RBAC_SKIP_METADATA, targets);\n    if (skip !== undefined) return true;\n\n    const requirements =\n      this.reflector.getAllAndMerge<unknown[]>(RBAC_REQUIREMENTS_METADATA, targets) ?? [];\n    if (requirements.length === 0) {\n      if (this.options.requireMetadata) {\n        await this.audit.metadataMissing();\n        throw mapRbacErrorToHttpException(new RbacPermissionDeniedError());\n      }\n\n      return true;\n    }\n    const validatedRequirements = this.requirementEvaluator.validate(requirements);\n\n    const subject = await this.contextResolver.resolveSubject(context);\n    const request = context.switchToHttp().getRequest<HttpRequest>();\n    request[RBAC_SUBJECT_REQUEST_KEY] = subject;\n\n    await this.requirementEvaluator.assertAllowed(context, validatedRequirements, subject);\n\n    return true;\n  }\n}\n","import type {\n  RbacAuditEvent,\n  RbacModuleOptions,\n  RbacResourceRef,\n  RbacServiceDecision,\n  RbacSubject,\n} from '../interfaces';\n\nexport interface RbacGuardAuditContext {\n  subject: RbacSubject;\n  tenantId?: string | null | undefined;\n}\n\nconst auditResource = (resource: RbacResourceRef | undefined): RbacResourceRef | undefined =>\n  resource ? { type: resource.type, id: resource.id } : undefined;\n\nexport class RbacGuardAudit {\n  constructor(private readonly options: RbacModuleOptions) {}\n\n  async metadataMissing(): Promise<void> {\n    await this.log({\n      type: 'rbac.permission.denied',\n      metadata: { reason: 'rbac_metadata_missing' },\n    });\n  }\n\n  async subjectMissing(): Promise<void> {\n    await this.log({\n      type: 'rbac.permission.denied',\n      metadata: { reason: 'denied_subject_missing' },\n    });\n  }\n\n  async tenantSourceConflict(subject: RbacSubject): Promise<void> {\n    await this.log({\n      type: 'rbac.permission.denied',\n      subjectType: subject.type,\n      subjectId: subject.id,\n      metadata: { reason: 'tenant_source_conflict' },\n    });\n  }\n\n  async resourceMissing(context: RbacGuardAuditContext): Promise<void> {\n    await this.log({\n      type: 'rbac.permission.denied',\n      tenantId: context.tenantId,\n      subjectType: context.subject.type,\n      subjectId: context.subject.id,\n      metadata: { reason: 'denied_resource_missing' },\n    });\n  }\n\n  async deniedDecision(decision: RbacServiceDecision, requirementIndex: number): Promise<void> {\n    await this.log({\n      type: 'rbac.permission.denied',\n      tenantId: decision.tenantId,\n      subjectType: decision.subject?.type,\n      subjectId: decision.subject?.id,\n      metadata: {\n        reason: decision.reason,\n        requirementIndex,\n        permission: decision.permission,\n        permissions: decision.permissions,\n        roleKey: decision.roleKey,\n        resource: auditResource(decision.resource),\n        details: decision.details,\n      },\n    });\n  }\n\n  async allowedRequest(decisions: RbacServiceDecision[]): Promise<void> {\n    const firstDecision = decisions[0]!;\n\n    if (decisions.length === 1) {\n      await this.allowedDecision(firstDecision);\n      return;\n    }\n\n    const tenantId = decisions.every((decision) => decision.tenantId === firstDecision.tenantId)\n      ? firstDecision.tenantId\n      : undefined;\n\n    await this.log({\n      type: 'rbac.permission.allowed',\n      tenantId,\n      subjectType: firstDecision.subject?.type,\n      subjectId: firstDecision.subject?.id,\n      metadata: {\n        reason: 'allowed_all_requirements',\n        requirements: decisions.map((decision, requirementIndex) => ({\n          requirementIndex,\n          reason: decision.reason,\n        })),\n      },\n    });\n  }\n\n  async log(event: RbacAuditEvent): Promise<void> {\n    try {\n      await this.options.auditLogger?.log(event);\n    } catch {\n      // Preserve the RBAC HTTP response even when audit logging fails.\n    }\n  }\n\n  private async allowedDecision(decision: RbacServiceDecision): Promise<void> {\n    const metadata: Record<string, unknown> = { reason: decision.reason };\n    if (decision.permission !== undefined) metadata.permission = decision.permission;\n    if (decision.permissions !== undefined) metadata.permissions = decision.permissions;\n    if (decision.roleKey !== undefined) metadata.roleKey = decision.roleKey;\n    if (decision.matchedRoleKeys !== undefined) metadata.matchedRoleKeys = decision.matchedRoleKeys;\n    if (decision.matchedPermissions !== undefined) {\n      metadata.matchedPermissions = decision.matchedPermissions;\n    }\n    if (decision.details !== undefined) metadata.details = decision.details;\n    const resource = auditResource(decision.resource);\n    if (resource !== undefined) metadata.resource = resource;\n\n    await this.log({\n      type: 'rbac.permission.allowed',\n      tenantId: decision.tenantId,\n      subjectType: decision.subject?.type,\n      subjectId: decision.subject?.id,\n      metadata,\n    });\n  }\n}\n","import type { ExecutionContext } from '@nestjs/common';\nimport type { RbacBuiltInResourceDeclaration } from '../interfaces/requirements';\nimport type { RbacResourceRef } from '../interfaces/resource';\n\ntype HttpRequest = {\n  params?: Record<string, unknown>;\n  query?: Record<string, unknown>;\n  headers?: Record<string, unknown>;\n};\n\nconst resolveId = (value: unknown): string | undefined => {\n  if (typeof value === 'string' && value.length > 0) {\n    return value;\n  }\n  if (typeof value === 'number') {\n    return String(value);\n  }\n\n  return undefined;\n};\n\nconst getHeader = (headers: Record<string, unknown> | undefined, name: string): unknown => {\n  if (headers === undefined) {\n    return undefined;\n  }\n\n  return headers[name.toLowerCase()] ?? headers[name];\n};\n\nexport const resolveHttpResource = (\n  context: ExecutionContext,\n  declaration: RbacBuiltInResourceDeclaration,\n): RbacResourceRef | undefined => {\n  const request = context.switchToHttp().getRequest<HttpRequest>();\n  const id =\n    'idParam' in declaration\n      ? resolveId(request.params?.[declaration.idParam])\n      : 'idQuery' in declaration\n        ? resolveId(request.query?.[declaration.idQuery])\n        : resolveId(getHeader(request.headers, declaration.idHeader));\n\n  if (id === undefined) {\n    return undefined;\n  }\n\n  return { type: declaration.type, id };\n};\n","import type { RbacSubject } from '../interfaces/subject';\n\ntype HttpRequest = Record<string, unknown>;\ntype ApiKeyRecord = Record<string, unknown>;\n\ntype ParsedApiKey = {\n  id: string;\n  tenantId?: string;\n  attributes: ApiKeyRecord;\n};\n\nconst isRecord = (value: unknown): value is ApiKeyRecord =>\n  typeof value === 'object' && value !== null;\n\nconst isOpaqueIdentifier = (value: unknown): value is string =>\n  typeof value === 'string' && value.length > 0;\n\nconst parseApiKey = (value: unknown): ParsedApiKey | undefined => {\n  if (!isRecord(value)) return undefined;\n\n  const hasKeyId = value.keyId !== undefined;\n  const hasLegacyId = value.id !== undefined;\n  const hasTenantId = value.tenantId !== undefined;\n\n  if (\n    (hasKeyId && !isOpaqueIdentifier(value.keyId)) ||\n    (hasLegacyId && !isOpaqueIdentifier(value.id)) ||\n    (hasTenantId && !isOpaqueIdentifier(value.tenantId))\n  ) {\n    return undefined;\n  }\n\n  const keyId = isOpaqueIdentifier(value.keyId) ? value.keyId : undefined;\n  const legacyId = isOpaqueIdentifier(value.id) ? value.id : undefined;\n  const id = keyId ?? legacyId;\n  if (id === undefined) return undefined;\n\n  const tenantId = isOpaqueIdentifier(value.tenantId) ? value.tenantId : undefined;\n\n  return {\n    id,\n    ...(tenantId !== undefined ? { tenantId } : {}),\n    attributes: value,\n  };\n};\n\nconst toSubject = (apiKey: ParsedApiKey): RbacSubject => ({\n  type: 'api_key',\n  id: apiKey.id,\n  ...(apiKey.tenantId !== undefined ? { tenantId: apiKey.tenantId } : {}),\n  attributes: apiKey.attributes,\n});\n\nexport const resolveApiKeySubject = (request: HttpRequest): RbacSubject | undefined => {\n  const canonicalValue = request.apiKey;\n  const legacyValue = request.apiKeyContext;\n  const hasCanonical = canonicalValue !== undefined && canonicalValue !== null;\n  const hasLegacy = legacyValue !== undefined && legacyValue !== null;\n\n  if (hasCanonical) {\n    const canonical = parseApiKey(canonicalValue);\n    if (canonical === undefined) return undefined;\n\n    if (hasLegacy) {\n      const legacy = parseApiKey(legacyValue);\n      if (\n        legacy === undefined ||\n        legacy.id !== canonical.id ||\n        legacy.tenantId !== canonical.tenantId\n      ) {\n        return undefined;\n      }\n    }\n\n    return toSubject(canonical);\n  }\n\n  if (!hasLegacy) return undefined;\n\n  const legacy = parseApiKey(legacyValue);\n  return legacy === undefined ? undefined : toSubject(legacy);\n};\n","import { RBAC_SUBJECT_REQUEST_KEY } from '../constants';\nimport type { RbacSubjectResolver } from '../interfaces/resolvers';\nimport type { RbacSubject, RbacSubjectType } from '../interfaces/subject';\nimport { resolveApiKeySubject } from './api-key-subject.resolver';\n\ntype HttpRequest = Record<string, unknown>;\ntype SubjectRecord = Record<string, unknown>;\n\nconst isRecord = (value: unknown): value is SubjectRecord =>\n  typeof value === 'object' && value !== null;\n\nconst resolveId = (record: SubjectRecord, keys: string[]): string | undefined => {\n  for (const key of keys) {\n    const value = record[key];\n\n    if (typeof value === 'string' && value.length > 0) {\n      return value;\n    }\n    if (typeof value === 'number') {\n      return String(value);\n    }\n  }\n\n  return undefined;\n};\n\nconst resolveTenantId = (record: SubjectRecord): string | null | undefined => {\n  const tenantId = record.tenantId;\n\n  if (tenantId === null) {\n    return null;\n  }\n  if (typeof tenantId === 'string') {\n    return tenantId;\n  }\n  if (typeof tenantId === 'number') {\n    return String(tenantId);\n  }\n\n  return undefined;\n};\n\nconst normalizeSubject = (value: unknown): RbacSubject | undefined => {\n  if (!isRecord(value) || typeof value.type !== 'string' || value.type.length === 0) {\n    return undefined;\n  }\n\n  const id = resolveId(value, ['id']);\n  if (id === undefined) {\n    return undefined;\n  }\n\n  if (typeof value.id === 'string') {\n    return value as unknown as RbacSubject;\n  }\n\n  const subject: RbacSubject = {\n    type: value.type,\n    id,\n  };\n  const tenantId = resolveTenantId(value);\n\n  if (tenantId !== undefined) {\n    subject.tenantId = tenantId;\n  }\n\n  return subject;\n};\n\nconst resolveSubjectType = (record: SubjectRecord, fallback: RbacSubjectType): RbacSubjectType => {\n  const type = record.type;\n\n  return typeof type === 'string' && type.length > 0 ? type : fallback;\n};\n\nconst mapSubject = (\n  fallbackType: RbacSubjectType,\n  record: unknown,\n  idKeys: string[],\n): RbacSubject | undefined => {\n  if (!isRecord(record)) {\n    return undefined;\n  }\n\n  const id = resolveId(record, idKeys);\n  if (id === undefined) {\n    return undefined;\n  }\n\n  const subject: RbacSubject = {\n    type: resolveSubjectType(record, fallbackType),\n    id,\n    attributes: record,\n  };\n  const tenantId = resolveTenantId(record);\n\n  if (tenantId !== undefined) {\n    subject.tenantId = tenantId;\n  }\n\n  return subject;\n};\n\nconst hasPopulatedApiKeySource = (request: HttpRequest): boolean =>\n  (request.apiKey !== undefined && request.apiKey !== null) ||\n  (request.apiKeyContext !== undefined && request.apiKeyContext !== null);\n\nconst hasSameIdentity = (left: RbacSubject, right: RbacSubject): boolean =>\n  left.type === right.type && left.id === right.id && left.tenantId === right.tenantId;\n\nexport const defaultHttpSubjectResolver = (): RbacSubjectResolver => (context) => {\n  const request = context.switchToHttp().getRequest<HttpRequest>();\n  const rbacSubject = request[RBAC_SUBJECT_REQUEST_KEY];\n  const normalizedSubject = normalizeSubject(rbacSubject);\n  const userSubject = mapSubject('user', request.user, ['id', 'sub', 'userId']);\n  const apiKeySubject = resolveApiKeySubject(request);\n\n  if (hasPopulatedApiKeySource(request) && apiKeySubject === undefined) {\n    return undefined;\n  }\n\n  const candidates = [normalizedSubject, userSubject, apiKeySubject].filter(\n    (subject): subject is RbacSubject => subject !== undefined,\n  );\n  const selected = candidates[0];\n\n  if (selected === undefined || candidates.some((subject) => !hasSameIdentity(selected, subject))) {\n    return undefined;\n  }\n\n  return selected;\n};\n","import type { ExecutionContext } from '@nestjs/common';\nimport type { RbacRequirementOptions } from '../interfaces/requirements';\nimport type { RbacSubject } from '../interfaces/subject';\n\ntype HttpRequest = {\n  tenantId?: unknown;\n  tenant?: unknown;\n  headers?: Record<string, unknown>;\n};\n\nexport interface RbacHttpTenantSource {\n  source: 'subject' | 'request.tenantId' | 'request.tenant.id' | 'header';\n  tenantId: string | null;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n  typeof value === 'object' && value !== null;\n\nconst resolveTenantId = (value: unknown): string | null | undefined => {\n  if (value === null) {\n    return null;\n  }\n  if (typeof value === 'string' && value.length > 0) {\n    return value;\n  }\n  if (typeof value === 'number') {\n    return String(value);\n  }\n\n  return undefined;\n};\n\nconst getHeader = (headers: Record<string, unknown> | undefined, name: string): unknown => {\n  if (headers === undefined) {\n    return undefined;\n  }\n\n  return headers[name.toLowerCase()] ?? headers[name];\n};\n\nexport const resolveHttpTenant = (\n  context: ExecutionContext,\n  requirementOptions: RbacRequirementOptions,\n  subject: RbacSubject,\n): string | null | undefined => {\n  if (requirementOptions.tenant === 'none') return null;\n\n  return resolveHttpTenantSources(context, requirementOptions, subject)[0]?.tenantId;\n};\n\nexport const resolveHttpTenantSources = (\n  context: ExecutionContext,\n  requirementOptions: RbacRequirementOptions,\n  subject: RbacSubject,\n): RbacHttpTenantSource[] => {\n  if (requirementOptions.tenant === 'none') return [];\n\n  const sources: RbacHttpTenantSource[] = [];\n\n  const subjectTenantId = resolveTenantId(subject.tenantId);\n  if (subjectTenantId !== undefined) {\n    sources.push({ source: 'subject', tenantId: subjectTenantId });\n  }\n\n  const request = context.switchToHttp().getRequest<HttpRequest>();\n  const requestTenantId = resolveTenantId(request.tenantId);\n  if (requestTenantId !== undefined) {\n    sources.push({ source: 'request.tenantId', tenantId: requestTenantId });\n  }\n\n  const tenantObjectId = isRecord(request.tenant) ? resolveTenantId(request.tenant.id) : undefined;\n  if (tenantObjectId !== undefined) {\n    sources.push({ source: 'request.tenant.id', tenantId: tenantObjectId });\n  }\n\n  const headerTenantId = resolveTenantId(getHeader(request.headers, 'x-tenant-id'));\n  if (headerTenantId !== undefined) {\n    sources.push({ source: 'header', tenantId: headerTenantId });\n  }\n\n  return sources;\n};\n","import type { ExecutionContext } from '@nestjs/common';\nimport type { ModuleRef } from '@nestjs/core';\nimport {\n  mapRbacErrorToHttpException,\n  RbacPermissionDeniedError,\n  RbacResourceMissingError,\n  RbacSubjectMissingError,\n} from '../errors';\nimport type {\n  RbacBuiltInResourceDeclaration,\n  RbacCanInput,\n  RbacModuleOptions,\n  RbacRequirement,\n  RbacRequirementOptions,\n  RbacResourceRef,\n  RbacResourceResolver,\n  RbacResourceResolverFn,\n  RbacResourceResolverToken,\n  RbacResourceResolverTokenRef,\n  RbacSubject,\n  RbacTenantMode,\n} from '../interfaces';\nimport { defaultHttpSubjectResolver, resolveHttpResource } from '../resolvers';\nimport {\n  resolveHttpTenantSources,\n  type RbacHttpTenantSource,\n} from '../resolvers/default-http-tenant.resolver';\nimport { isRbacSubject } from '../utils/runtime-validation';\nimport { RbacGuardAudit, type RbacGuardAuditContext } from './rbac-guard-audit';\n\ntype RbacResourceResolverClassToken = abstract new (...args: never[]) => RbacResourceResolver;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n  typeof value === 'object' && value !== null;\n\nconst isNonEmptyString = (value: unknown): value is string =>\n  typeof value === 'string' && value.trim() !== '';\n\nconst isBuiltInResourceDeclaration = (\n  resource: RbacRequirementOptions['resource'],\n): resource is RbacBuiltInResourceDeclaration =>\n  isRecord(resource) &&\n  typeof resource.type === 'string' &&\n  ('idParam' in resource || 'idHeader' in resource || 'idQuery' in resource);\n\nconst isResolverTokenRef = (\n  resource: RbacRequirementOptions['resource'],\n): resource is RbacResourceResolverTokenRef => isRecord(resource) && 'resolverToken' in resource;\n\nconst isClassResolverToken = (resource: unknown): resource is RbacResourceResolverClassToken =>\n  typeof resource === 'function' &&\n  isRecord(resource.prototype) &&\n  typeof resource.prototype.resolve === 'function';\n\nconst isStringOrSymbolResolverToken = (resource: unknown): resource is RbacResourceResolverToken =>\n  typeof resource === 'string' || typeof resource === 'symbol';\n\nexport class RbacGuardContextResolver {\n  constructor(\n    private readonly options: RbacModuleOptions,\n    private readonly moduleRef: ModuleRef,\n    private readonly audit: RbacGuardAudit,\n  ) {}\n\n  async resolveSubject(context: ExecutionContext): Promise<RbacSubject> {\n    const resolver = this.options.subjectResolver ?? defaultHttpSubjectResolver();\n    const subject = await resolver(context);\n\n    if (!isRbacSubject(subject)) {\n      await this.audit.subjectMissing();\n      throw mapRbacErrorToHttpException(new RbacSubjectMissingError());\n    }\n\n    return subject;\n  }\n\n  async toCanInput(\n    context: ExecutionContext,\n    requirement: RbacRequirement,\n    subject: RbacSubject,\n  ): Promise<RbacCanInput> {\n    const tenantMode = this.resolveTenantMode(requirement.options);\n    const tenantId = await this.resolveTenant(context, requirement.options, subject);\n    const resource = await this.resolveResource(context, requirement.options.resource, {\n      subject,\n      tenantId,\n    });\n\n    if (requirement.kind === 'role') {\n      return {\n        subject,\n        tenantId,\n        tenantMode,\n        roleKey: requirement.roleKey,\n        ...(resource !== undefined ? { resource } : {}),\n      };\n    }\n\n    return {\n      subject,\n      tenantId,\n      tenantMode,\n      permissions: requirement.permissions,\n      mode: requirement.mode,\n      ...(resource !== undefined ? { resource } : {}),\n    };\n  }\n\n  private resolveTenantMode(options: RbacRequirementOptions): RbacTenantMode {\n    return options.tenant ?? (this.options.tenant?.requiredByDefault ? 'required' : 'optional');\n  }\n\n  private async resolveTenant(\n    context: ExecutionContext,\n    requirementOptions: RbacRequirementOptions,\n    subject: RbacSubject,\n  ): Promise<string | null | undefined> {\n    if (requirementOptions.tenant === 'none') return null;\n\n    const httpSources = resolveHttpTenantSources(context, requirementOptions, subject);\n    const resolver = this.options.tenantResolver;\n    const resolverMode = this.options.tenant?.resolverMode ?? 'authoritative';\n\n    if (resolverMode === 'legacy-fallback' && httpSources.length > 0) {\n      await this.ensureTenantSourcesAgree(httpSources, subject);\n      return httpSources[0]?.tenantId;\n    }\n\n    const trustedTenantId = await resolver?.(context, requirementOptions, subject);\n    const sources =\n      trustedTenantId === undefined\n        ? httpSources\n        : [{ source: 'configuredResolver' as const, tenantId: trustedTenantId }, ...httpSources];\n\n    await this.ensureTenantSourcesAgree(sources, subject);\n\n    return trustedTenantId !== undefined ? trustedTenantId : httpSources[0]?.tenantId;\n  }\n\n  private async ensureTenantSourcesAgree(\n    sources: Array<\n      | RbacHttpTenantSource\n      | {\n          source: 'configuredResolver';\n          tenantId: string | null;\n        }\n    >,\n    subject: RbacSubject,\n  ): Promise<void> {\n    const selected = sources[0]?.tenantId;\n    if (sources.every((source) => source.tenantId === selected)) return;\n\n    await this.audit.tenantSourceConflict(subject);\n    throw mapRbacErrorToHttpException(new RbacPermissionDeniedError());\n  }\n\n  private async resolveResource(\n    context: ExecutionContext,\n    resource: RbacRequirementOptions['resource'],\n    auditContext: RbacGuardAuditContext,\n  ): Promise<RbacResourceRef | undefined> {\n    if (resource === undefined) return undefined;\n\n    if (isBuiltInResourceDeclaration(resource)) {\n      return this.ensureResource(resolveHttpResource(context, resource), auditContext);\n    }\n\n    if (isResolverTokenRef(resource)) {\n      const resolver = this.resolveResourceProvider(resource);\n      return this.ensureResource(await resolver.resolve(context), auditContext);\n    }\n\n    if (isClassResolverToken(resource)) {\n      const resolver = this.resolveResourceProvider(resource);\n      return this.ensureResource(await resolver.resolve(context), auditContext);\n    }\n\n    if (typeof resource === 'function') {\n      const resolver = resource as RbacResourceResolverFn;\n      return this.ensureResource(await resolver(context), auditContext);\n    }\n\n    if (isStringOrSymbolResolverToken(resource)) {\n      const resolver = this.resolveResourceProvider(resource);\n      return this.ensureResource(await resolver.resolve(context), auditContext);\n    }\n\n    return undefined;\n  }\n\n  private resolveResourceProvider(\n    resource: RbacResourceResolverToken | RbacResourceResolverTokenRef,\n  ): RbacResourceResolver {\n    const resolverToken = isResolverTokenRef(resource) ? resource.resolverToken : resource;\n\n    try {\n      const resolver = this.moduleRef.get<RbacResourceResolver | undefined>(resolverToken, {\n        strict: false,\n      });\n\n      if (resolver === undefined || typeof resolver.resolve !== 'function') {\n        throw new RbacResourceMissingError({ resolverToken: String(resolverToken) });\n      }\n\n      return resolver;\n    } catch (error) {\n      if (error instanceof RbacResourceMissingError) {\n        throw mapRbacErrorToHttpException(error);\n      }\n\n      throw mapRbacErrorToHttpException(\n        new RbacResourceMissingError({ resolverToken: String(resolverToken) }, { cause: error }),\n      );\n    }\n  }\n\n  private async ensureResource(\n    resource: unknown,\n    auditContext: RbacGuardAuditContext,\n  ): Promise<RbacResourceRef> {\n    if (!isRecord(resource) || !isNonEmptyString(resource.type) || !isNonEmptyString(resource.id)) {\n      await this.audit.resourceMissing(auditContext);\n      throw mapRbacErrorToHttpException(new RbacResourceMissingError());\n    }\n\n    return { type: resource.type.trim(), id: resource.id.trim() };\n  }\n}\n","import type { ExecutionContext } from '@nestjs/common';\nimport {\n  mapRbacErrorToHttpException,\n  RbacConfigError,\n  RbacError,\n  RbacPermissionDeniedError,\n  RbacResourceMissingError,\n  RbacStorageError,\n  RbacSubjectMissingError,\n  RbacTenantMissingError,\n} from '../errors';\nimport type {\n  RbacDecisionReason,\n  RbacModuleOptions,\n  RbacRequirement,\n  RbacServiceDecision,\n  RbacSubject,\n} from '../interfaces';\nimport { RbacService } from '../rbac.service';\nimport { assertRbacRequirements } from '../utils/runtime-validation';\nimport { RbacGuardAudit } from './rbac-guard-audit';\nimport { RbacGuardContextResolver } from './rbac-guard-context.resolver';\n\nexport class RbacGuardRequirementEvaluator {\n  constructor(\n    private readonly rbac: RbacService,\n    private readonly options: RbacModuleOptions,\n    private readonly audit: RbacGuardAudit,\n    private readonly contextResolver: RbacGuardContextResolver,\n  ) {}\n\n  validate(requirements: unknown[]): RbacRequirement[] {\n    try {\n      assertRbacRequirements(requirements);\n      return requirements;\n    } catch (error) {\n      if (error instanceof RbacConfigError) throw mapRbacErrorToHttpException(error);\n      throw error;\n    }\n  }\n\n  async assertAllowed(\n    context: ExecutionContext,\n    requirements: RbacRequirement[],\n    subject: RbacSubject,\n  ): Promise<void> {\n    const allowedDecisions: RbacServiceDecision[] = [];\n    for (const [requirementIndex, requirement] of requirements.entries()) {\n      const decision = await this.checkRequirement(context, requirement, subject);\n      if (!decision.allowed) {\n        await this.audit.deniedDecision(decision, requirementIndex);\n        throw this.deniedDecisionToHttpException(decision.reason);\n      }\n\n      allowedDecisions.push(decision);\n    }\n\n    if (this.options.logAllowedDecisions) {\n      await this.audit.allowedRequest(allowedDecisions);\n    }\n  }\n\n  private async checkRequirement(\n    context: ExecutionContext,\n    requirement: RbacRequirement,\n    subject: RbacSubject,\n  ): Promise<RbacServiceDecision> {\n    try {\n      return await this.rbac.can(\n        await this.contextResolver.toCanInput(context, requirement, subject),\n      );\n    } catch (error) {\n      if (error instanceof RbacError) throw mapRbacErrorToHttpException(error);\n      throw error;\n    }\n  }\n\n  private deniedDecisionToHttpException(reason: RbacDecisionReason) {\n    switch (reason) {\n      case 'denied_subject_missing':\n        return mapRbacErrorToHttpException(new RbacSubjectMissingError());\n      case 'denied_tenant_missing':\n        return mapRbacErrorToHttpException(new RbacTenantMissingError());\n      case 'denied_resource_missing':\n        return mapRbacErrorToHttpException(new RbacResourceMissingError());\n      case 'denied_storage_error':\n        return mapRbacErrorToHttpException(new RbacStorageError());\n      default:\n        return mapRbacErrorToHttpException(new RbacPermissionDeniedError());\n    }\n  }\n}\n"],"mappings":"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","names":["expectAllowed","rbac","input","decision","can","allowed","Error","reason","expectDenied","undefined","expectDeniedReason","mapRbacErrorToHttpException","error","response","message","code","InternalServerErrorException","UnauthorizedException","ForbiddenException","assertNever","_code","Error","RbacError","Error","message","code","status","options","cause","name","details","undefined","RbacConfigError","RbacSubjectMissingError","RbacTenantMissingError","RbacResourceMissingError","RbacPermissionDeniedError","RbacRoleNotFoundError","RbacStorageError","RbacError","details","options","cause","assertNonEmptyString","value","name","trim","Error","PERMISSION_RE","normalizePermission","permission","normalized","trim","test","Error","normalizePermissions","permissions","Set","map","matchesPermission","granted","required","normalizedGranted","normalizePermission","normalizedRequired","endsWith","prefix","slice","startsWith","storedResource","resource","type","id","resourceType","resourceId","matchesResource","granted","required","grantedResource","canonicalizeIdentifier","value","name","assertNonEmptyString","isCanonicalIdentifier","trim","canonicalizeTenantId","tenantId","canonicalizeSubject","subject","isApiKey","type","id","preserveOpaqueIdentifier","undefined","canonicalizeResource","resource","normalizeTenantId","tenantId","canonicalizeTenantId","canonicalizeUpsertRoleInput","input","roleId","canonicalizeIdentifier","undefined","key","permissions","normalizePermissions","canonicalizeAssignInput","subject","canonicalizeSubject","resource","canonicalizeResource","cloneDate","date","Date","cloneValue","value","Array","isArray","map","Object","fromEntries","entries","nestedValue","cloneMetadata","metadata","globalThis","structuredClone","cloneRole","role","id","name","description","isSystem","cloneBinding","binding","cloned","subjectType","subjectId","resourceType","resourceId","expiresAt","revokedAt","bindingResource","type","isBindingActive","now","getTime","samePermissions","stored","requested","left","sort","right","length","every","index","roleInputChanges","InMemoryRbacStorage","roleSequence","bindingSequence","roles","Map","bindings","mutationResults","createRole","canonicalInput","existing","findStoredRole","outcome","upsertRole","updateRole","get","reason","deleteRole","has","grantPermission","permission","normalizePermission","includes","revokePermission","assignRole","findStoredBinding","before","isDeepStrictEqual","revokeRole","bindingId","findRole","values","find","candidate","Promise","resolve","findRoleById","listRoles","filter","updated","duplicateRole","reject","RbacConfigError","operation","conflictingRoleId","set","nextRoleId","delete","listRolePermissions","RbacRoleNotFoundError","nextBindingId","listBindings","listEffectiveRoles","collectEffectiveRoles","listEffectivePermissions","effectiveRoles","flatMap","effectiveRole","isEffectiveBinding","toEffectiveRole","bindingResourceType","bindingResourceId","roleKey","normalizedTenantId","import_common","RBAC_OPTIONS","Symbol","RBAC_STORAGE","RBAC_REQUIREMENTS_METADATA","RBAC_SKIP_METADATA","RBAC_SUBJECT_REQUEST_KEY","RbacServiceDecisionFactory","create","input","reason","overrides","decision","allowed","subject","tenantId","permission","undefined","permissions","rawPermissions","roleKey","mode","matchedRoleKeys","matchedPermissions","resource","details","buildDetails","sanitize","sanitizeSubject","push","Array","isArray","filter","type","id","requirement","buildRequirementDetails","matched","buildMatchedDetails","missing","buildMissingDetails","evaluationPath","evaluationStep","safeMessage","roleKeys","length","tenant","missingPermissions","code","outcome","isRecord","value","Array","isArray","isNonEmptyString","trim","isRequirementMode","isTenantMode","fail","operation","field","RbacConfigError","reason","isFiniteDate","Date","Number","isFinite","getTime","isRbacSubject","type","id","tenantId","undefined","isRbacResourceRef","assertFiniteDate","assertCanInput","input","subject","tenantMode","resource","now","hasRole","roleKey","hasPermission","permission","permissions","mode","some","isResolverToken","isBuiltInResourceDeclaration","selectorKeys","filter","key","length","isRequirementResource","resolverToken","assertRequirement","index","requirement","options","tenant","kind","assertRbacRequirements","requirements","forEach","isNonEmptyString","value","trim","RbacServiceInput","options","canonicalizeCan","input","assertCanInput","base","subject","undefined","canonicalizeSubject","tenantId","canonicalizeTenantId","resource","canonicalizeResource","roleKey","canonicalizeIdentifier","permission","normalizePermission","permissions","normalizePermissions","canonicalizeCreateRole","validateOptionalTenantId","assertNonEmptyString","key","canonicalizeUpdateRole","roleId","canonicalizeAssignRole","validateAssignRole","expiresAt","metadata","resolveTenant","mode","tenantMode","tenant","requiredByDefault","explicitTenantId","normalizeTenantForComparison","subjectTenantId","conflict","missing","rawTenantId","permissionRequirement","rawPermissions","length","invalid","filter","candidate","isRoleCheck","resolveNow","now","Date","assertFiniteDate","validateAssignRoleBoundary","role","validation","writeValidation","rejectResourceWithoutTenant","RbacConfigError","operation","reason","roleTenantId","bindingTenantId","rejectTenantMismatch","id","rejectGlobalRoleInTenantBinding","push","Array","isArray","isRbacSubject","field","validateAssignRoleSubjectTenant","hasRoleId","hasRoleKey","isRbacResourceRef","name","RbacServiceMutationSupport","options","requireValue","operation","result","value","undefined","RbacConfigError","reason","outcome","legacy","mutation","audit","event","auditLogger","log","publish","changePublisher","occurredAt","now","Date","unique","values","Set","auditResource","resource","type","id","undefined","RbacService","decisions","inputs","mutations","options","RbacServiceDecisionFactory","RbacServiceInput","RbacServiceMutationSupport","can","input","canonicalInput","canonicalizeCan","subject","isRbacSubject","tenant","resolveTenant","create","allowed","tenantId","conflict","missing","isRoleCheck","canRole","canPermission","assertCan","decision","RbacPermissionDeniedError","sanitize","createRole","canonicalizeCreateRole","result","storage","mutationResults","outcome","value","upsertRole","RbacConfigError","operation","reason","role","requireValue","created","audit","metadata","roleId","roleKey","key","publish","permissions","updateRole","canonicalizeUpdateRole","RbacRoleNotFoundError","deleteRole","canonicalizeIdentifier","legacy","grantPermission","permission","normalizePermission","revokePermission","assignRole","canonicalizeAssignRole","resolveAssignRoleIdentifier","validateAssignRoleBoundary","storageInput","expiresAt","binding","subjectType","subjectId","bindingId","revokeRole","revokedAt","assertFiniteDate","listRoles","canonicalizeTenantId","listPermissions","listRolePermissions","listBindings","canonicalizeSubject","trim","matchedRoleKeys","now","resolveNow","roles","listEffectiveRolesForTenant","filter","map","length","error","handleStorageError","requirement","permissionRequirement","invalid","mode","matchedPermissions","effectivePermissions","listEffectivePermissionsForTenant","matches","matchPermissions","every","required","byRequired","has","missingPermissions","requiredPermissions","Map","effectivePermission","matchesPermission","set","push","match","assignRoleNeedsResolvedRole","findRoleById","findRole","validation","writeValidation","rejectTenantMismatch","rejectGlobalRoleInTenantBinding","find","storageErrors","RbacStorageError","cause","tenantRoles","listEffectiveRoles","validTenantRoles","validEffectiveRecords","allowGlobalRolesInTenant","globalRoles","tenantPermissions","listEffectivePermissions","validTenantPermissions","globalPermissions","records","record","isValidEffectiveRecord","effectiveRecord","isCanonicalIdentifier","Error","normalizedPermission","Date","expiresAtTime","getTime","Number","isFinite","resourceType","resourceId","matchesResource","describeMatrixInput","input","parts","permission","undefined","push","permissions","join","roleKey","tenantId","resource","type","id","length","createRbacScenario","storage","InMemoryRbacStorage","rbac","RbacService","options","role","roles","createRole","binding","bindings","assignRole","expectRbacMatrix","cases","decisions","index","matrixCase","entries","allowed","reason","label","decision","can","caseName","inputDescription","Error","rbacUser","id","tenantId","type","undefined","rbacApiKey","rbacServiceAccount","user","apiKey","serviceAccount","import_common","import_common","import_common","auditResource","resource","type","id","undefined","RbacGuardAudit","options","metadataMissing","log","metadata","reason","subjectMissing","tenantSourceConflict","subject","subjectType","subjectId","resourceMissing","context","tenantId","deniedDecision","decision","requirementIndex","permission","permissions","roleKey","details","allowedRequest","decisions","firstDecision","length","allowedDecision","every","requirements","map","event","auditLogger","matchedRoleKeys","matchedPermissions","resolveId","value","length","String","undefined","getHeader","headers","name","toLowerCase","resolveHttpResource","context","declaration","request","switchToHttp","getRequest","id","params","idParam","query","idQuery","idHeader","type","isRecord","value","isOpaqueIdentifier","length","parseApiKey","undefined","hasKeyId","keyId","hasLegacyId","id","hasTenantId","tenantId","legacyId","attributes","toSubject","apiKey","type","resolveApiKeySubject","request","canonicalValue","legacyValue","apiKeyContext","hasCanonical","hasLegacy","canonical","legacy","isRecord","value","resolveId","record","keys","key","length","String","undefined","resolveTenantId","tenantId","normalizeSubject","type","id","subject","resolveSubjectType","fallback","mapSubject","fallbackType","idKeys","attributes","hasPopulatedApiKeySource","request","apiKey","apiKeyContext","hasSameIdentity","left","right","defaultHttpSubjectResolver","context","switchToHttp","getRequest","rbacSubject","RBAC_SUBJECT_REQUEST_KEY","normalizedSubject","userSubject","user","apiKeySubject","resolveApiKeySubject","candidates","filter","selected","some","isRecord","value","resolveTenantId","length","String","undefined","getHeader","headers","name","toLowerCase","resolveHttpTenantSources","context","requirementOptions","subject","tenant","sources","subjectTenantId","resolveTenantId","tenantId","undefined","push","source","request","switchToHttp","getRequest","requestTenantId","tenantObjectId","isRecord","id","headerTenantId","getHeader","headers","isRecord","value","isNonEmptyString","trim","isBuiltInResourceDeclaration","resource","type","isResolverTokenRef","isClassResolverToken","prototype","resolve","isStringOrSymbolResolverToken","RbacGuardContextResolver","options","moduleRef","audit","resolveSubject","context","resolver","subjectResolver","defaultHttpSubjectResolver","subject","isRbacSubject","subjectMissing","mapRbacErrorToHttpException","RbacSubjectMissingError","toCanInput","requirement","tenantMode","resolveTenantMode","tenantId","resolveTenant","resolveResource","kind","roleKey","undefined","permissions","mode","tenant","requiredByDefault","requirementOptions","httpSources","resolveHttpTenantSources","tenantResolver","resolverMode","length","ensureTenantSourcesAgree","trustedTenantId","sources","source","selected","every","tenantSourceConflict","RbacPermissionDeniedError","auditContext","ensureResource","resolveHttpResource","resolveResourceProvider","resolverToken","get","strict","RbacResourceMissingError","String","error","cause","id","resourceMissing","RbacGuardRequirementEvaluator","rbac","options","audit","contextResolver","validate","requirements","assertRbacRequirements","error","RbacConfigError","mapRbacErrorToHttpException","assertAllowed","context","subject","allowedDecisions","requirementIndex","requirement","entries","decision","checkRequirement","allowed","deniedDecision","deniedDecisionToHttpException","reason","push","logAllowedDecisions","allowedRequest","can","toCanInput","RbacError","RbacSubjectMissingError","RbacTenantMissingError","RbacResourceMissingError","RbacStorageError","RbacPermissionDeniedError","RbacGuard","audit","contextResolver","requirementEvaluator","reflector","rbac","options","moduleRef","RbacGuardAudit","RbacGuardContextResolver","RbacGuardRequirementEvaluator","canActivate","context","targets","getHandler","getClass","skip","getAllAndOverride","RBAC_SKIP_METADATA","undefined","requirements","getAllAndMerge","RBAC_REQUIREMENTS_METADATA","length","requireMetadata","metadataMissing","mapRbacErrorToHttpException","RbacPermissionDeniedError","validatedRequirements","validate","subject","resolveSubject","request","switchToHttp","getRequest","RBAC_SUBJECT_REQUEST_KEY","assertAllowed","rbacStorageProvider","provide","RBAC_STORAGE","useFactory","options","storage","inject","RBAC_OPTIONS","rbacExports","RbacService","RbacGuard","RbacModule","forRoot","module","providers","useValue","exports","forRootAsync","imports","undefined","TestRbacModule","forRoot","options","storage","subject","subjectResolver","rbacOptions","RbacModule","InMemoryRbacStorage","undefined"]}