package auth import "slices" // Scope represents an API permission scope. type Scope string // Available scopes. const ( ScopeProjectsRead Scope = "projects:read" ScopeProjectsExecute Scope = "projects:execute" ScopeKeysRead Scope = "keys:read" ScopeKeysWrite Scope = "keys:write" ScopeAuditRead Scope = "audit:read" ScopeQueueRead Scope = "queue:read" ScopeQueueWrite Scope = "queue:write" ScopeWebhookRead Scope = "webhook:read" ScopeWebhookWrite Scope = "webhook:write" ScopeAdmin Scope = "admin" ) // AllScopes is the list of all valid scopes. var AllScopes = []Scope{ ScopeProjectsRead, ScopeProjectsExecute, ScopeKeysRead, ScopeKeysWrite, ScopeAuditRead, ScopeQueueRead, ScopeQueueWrite, ScopeWebhookRead, ScopeWebhookWrite, ScopeAdmin, } // ScopeDescriptions provides human-readable descriptions. var ScopeDescriptions = map[Scope]string{ ScopeProjectsRead: "List and view project details", ScopeProjectsExecute: "Execute commands (claude, shell, git) on projects", ScopeKeysRead: "List API keys (metadata only, not secrets)", ScopeKeysWrite: "Create and revoke API keys", ScopeAuditRead: "View audit logs for command executions", ScopeQueueRead: "View queued commands and queue status", ScopeQueueWrite: "Enqueue and cancel queued commands", ScopeWebhookRead: "View webhooks and delivery history", ScopeWebhookWrite: "Create, update, and delete webhooks", ScopeAdmin: "Full administrative access (includes all scopes)", } // IsValid checks if a scope is valid. func (s Scope) IsValid() bool { return slices.Contains(AllScopes, s) } // String returns the scope as a string. func (s Scope) String() string { return string(s) } // ScopesFromStrings converts string slice to Scope slice. func ScopesFromStrings(ss []string) []Scope { scopes := make([]Scope, len(ss)) for i, s := range ss { scopes[i] = Scope(s) } return scopes } // ScopesToStrings converts Scope slice to string slice. func ScopesToStrings(scopes []Scope) []string { ss := make([]string, len(scopes)) for i, s := range scopes { ss[i] = string(s) } return ss } // ValidateScopes checks if all scopes are valid. func ValidateScopes(scopes []Scope) bool { for _, s := range scopes { if !s.IsValid() { return false } } return true } // HasScope checks if a scope list contains a required scope. // Admin scope grants access to everything. func HasScope(scopes []Scope, required Scope) bool { for _, s := range scopes { if s == ScopeAdmin || s == required { return true } } return false } // HasAnyScope checks if a scope list contains any of the required scopes. func HasAnyScope(scopes []Scope, required ...Scope) bool { for _, r := range required { if HasScope(scopes, r) { return true } } return false } // HasProjectAccess checks if the key has access to a specific project. // projectIDs nil means access to all projects. func HasProjectAccess(allowedProjects []string, projectID string) bool { if allowedProjects == nil { return true // nil = all projects } return slices.Contains(allowedProjects, projectID) }