export const ROLES = ["viewer", "operator", "admin"] as const; export type Role = (typeof ROLES)[number]; export const CAPABILITIES = [ "kubernetes:read", "kubernetes:write", "kubernetes:exec", "users:read", "users:write", "sessions:revoke", "platform:adopt", ] as const; export type Capability = (typeof CAPABILITIES)[number]; const ROLE_CAPABILITIES: Readonly> = { viewer: ["kubernetes:read"], operator: ["kubernetes:read", "kubernetes:write", "kubernetes:exec"], admin: CAPABILITIES, }; export function isRole(value: unknown): value is Role { return ( typeof value === "string" && (ROLES as readonly string[]).includes(value) ); } export function isCapability(value: unknown): value is Capability { return ( typeof value === "string" && (CAPABILITIES as readonly string[]).includes(value) ); } export function capabilitiesForRoles( roles: readonly string[], ): ReadonlySet { const capabilities = new Set(); for (const role of roles) { if (!isRole(role)) continue; for (const capability of ROLE_CAPABILITIES[role]) capabilities.add(capability); } return capabilities; } export function hasCapability( roles: readonly string[], capability: Capability, ): boolean { return capabilitiesForRoles(roles).has(capability); }