import type { ManagementRole } from "./contracts"; export type { ManagementRole }; export type ManagementAction = | "dashboard.read" | "resource.read" | "audit.read" | "policy.simulate" | "catalog.preview" | "tool.test" | "tool.invoke" | "operations.check" | "client.read" | "client.bootstrap" | "client.disable" | "client.revoke" | "client.create" | "catalog.apply"; /** Mirrors services/control_api/authz.py's ENDPOINT_PERMISSIONS exactly. * This is a client-side hide-only affordance, never an authorization * boundary -- services/control_api/authz.py's check_role() is what * actually enforces every one of these actions server-side. */ const PERMISSIONS: Record = { "dashboard.read": ["viewer", "auditor", "operator", "admin"], "resource.read": ["viewer", "auditor", "operator", "admin"], "audit.read": ["auditor", "operator", "admin"], "policy.simulate": ["viewer", "auditor", "operator", "admin"], "catalog.preview": ["viewer", "auditor", "operator", "admin"], "tool.test": ["operator", "admin"], "tool.invoke": ["operator", "admin"], "operations.check": ["operator", "admin"], "client.read": ["viewer", "auditor", "operator", "admin"], "client.bootstrap": ["operator", "admin"], "client.disable": ["operator", "admin"], "client.revoke": ["operator", "admin"], "client.create": ["admin"], "catalog.apply": ["admin"], }; export function can(roles: readonly ManagementRole[], action: ManagementAction): boolean { const allowed = PERMISSIONS[action]; return roles.some((role) => allowed.includes(role)); }