authz

package
v2.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2026 License: BSD-3-Clause Imports: 1 Imported by: 0

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

View Source
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"
)
View Source
const (
	PermissionScopeGlobal = "global"
	PermissionScopeEnv    = "env"
)
View Source
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.

View Source
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).

View Source
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

func EnvIDFromPath(path string) string

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

func IsEnvScoped(perm string) bool

IsEnvScoped reports whether the given permission is resolved against an environment ID. Returns false for permissions not in AllPermissions().

func IsKnownPermission

func IsKnownPermission(perm string) bool

IsKnownPermission reports whether perm matches any defined permission constant. Used to reject role definitions referencing unknown permissions.

func IsOrgLevel

func IsOrgLevel(perm string) bool

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL