package authz import ( "context" "errors" ) type contextKey string const principalKey contextKey = "principal" const ( RoleAdmin = "admin" RoleUser = "user" ) const ( VisibilityPrivate = "private" VisibilityWorkspaceShared = "workspace_shared" VisibilityGlobalShared = "global_shared" ) var ( ErrUnauthenticated = errors.New("authentication required") ErrForbidden = errors.New("permission denied") ) type Principal struct { UserID string Username string Role string WorkspaceID string WorkspaceName string Namespace string DefaultClusterID string QuotaCPU string QuotaMemory string QuotaGPU string QuotaGPUMem string Permissions []string PermissionVersion int } func WithPrincipal(ctx context.Context, principal *Principal) context.Context { return context.WithValue(ctx, principalKey, principal) } func PrincipalFromContext(ctx context.Context) (*Principal, bool) { principal, ok := ctx.Value(principalKey).(*Principal) return principal, ok && principal != nil } func RequirePrincipal(ctx context.Context) (*Principal, error) { principal, ok := PrincipalFromContext(ctx) if !ok { return nil, ErrUnauthenticated } return principal, nil } func (p *Principal) IsAdmin() bool { return p != nil && p.Role == RoleAdmin } func CanReadResource(p *Principal, workspaceID, ownerID, visibility string) bool { if p == nil { return false } if p.IsAdmin() { return true } switch visibility { case VisibilityGlobalShared: return true case VisibilityWorkspaceShared: return workspaceID != "" && workspaceID == p.WorkspaceID default: return ownerID != "" && ownerID == p.UserID } } func CanWriteResource(p *Principal, workspaceID, ownerID, visibility string) bool { if p == nil { return false } if p.IsAdmin() { return true } if visibility == VisibilityGlobalShared { return false } return workspaceID != "" && workspaceID == p.WorkspaceID && ownerID != "" && ownerID == p.UserID } func NormalizeVisibility(role, requested string) string { switch requested { case VisibilityWorkspaceShared: if role == RoleAdmin { return requested } return VisibilityPrivate case VisibilityGlobalShared: if role == RoleAdmin { return requested } return VisibilityPrivate case VisibilityPrivate: return requested default: return VisibilityPrivate } } func PermissionsForRole(role string) []string { if role == RoleAdmin { return []string{ "*", "home:view", "workspaces:manage", "users:manage", "configuration:clusters:manage", "configuration:registries:manage", "artifact:registries:view", "artifact:instances:manage", "monitoring:clusters:view", "clusters:manage:any", "registries:manage:any", "instances:manage:any", "kubeconfig:issue:any", } } return []string{ "home:view", "configuration:clusters:manage_own", "configuration:registries:manage_own", "artifact:registries:view", "artifact:instances:manage_own", "monitoring:clusters:view", "clusters:manage:own", "registries:manage:own", "instances:manage:own", "kubeconfig:issue:own", } }