package domain import "time" // APIKeyID is a strongly-typed identifier for API keys. type APIKeyID string // Scope represents a permission scope for API keys. type Scope string const ( ScopeAdmin Scope = "admin" ScopeProjectsRead Scope = "projects:read" ScopeProjectsExecute Scope = "projects:execute" ScopeKeysManage Scope = "keys:manage" ) // APIKey represents an API key for authentication. type APIKey struct { ID APIKeyID Name string KeyPrefix string // First 8 chars of key for identification Scopes []Scope ProjectIDs []ProjectID // nil = access to all projects CreatedAt time.Time ExpiresAt *time.Time LastUsedAt *time.Time RevokedAt *time.Time CreatedBy string } // IsExpired returns true if the key has expired. func (k *APIKey) IsExpired() bool { if k.ExpiresAt == nil { return false } return time.Now().After(*k.ExpiresAt) } // IsRevoked returns true if the key has been revoked. func (k *APIKey) IsRevoked() bool { return k.RevokedAt != nil } // IsActive returns true if the key is valid for use. func (k *APIKey) IsActive() bool { return !k.IsRevoked() && !k.IsExpired() } // HasScope returns true if the key has the specified scope. func (k *APIKey) HasScope(scope Scope) bool { // Admin scope grants all permissions for _, s := range k.Scopes { if s == ScopeAdmin || s == scope { return true } } return false } // HasAnyScope returns true if the key has any of the specified scopes. func (k *APIKey) HasAnyScope(scopes ...Scope) bool { for _, scope := range scopes { if k.HasScope(scope) { return true } } return false } // HasProjectAccess returns true if the key can access the given project. func (k *APIKey) HasProjectAccess(projectID ProjectID) bool { // Admin or nil project list means access to all projects if k.HasScope(ScopeAdmin) || k.ProjectIDs == nil { return true } for _, pid := range k.ProjectIDs { if pid == projectID { return true } } return false }