Documentation
¶
Overview ¶
Package role owns RBAC roles, assignments, permission resolution, and role HTTP routes.
Index ¶
- Constants
- func RegisterRoles(api huma.API, roleService *RoleService)
- type ApiKeyPermission
- type CreateRoleInput
- type DeleteRoleInput
- type GetRoleInput
- type ListRolesInput
- type ListUserRoleAssignmentsInput
- type Module
- type OidcRoleMapping
- type Role
- type RoleHandler
- func (h *RoleHandler) CreateRole(ctx context.Context, input *CreateRoleInput) (*handlerutil.Out[roletypes.Role], error)
- func (h *RoleHandler) DeleteRole(ctx context.Context, input *DeleteRoleInput) (*handlerutil.Out[base.MessageResponse], error)
- func (h *RoleHandler) GetPermissionsManifest(_ context.Context, _ *struct{}) (*handlerutil.Out[roletypes.PermissionsManifest], error)
- func (h *RoleHandler) GetRole(ctx context.Context, input *GetRoleInput) (*handlerutil.Out[roletypes.Role], error)
- func (h *RoleHandler) ListRoles(ctx context.Context, input *ListRolesInput) (*handlerutil.Page[roletypes.Role], error)
- func (h *RoleHandler) ListUserRoleAssignments(ctx context.Context, input *ListUserRoleAssignmentsInput) (*handlerutil.Out[[]roletypes.RoleAssignment], error)
- func (h *RoleHandler) SetUserRoleAssignments(ctx context.Context, input *SetUserRoleAssignmentsInput) (*handlerutil.Out[[]roletypes.RoleAssignment], error)
- func (h *RoleHandler) UpdateRole(ctx context.Context, input *UpdateRoleInput) (*handlerutil.Out[roletypes.Role], error)
- type RoleService
- func (s *RoleService) AssertGlobalAdminExists(ctx context.Context, tx *gorm.DB) error
- func (s *RoleService) BackfillLegacyRoleAssignments(ctx context.Context) error
- func (s *RoleService) CountGlobalAdmins(ctx context.Context, tx *gorm.DB, excludedUserID string) (int, error)
- func (s *RoleService) CountUsersAssignedToRole(ctx context.Context, roleID string) (int, error)
- func (s *RoleService) CreateOidcMapping(ctx context.Context, claimValue, roleID string, environmentID *string) (*OidcRoleMapping, error)
- func (s *RoleService) CreateRole(ctx context.Context, name string, description *string, permissions []string) (*Role, error)
- func (s *RoleService) DeleteOidcMapping(ctx context.Context, id string) error
- func (s *RoleService) DeleteRole(ctx context.Context, id string) error
- func (s *RoleService) EnsureBuiltInRoles(ctx context.Context) error
- func (s *RoleService) GetOidcMapping(ctx context.Context, id string) (*OidcRoleMapping, error)
- func (s *RoleService) GetRole(ctx context.Context, id string) (*Role, error)
- func (s *RoleService) InvalidateApiKey(apiKeyID string)
- func (s *RoleService) InvalidateUser(userID string)
- func (s *RoleService) ListAllRoles(ctx context.Context) ([]Role, error)
- func (s *RoleService) ListOidcMappings(ctx context.Context) ([]OidcRoleMapping, error)
- func (s *RoleService) ListRoles(ctx context.Context, params pagination.QueryParams) ([]Role, pagination.Response, error)
- func (s *RoleService) ListUserAssignments(ctx context.Context, userID string) ([]UserRoleAssignment, error)
- func (s *RoleService) LockGlobalAdminGuard(tx *gorm.DB) error
- func (s *RoleService) ReconcileEnvOidcMappings(ctx context.Context, rawSpec string) error
- func (s *RoleService) ReplaceUserAssignments(ctx context.Context, userID, source string, desired []UserRoleAssignment) error
- func (s *RoleService) ResolveApiKeyPermissions(ctx context.Context, apiKeyID string) (*authz.PermissionSet, error)
- func (s *RoleService) ResolveExecutionPermissions(ctx context.Context, userID, keyID string) (*authz.PermissionSet, error)
- func (s *RoleService) ResolvePermissions(ctx context.Context, userID string) (*authz.PermissionSet, error)
- func (s *RoleService) ResolveUserPermissionsInDB(_ context.Context, tx *gorm.DB, userID string) (*authz.PermissionSet, error)
- func (s *RoleService) SetApiKeyPermissions(ctx context.Context, apiKeyID string, grants []ApiKeyPermission) error
- func (s *RoleService) SetApiKeyPermissionsInDB(ctx context.Context, tx *gorm.DB, apiKeyID string, grants []ApiKeyPermission) error
- func (s *RoleService) Stop()
- func (s *RoleService) UpdateOidcMapping(ctx context.Context, id, claimValue, roleID string, environmentID *string) (*OidcRoleMapping, error)
- func (s *RoleService) UpdateRole(ctx context.Context, id, name string, description *string, ...) (*Role, error)
- func (s *RoleService) ValidatePermissionsAgainstCaller(caller *authz.PermissionSet, desired []string) error
- func (s *RoleService) ValidateRoleAssignmentAgainstCaller(ctx context.Context, caller *authz.PermissionSet, roleID string, ...) error
- type SetUserRoleAssignmentsInput
- type UpdateRoleInput
- type UserRoleAssignment
Constants ¶
const ( RoleAssignmentSourceManual = "manual" RoleAssignmentSourceOidc = "oidc" OidcMappingSourceManual = "manual" OidcMappingSourceEnv = "env" )
Variables ¶
This section is empty.
Functions ¶
func RegisterRoles ¶
func RegisterRoles(api huma.API, roleService *RoleService)
Types ¶
type ApiKeyPermission ¶ added in v2.8.1
type ApiKeyPermission struct {
database.BaseModel
ApiKeyID string `json:"apiKeyId" gorm:"column:api_key_id;not null;index"`
Permission string `json:"permission" gorm:"column:permission;not null"`
EnvironmentID *string `json:"environmentId,omitempty" gorm:"column:environment_id"`
}
ApiKeyPermission is one permission grant on an API key, optionally scoped to a single environment. Permissions are stored per-row (rather than as a JSON column on api_keys) so we can index by (api_key_id, permission) for fast lookups in the auth bridge.
func (ApiKeyPermission) TableName ¶ added in v2.8.1
func (ApiKeyPermission) TableName() string
type CreateRoleInput ¶
type CreateRoleInput struct {
Body roletypes.CreateRole
}
type DeleteRoleInput ¶
type DeleteRoleInput struct {
ID string `path:"id" doc:"Role ID"`
}
type GetRoleInput ¶
type GetRoleInput struct {
ID string `path:"id" doc:"Role ID"`
}
type ListRolesInput ¶
type ListRolesInput struct {
Search string `query:"search" doc:"Search by role name or description"`
Sort string `query:"sort" doc:"Column to sort by"`
Order string `query:"order" default:"asc" doc:"Sort direction (asc or desc)"`
Start int `query:"start" default:"0" doc:"Start index for pagination"`
Limit int `query:"limit" default:"20" doc:"Items per page"`
}
type ListUserRoleAssignmentsInput ¶
type ListUserRoleAssignmentsInput struct {
UserID string `path:"userId" doc:"User ID"`
}
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module owns role persistence and its HTTP surface.
func (*Module) RegisterRoutes ¶
RegisterRoutes mounts role endpoints for runtime and schema discovery.
func (*Module) Service ¶
func (m *Module) Service() *RoleService
Service exposes role operations to authentication and authorization collaborators.
type OidcRoleMapping ¶ added in v2.8.1
type OidcRoleMapping struct {
database.BaseModel
ClaimValue string `json:"claimValue" gorm:"column:claim_value;not null;index"`
RoleID string `json:"roleId" gorm:"column:role_id;not null;index"`
EnvironmentID *string `json:"environmentId,omitempty" gorm:"column:environment_id"`
Source string `json:"source" gorm:"column:source;not null;default:'manual'"`
}
OidcRoleMapping maps an OIDC group/claim value to a role assignment. On every OIDC login, the auth service replaces all source='oidc' rows on the user with assignments derived from the mappings whose ClaimValue matches a claim returned by the IdP.
Source distinguishes UI/API-managed rows (the default) from env-declared rows reconciled at boot from OIDC_ROLE_MAPPINGS. Env-managed rows are read-only via the API — they can only be changed by editing the env var and restarting.
func (OidcRoleMapping) TableName ¶ added in v2.8.1
func (OidcRoleMapping) TableName() string
type Role ¶ added in v2.8.1
type Role struct {
database.BaseModel
Name string `json:"name" gorm:"column:name;not null;uniqueIndex" sortable:"true"`
Description *string `json:"description,omitempty" gorm:"column:description"`
Permissions database.StringSlice `json:"permissions" gorm:"column:permissions;type:text;not null"`
BuiltIn bool `json:"builtIn" gorm:"column:built_in;not null;default:false" sortable:"true"`
}
Role is a named permission set. Built-in roles (Admin, Editor, Deployer, Viewer) are seeded by migration 054 and cannot be edited or deleted.
type RoleHandler ¶
type RoleHandler struct {
// contains filtered or unexported fields
}
func (*RoleHandler) CreateRole ¶
func (h *RoleHandler) CreateRole(ctx context.Context, input *CreateRoleInput) (*handlerutil.Out[roletypes.Role], error)
func (*RoleHandler) DeleteRole ¶
func (h *RoleHandler) DeleteRole(ctx context.Context, input *DeleteRoleInput) (*handlerutil.Out[base.MessageResponse], error)
func (*RoleHandler) GetPermissionsManifest ¶
func (h *RoleHandler) GetPermissionsManifest(_ context.Context, _ *struct{}) (*handlerutil.Out[roletypes.PermissionsManifest], error)
func (*RoleHandler) GetRole ¶
func (h *RoleHandler) GetRole(ctx context.Context, input *GetRoleInput) (*handlerutil.Out[roletypes.Role], error)
func (*RoleHandler) ListRoles ¶
func (h *RoleHandler) ListRoles(ctx context.Context, input *ListRolesInput) (*handlerutil.Page[roletypes.Role], error)
func (*RoleHandler) ListUserRoleAssignments ¶
func (h *RoleHandler) ListUserRoleAssignments(ctx context.Context, input *ListUserRoleAssignmentsInput) (*handlerutil.Out[[]roletypes.RoleAssignment], error)
func (*RoleHandler) SetUserRoleAssignments ¶
func (h *RoleHandler) SetUserRoleAssignments(ctx context.Context, input *SetUserRoleAssignmentsInput) (*handlerutil.Out[[]roletypes.RoleAssignment], error)
func (*RoleHandler) UpdateRole ¶
func (h *RoleHandler) UpdateRole(ctx context.Context, input *UpdateRoleInput) (*handlerutil.Out[roletypes.Role], error)
type RoleService ¶
type RoleService struct {
// contains filtered or unexported fields
}
func NewRoleService ¶
func NewRoleService(db *database.DB) *RoleService
func (*RoleService) AssertGlobalAdminExists ¶
AssertGlobalAdminExists returns common.ErrNoGlobalAdminRemains when no non-service user is a global admin in tx.
func (*RoleService) BackfillLegacyRoleAssignments ¶
func (s *RoleService) BackfillLegacyRoleAssignments(ctx context.Context) error
BackfillLegacyRoleAssignments converts pre-RBAC users.roles into global assignments once.
func (*RoleService) CountGlobalAdmins ¶ added in v2.17.0
func (*RoleService) CountUsersAssignedToRole ¶
CountUsersAssignedToRole counts distinct users assigned to roleID in any source or scope.
func (*RoleService) CreateOidcMapping ¶
func (s *RoleService) CreateOidcMapping(ctx context.Context, claimValue, roleID string, environmentID *string) (*OidcRoleMapping, error)
func (*RoleService) CreateRole ¶
func (*RoleService) DeleteOidcMapping ¶
func (s *RoleService) DeleteOidcMapping(ctx context.Context, id string) error
func (*RoleService) DeleteRole ¶
func (s *RoleService) DeleteRole(ctx context.Context, id string) error
func (*RoleService) EnsureBuiltInRoles ¶
func (s *RoleService) EnsureBuiltInRoles(ctx context.Context) error
func (*RoleService) GetOidcMapping ¶
func (s *RoleService) GetOidcMapping(ctx context.Context, id string) (*OidcRoleMapping, error)
func (*RoleService) InvalidateApiKey ¶
func (s *RoleService) InvalidateApiKey(apiKeyID string)
InvalidateApiKey drops the cached permissions for one API key.
func (*RoleService) InvalidateUser ¶
func (s *RoleService) InvalidateUser(userID string)
InvalidateUser drops the cached permissions for one user.
func (*RoleService) ListAllRoles ¶
func (s *RoleService) ListAllRoles(ctx context.Context) ([]Role, error)
func (*RoleService) ListOidcMappings ¶
func (s *RoleService) ListOidcMappings(ctx context.Context) ([]OidcRoleMapping, error)
func (*RoleService) ListRoles ¶
func (s *RoleService) ListRoles(ctx context.Context, params pagination.QueryParams) ([]Role, pagination.Response, error)
func (*RoleService) ListUserAssignments ¶
func (s *RoleService) ListUserAssignments(ctx context.Context, userID string) ([]UserRoleAssignment, error)
func (*RoleService) LockGlobalAdminGuard ¶ added in v2.17.0
func (s *RoleService) LockGlobalAdminGuard(tx *gorm.DB) error
func (*RoleService) ReconcileEnvOidcMappings ¶
func (s *RoleService) ReconcileEnvOidcMappings(ctx context.Context, rawSpec string) error
ReconcileEnvOidcMappings replaces source='env' OIDC mappings with rawSpec at boot. Empty rawSpec leaves rows alone; manual rows are never touched.
func (*RoleService) ReplaceUserAssignments ¶ added in v2.17.0
func (s *RoleService) ReplaceUserAssignments(ctx context.Context, userID, source string, desired []UserRoleAssignment) error
ReplaceUserAssignments replaces the user's assignments for one source and enforces the global-admin guard.
func (*RoleService) ResolveApiKeyPermissions ¶
func (s *RoleService) ResolveApiKeyPermissions(ctx context.Context, apiKeyID string) (*authz.PermissionSet, error)
ResolveApiKeyPermissions returns the API key's permissions, cached per key.
func (*RoleService) ResolveExecutionPermissions ¶ added in v2.15.0
func (s *RoleService) ResolveExecutionPermissions(ctx context.Context, userID, keyID string) (*authz.PermissionSet, error)
ResolveExecutionPermissions revalidates durable work against current users and keys, bypassing caches.
func (*RoleService) ResolvePermissions ¶
func (s *RoleService) ResolvePermissions(ctx context.Context, userID string) (*authz.PermissionSet, error)
ResolvePermissions returns the user's effective permissions, cached for permissionCacheTTL.
func (*RoleService) ResolveUserPermissionsInDB ¶
func (s *RoleService) ResolveUserPermissionsInDB(_ context.Context, tx *gorm.DB, userID string) (*authz.PermissionSet, error)
ResolveUserPermissionsInDB resolves the user's permissions in tx.
func (*RoleService) SetApiKeyPermissions ¶
func (s *RoleService) SetApiKeyPermissions(ctx context.Context, apiKeyID string, grants []ApiKeyPermission) error
SetApiKeyPermissions atomically replaces the API key's permission rows.
func (*RoleService) SetApiKeyPermissionsInDB ¶
func (s *RoleService) SetApiKeyPermissionsInDB(ctx context.Context, tx *gorm.DB, apiKeyID string, grants []ApiKeyPermission) error
SetApiKeyPermissionsInDB replaces the API key's permission rows in tx.
func (*RoleService) Stop ¶ added in v2.17.0
func (s *RoleService) Stop()
func (*RoleService) UpdateOidcMapping ¶
func (s *RoleService) UpdateOidcMapping(ctx context.Context, id, claimValue, roleID string, environmentID *string) (*OidcRoleMapping, error)
func (*RoleService) UpdateRole ¶
func (*RoleService) ValidatePermissionsAgainstCaller ¶
func (s *RoleService) ValidatePermissionsAgainstCaller(caller *authz.PermissionSet, desired []string) error
ValidatePermissionsAgainstCaller rejects unknown permissions, then any the caller lacks globally. Env-scoped grants are insufficient because roles can later be assigned globally.
func (*RoleService) ValidateRoleAssignmentAgainstCaller ¶
func (s *RoleService) ValidateRoleAssignmentAgainstCaller(ctx context.Context, caller *authz.PermissionSet, roleID string, environmentID *string) error
ValidateRoleAssignmentAgainstCaller rejects a role whose permissions the caller lacks at that scope.
type SetUserRoleAssignmentsInput ¶
type SetUserRoleAssignmentsInput struct {
UserID string `path:"userId" doc:"User ID"`
Body roletypes.SetUserAssignments
}
type UpdateRoleInput ¶
type UpdateRoleInput struct {
ID string `path:"id" doc:"Role ID"`
Body roletypes.UpdateRole
}
type UserRoleAssignment ¶ added in v2.8.1
type UserRoleAssignment struct {
database.BaseModel
UserID string `json:"userId" gorm:"column:user_id;not null;index"`
RoleID string `json:"roleId" gorm:"column:role_id;not null;index"`
EnvironmentID *string `json:"environmentId,omitempty" gorm:"column:environment_id;index"`
Source string `json:"source" gorm:"column:source;not null;default:'manual'"`
}
UserRoleAssignment binds a user to a role, optionally scoped to one environment. EnvironmentID == nil means "global" — the role's permissions apply across all environments AND to org-level resources.
Source distinguishes manual assignments (managed by admins via the UI) from assignments synthesized from OIDC group mappings on every login.
func (UserRoleAssignment) TableName ¶ added in v2.8.1
func (UserRoleAssignment) TableName() string