Documentation
¶
Overview ¶
Package authz defines the permission taxonomy and authorization primitives used across Arcane handlers. Permissions are strings of the form "<resource>:<action>" and are classified as either org-level (require a globally-scoped role) or env-scoped (resolved against the environment ID from the request path).
Index ¶
- Constants
- func AllPermissions() []string
- func BuiltInDeployerPermissions() []string
- func BuiltInEditorPermissions() []string
- func BuiltInMonitorPermissions() []string
- func BuiltInNoShellEditorPermissions() []string
- func BuiltInViewerPermissions() []string
- func CanAccessCustomizeCategory(ps *PermissionSet, categoryID, selectedEnvID string) bool
- func CanAccessSettingsCategory(ps *PermissionSet, categoryID, selectedEnvID string) bool
- func CanAccessSurface(ps *PermissionSet, surfaceID, selectedEnvID string) bool
- func EnvIDFromPath(path string) string
- func IsEnvScoped(perm string) bool
- func IsKnownPermission(perm string) bool
- func IsOrgLevel(perm string) bool
- func TotalPermissionsCount() int
- type AccessSurface
- type PermissionCatalogAction
- type PermissionCatalogResource
- type PermissionSet
Constants ¶
const ( AccessSurfaceKindRoute = "route" AccessSurfaceKindSettingsCategory = "settings-category" AccessSurfaceKindCustomizeCategory = "customize-category" AccessSurfaceKindLanding = "landing" AccessModePermissions = "permissions" AccessModeAnyChild = "any-child" AccessMatchModeAnyOf = "any-of" AccessMatchModeAllOf = "all-of" AccessScopeModeGlobalOnly = "global-only" AccessScopeModeSelectedEnvPlusGlobal = "selected-env-plus-global" AccessScopeModeAnyEffectiveScope = "any-effective-scope" )
const ( PermissionScopeGlobal = "global" PermissionScopeEnv = "env" )
const ( BuiltInRoleAdmin = "role_admin" BuiltInRoleEditor = "role_editor" BuiltInRoleNoShellEditor = "role_no_shell_editor" BuiltInRoleDeployer = "role_deployer" BuiltInRoleMonitor = "role_monitor" BuiltInRoleViewer = "role_viewer" )
Built-in role IDs. Stable across migrations so other code may reference them safely. All six built-in roles are seeded by migration 054_add_rbac.
const ( PermUsersList = "users:list" PermUsersRead = "users:read" PermUsersCreate = "users:create" PermUsersUpdate = "users:update" PermUsersDelete = "users:delete" // PermRolesList and the role permissions below cover role management // (Create / Update / Delete) and role assignment to users. They are reserved // for global admins and intentionally not exposed as delegated permissions — // see backend/api/middleware/role.go::RequireGlobalAdmin. Likewise, managing // OIDC group → role mappings is admin-only because it is effectively another // path for granting role assignments. PermRolesList = "roles:list" PermRolesRead = "roles:read" PermApiKeysList = "apikeys:list" PermApiKeysRead = "apikeys:read" PermApiKeysCreate = "apikeys:create" PermApiKeysUpdate = "apikeys:update" PermApiKeysDelete = "apikeys:delete" PermFederatedList = "federated:list" PermFederatedRead = "federated:read" PermFederatedCreate = "federated:create" PermFederatedUpdate = "federated:update" PermFederatedDelete = "federated:delete" PermSettingsRead = "settings:read" PermSettingsWrite = "settings:write" PermEnvironmentsList = "environments:list" PermEnvironmentsRead = "environments:read" PermEnvironmentsCreate = "environments:create" PermEnvironmentsUpdate = "environments:update" PermEnvironmentsDelete = "environments:delete" PermEnvironmentsPair = "environments:pair" PermEnvironmentsSync = "environments:sync" PermRegistriesList = "registries:list" PermRegistriesRead = "registries:read" PermRegistriesCreate = "registries:create" PermRegistriesUpdate = "registries:update" PermRegistriesDelete = "registries:delete" PermRegistriesTest = "registries:test" PermTemplatesList = "templates:list" PermTemplatesRead = "templates:read" PermTemplatesCreate = "templates:create" PermTemplatesUpdate = "templates:update" PermTemplatesDelete = "templates:delete" PermGitReposList = "git-repositories:list" PermGitReposRead = "git-repositories:read" PermGitReposCreate = "git-repositories:create" PermGitReposUpdate = "git-repositories:update" PermGitReposDelete = "git-repositories:delete" PermGitReposTest = "git-repositories:test" PermGitReposSync = "git-repositories:sync" PermEventsRead = "events:read" PermEventsDelete = "events:delete" PermCustomizeManage = "customize:manage" // PermDiagnosticsRead gates the admin-only runtime diagnostics surface // (runtime/memory/GC stats, WebSocket metrics, pprof profiles, and the live // backend log tail). Global-scoped; seeded only into the Admin role. PermDiagnosticsRead = "diagnostics:read" )
Org-level permissions (require a global-scope role assignment).
const ( PermContainersList = "containers:list" PermContainersRead = "containers:read" PermContainersLogs = "containers:logs" PermContainersCreate = "containers:create" PermContainersStart = "containers:start" PermContainersStop = "containers:stop" PermContainersRestart = "containers:restart" PermContainersRedeploy = "containers:redeploy" PermContainersDelete = "containers:delete" PermContainersExec = "containers:exec" PermContainersAutoUpdate = "containers:autoupdate" PermProjectsList = "projects:list" PermProjectsRead = "projects:read" PermProjectsLogs = "projects:logs" PermProjectsCreate = "projects:create" PermProjectsUpdate = "projects:update" PermProjectsDeploy = "projects:deploy" PermProjectsDown = "projects:down" PermProjectsRestart = "projects:restart" PermProjectsDelete = "projects:delete" PermProjectsArchive = "projects:archive" PermImagesList = "images:list" PermImagesRead = "images:read" PermImagesPull = "images:pull" PermImagesPush = "images:push" PermImagesBuild = "images:build" PermImagesPrune = "images:prune" PermImagesDelete = "images:delete" PermImagesUpload = "images:upload" PermVolumesList = "volumes:list" PermVolumesRead = "volumes:read" PermVolumesCreate = "volumes:create" PermVolumesDelete = "volumes:delete" PermVolumesPrune = "volumes:prune" PermVolumesBrowse = "volumes:browse" PermVolumesUpload = "volumes:upload" PermVolumesBackup = "volumes:backup" PermNetworksList = "networks:list" PermNetworksRead = "networks:read" PermNetworksCreate = "networks:create" PermNetworksDelete = "networks:delete" PermNetworksPrune = "networks:prune" PermSwarmRead = "swarm:read" PermSwarmInit = "swarm:init" PermSwarmJoin = "swarm:join" PermSwarmLeave = "swarm:leave" PermSwarmSpec = "swarm:spec" PermSwarmNodes = "swarm:nodes" PermSwarmServices = "swarm:services" PermSwarmServicesLogs = "swarm:services:logs" PermSwarmStacks = "swarm:stacks" PermSwarmConfigs = "swarm:configs" PermSwarmSecrets = "swarm:secrets" PermSwarmUnlock = "swarm:unlock" PermGitOpsList = "gitops:list" PermGitOpsRead = "gitops:read" PermGitOpsCreate = "gitops:create" PermGitOpsUpdate = "gitops:update" PermGitOpsDelete = "gitops:delete" PermGitOpsSync = "gitops:sync" PermWebhooksList = "webhooks:list" PermWebhooksCreate = "webhooks:create" PermWebhooksUpdate = "webhooks:update" PermWebhooksDelete = "webhooks:delete" PermJobsManage = "jobs:manage" PermNotificationsManage = "notifications:manage" PermDashboardRead = "dashboard:read" PermSystemRead = "system:read" PermSystemPrune = "system:prune" PermSystemUpgrade = "system:upgrade" PermImageUpdatesRead = "image-updates:read" PermImageUpdatesCheck = "image-updates:check" PermVulnsRead = "vulnerabilities:read" PermVulnsScan = "vulnerabilities:scan" PermVulnsManage = "vulnerabilities:manage" PermBuildWorkspacesManage = "build-workspaces:manage" PermActivitiesRead = "activities:read" PermActivitiesCancel = "activities:cancel" PermActivitiesDelete = "activities:delete" )
Env-scoped permissions (resolved against the {id} env ID in the path).
Variables ¶
This section is empty.
Functions ¶
func AllPermissions ¶
func AllPermissions() []string
AllPermissions returns every recognized permission constant. Used to seed the Admin built-in role and to validate role definitions.
func BuiltInDeployerPermissions ¶
func BuiltInDeployerPermissions() []string
BuiltInDeployerPermissions returns the permission set for the Deployer built-in role: container/project lifecycle and read-only on everything else. Cannot create or delete resources; cannot manage settings/users/roles/keys.
func BuiltInEditorPermissions ¶
func BuiltInEditorPermissions() []string
BuiltInEditorPermissions returns the permission set for the Editor built-in role: read+write on Docker resources and read on most org-level resources. Excludes user/role/key management and settings writes.
func BuiltInMonitorPermissions ¶
func BuiltInMonitorPermissions() []string
BuiltInMonitorPermissions returns the permission set for the Monitor built-in role: observability-only access — read Docker resources, view logs, dashboards, and events. No mutations, no exec, no user/role/settings access.
func BuiltInNoShellEditorPermissions ¶
func BuiltInNoShellEditorPermissions() []string
BuiltInNoShellEditorPermissions returns the Editor permission set minus PermContainersExec. For teams that want full Docker management but no interactive shell access into running containers.
func BuiltInViewerPermissions ¶
func BuiltInViewerPermissions() []string
BuiltInViewerPermissions returns the permission set for the Viewer built-in role: read-only access across every resource.
func CanAccessCustomizeCategory ¶
func CanAccessCustomizeCategory(ps *PermissionSet, categoryID, selectedEnvID string) bool
CanAccessCustomizeCategory reports whether a customize category is reachable.
func CanAccessSettingsCategory ¶
func CanAccessSettingsCategory(ps *PermissionSet, categoryID, selectedEnvID string) bool
CanAccessSettingsCategory reports whether a settings category is reachable for the selected environment.
func CanAccessSurface ¶
func CanAccessSurface(ps *PermissionSet, surfaceID, selectedEnvID string) bool
CanAccessSurface evaluates backend-owned UI reachability metadata for the caller. It is for advisory UX only; middleware and handlers still enforce permissions on actual API requests.
func EnvIDFromPath ¶
EnvIDFromPath extracts the environment ID from a Huma operation path of the form /environments/{id}/... Returns "" for paths without an env segment. Tolerates a leading /api prefix for safety, though the Huma group already strips it.
func IsEnvScoped ¶
IsEnvScoped reports whether the given permission is resolved against an environment ID. Returns false for permissions not in AllPermissions().
func IsKnownPermission ¶
IsKnownPermission reports whether perm matches any defined permission constant. Used to reject role definitions referencing unknown permissions.
func IsOrgLevel ¶
IsOrgLevel reports whether the given permission requires a globally-scoped role assignment (and applies only to org-level endpoints).
func TotalPermissionsCount ¶
func TotalPermissionsCount() int
TotalPermissionsCount returns the number of distinct permission constants the package defines. Computed once at init; cheap to call repeatedly.
Types ¶
type AccessSurface ¶
type AccessSurface struct {
ID string
Kind string
URL string
Label string
AccessMode string
MatchMode string
ScopeMode string
Permissions []string
Children []string
FallbackOrder int
}
AccessSurface describes one frontend-visible surface whose reachability is derived from backend-owned permission metadata. This is decision metadata for UX gating; backend middleware and service checks remain authoritative.
func AccessSurfaces ¶
func AccessSurfaces() []AccessSurface
AccessSurfaces returns a defensive copy of every backend-owned access surface in stable evaluation order.
type PermissionCatalogAction ¶
type PermissionCatalogAction struct {
Key string
Permission string
Label string
Description string
}
PermissionCatalogAction describes one recognized permission.
type PermissionCatalogResource ¶
type PermissionCatalogResource struct {
Key string
Label string
Scope string
Actions []PermissionCatalogAction
}
PermissionCatalogResource describes a resource group in the permission catalog. It is the authz-owned source for permission ordering, scope, and display metadata used by API manifests and validation helpers.
func PermissionCatalog ¶
func PermissionCatalog() []PermissionCatalogResource
PermissionCatalog returns a defensive copy of the full permission catalog.
type PermissionSet ¶
type PermissionSet struct {
Global map[string]struct{}
PerEnv map[string]map[string]struct{}
Sudo bool
}
PermissionSet is the effective permission set for one caller in one request. Built once by the auth bridge and stashed in the request context.
Global permissions apply to every environment and to org-level endpoints. PerEnv permissions apply only when the caller is acting on that specific environment. Sudo bypasses all checks (used for the agent token and the per-environment access token paths).
func NewPermissionSet ¶
func NewPermissionSet() *PermissionSet
NewPermissionSet builds an empty PermissionSet ready for population.
func SudoPermissionSet ¶
func SudoPermissionSet() *PermissionSet
SudoPermissionSet returns a PermissionSet that allows every action. Used for the agent token and environment access token paths, which bypass per-user permission resolution entirely.
func (*PermissionSet) AddEnv ¶
func (ps *PermissionSet) AddEnv(envID string, perms ...string)
AddEnv grants `perms` scoped to envID.
func (*PermissionSet) AddGlobal ¶
func (ps *PermissionSet) AddGlobal(perms ...string)
AddGlobal grants `perms` at global scope.
func (*PermissionSet) Allows ¶
func (ps *PermissionSet) Allows(perm, envID string) bool
Allows reports whether the caller may perform `perm`. For env-scoped permissions, envID is the target environment's ID. For org-level permissions, pass envID = "" — only Global permissions count.
func (*PermissionSet) IsGlobalAdmin ¶
func (ps *PermissionSet) IsGlobalAdmin() bool
IsGlobalAdmin reports whether the caller holds enough global permissions to be considered an administrator. True for sudo callers and for callers whose Global set contains every defined permission. Used by the backward-compat IsAdminFromContext helper and by last-admin guards.
Implementation: first checks cardinality against TotalPermissionsCount() for a fast early exit, then walks AllPermissions() to confirm every known permission is present. This guards against a ps.Global that contains the right count but includes injected unknown permissions instead of all real ones.