Documentation
¶
Index ¶
- Constants
- Variables
- func APIKeyAlreadyExists(prefix string) *errs.AuthsomeError
- func APIKeyCreationFailed(err error) *errs.AuthsomeError
- func APIKeyDeletionFailed(err error) *errs.AuthsomeError
- func APIKeyExpired() *errs.AuthsomeError
- func APIKeyInactive() *errs.AuthsomeError
- func APIKeyNotFound() *errs.AuthsomeError
- func APIKeyRotationFailed(err error) *errs.AuthsomeError
- func APIKeyUpdateFailed(err error) *errs.AuthsomeError
- func APIKeyVerificationFailed(reason string) *errs.AuthsomeError
- func AccessDenied(reason string) *errs.AuthsomeError
- func CheckScopeOrRBAC(scopes []string, rbacPermissions []string, ...) bool
- func GenerateSuggestedRole(scopes []string) string
- func IPNotAllowed(ip string) *errs.AuthsomeError
- func InsufficientPermission(required string) *errs.AuthsomeError
- func InsufficientScope(required string) *errs.AuthsomeError
- func InvalidAPIKeyHash() *errs.AuthsomeError
- func InvalidKeyFormat() *errs.AuthsomeError
- func InvalidRateLimit(rateLimit, maxRateLimit int) *errs.AuthsomeError
- func IsSafeForPublicKey(scope string) bool
- func MapScopeToRBAC(scope string) (action, resource string)
- func MaxKeysReached(limit int) *errs.AuthsomeError
- func MissingAppContext() *errs.AuthsomeError
- func MissingEnvContext() *errs.AuthsomeError
- type APIKey
- type Config
- type CreateAPIKeyRequest
- type EffectivePermissions
- type EnvironmentRepository
- type KeyType
- type ListAPIKeysFilter
- type ListAPIKeysResponse
- type Permission
- type RBACPermission
- type Repository
- type Role
- type RoleRepository
- type RotateAPIKeyRequest
- type Service
- func (s *Service) AssignRole(ctx context.Context, apiKeyID, roleID xid.ID, orgID *xid.ID, createdBy *xid.ID) error
- func (s *Service) BulkAssignRoles(ctx context.Context, apiKeyID xid.ID, roleIDs []xid.ID, orgID *xid.ID, ...) error
- func (s *Service) CanAccess(ctx context.Context, apiKey *APIKey, action, resource string, orgID *xid.ID) (bool, error)
- func (s *Service) CleanupExpired(ctx context.Context) (int, error)
- func (s *Service) CreateAPIKey(ctx context.Context, req *CreateAPIKeyRequest) (*APIKey, error)
- func (s *Service) DeleteAPIKey(ctx context.Context, appID, id, userID xid.ID, orgID *xid.ID) error
- func (s *Service) GetAPIKey(ctx context.Context, appID, id, userID xid.ID, orgID *xid.ID) (*APIKey, error)
- func (s *Service) GetEffectivePermissions(ctx context.Context, apiKeyID xid.ID, orgID *xid.ID) (*EffectivePermissions, error)
- func (s *Service) GetPermissions(ctx context.Context, apiKeyID xid.ID, orgID *xid.ID) ([]*Permission, error)
- func (s *Service) GetRoles(ctx context.Context, apiKeyID xid.ID, orgID *xid.ID) ([]*Role, error)
- func (s *Service) ListAPIKeys(ctx context.Context, filter *ListAPIKeysFilter) (*ListAPIKeysResponse, error)
- func (s *Service) RotateAPIKey(ctx context.Context, req *RotateAPIKeyRequest) (*APIKey, error)
- func (s *Service) SetEnvironmentRepository(envRepo EnvironmentRepository)
- func (s *Service) SetRoleRepository(roleRepo RoleRepository)
- func (s *Service) UnassignRole(ctx context.Context, apiKeyID, roleID xid.ID, orgID *xid.ID, actorID *xid.ID) error
- func (s *Service) UpdateAPIKey(ctx context.Context, appID, id, userID xid.ID, orgID *xid.ID, ...) (*APIKey, error)
- func (s *Service) VerifyAPIKey(ctx context.Context, req *VerifyAPIKeyRequest) (*VerifyAPIKeyResponse, error)
- type UpdateAPIKeyRequest
- type VerifyAPIKeyRequest
- type VerifyAPIKeyResponse
Constants ¶
const ( CodeAPIKeyNotFound = "API_KEY_NOT_FOUND" CodeAPIKeyInactive = "API_KEY_INACTIVE" CodeAPIKeyExpired = "API_KEY_EXPIRED" CodeInsufficientScope = "INSUFFICIENT_SCOPE" CodeInsufficientPermission = "INSUFFICIENT_PERMISSION" CodeIPNotAllowed = "IP_NOT_ALLOWED" CodeInvalidKeyFormat = "INVALID_KEY_FORMAT" CodeMaxKeysReached = "MAX_KEYS_REACHED" CodeAPIKeyAlreadyExists = "API_KEY_ALREADY_EXISTS" CodeAPIKeyCreationFailed = "API_KEY_CREATION_FAILED" CodeAPIKeyUpdateFailed = "API_KEY_UPDATE_FAILED" CodeAPIKeyDeletionFailed = "API_KEY_DELETION_FAILED" CodeAPIKeyRotationFailed = "API_KEY_ROTATION_FAILED" CodeAPIKeyVerificationFailed = "API_KEY_VERIFICATION_FAILED" CodeInvalidAPIKeyHash = "INVALID_API_KEY_HASH" CodeMissingAppContext = "MISSING_APP_CONTEXT" CodeMissingEnvContext = "MISSING_ENV_CONTEXT" CodeAccessDenied = "ACCESS_DENIED" CodeInvalidRateLimit = "INVALID_RATE_LIMIT" )
const ( // KeyTypePublishable - Frontend-safe, identifies app, limited operations // Can be safely exposed in client-side code (browser, mobile apps) // Limited to read-only and session creation operations KeyTypePublishable = base.KeyTypePublishable // KeyTypeSecret - Backend-only, full administrative privileges // Must be kept secret on server-side only // Has unrestricted access to all operations KeyTypeSecret = base.KeyTypeSecret // KeyTypeRestricted - Backend-only, scoped to specific operations // Must be kept secret on server-side // Access limited to explicitly granted scopes KeyTypeRestricted = base.KeyTypeRestricted )
Variables ¶
var ( ErrAPIKeyNotFound = &errs.AuthsomeError{Code: CodeAPIKeyNotFound} ErrAPIKeyInactive = &errs.AuthsomeError{Code: CodeAPIKeyInactive} ErrAPIKeyExpired = &errs.AuthsomeError{Code: CodeAPIKeyExpired} ErrInsufficientScope = &errs.AuthsomeError{Code: CodeInsufficientScope} ErrInsufficientPermission = &errs.AuthsomeError{Code: CodeInsufficientPermission} ErrIPNotAllowed = &errs.AuthsomeError{Code: CodeIPNotAllowed} ErrInvalidKeyFormat = &errs.AuthsomeError{Code: CodeInvalidKeyFormat} ErrMaxKeysReached = &errs.AuthsomeError{Code: CodeMaxKeysReached} ErrAPIKeyAlreadyExists = &errs.AuthsomeError{Code: CodeAPIKeyAlreadyExists} ErrAPIKeyCreationFailed = &errs.AuthsomeError{Code: CodeAPIKeyCreationFailed} ErrAPIKeyUpdateFailed = &errs.AuthsomeError{Code: CodeAPIKeyUpdateFailed} ErrAPIKeyDeletionFailed = &errs.AuthsomeError{Code: CodeAPIKeyDeletionFailed} ErrAPIKeyRotationFailed = &errs.AuthsomeError{Code: CodeAPIKeyRotationFailed} ErrAPIKeyVerificationFailed = &errs.AuthsomeError{Code: CodeAPIKeyVerificationFailed} ErrInvalidAPIKeyHash = &errs.AuthsomeError{Code: CodeInvalidAPIKeyHash} ErrMissingAppContext = &errs.AuthsomeError{Code: CodeMissingAppContext} ErrMissingEnvContext = &errs.AuthsomeError{Code: CodeMissingEnvContext} ErrAccessDenied = &errs.AuthsomeError{Code: CodeAccessDenied} ErrInvalidRateLimit = &errs.AuthsomeError{Code: CodeInvalidRateLimit} )
var KeyTypeScopes = map[KeyType][]string{ KeyTypePublishable: { "app:identify", "sessions:create", "users:verify", "public:read", }, KeyTypeSecret: { "admin:full", }, KeyTypeRestricted: {}, }
KeyTypeScopes defines default scopes for each key type These are automatically granted based on key type
var SafePublicScopes = map[string]bool{ "app:identify": true, "sessions:create": true, "sessions:verify": true, "users:verify": true, "users:read": true, "public:read": true, "webhooks:verify": true, }
SafePublicScopes defines scopes that are safe for publishable keys Only these scopes can be granted to pk_ keys
var ScopeToRBACMapping = map[string]RBACPermission{
"users:read": {Action: "view", Resource: "users"},
"users:write": {Action: "edit", Resource: "users"},
"users:create": {Action: "create", Resource: "users"},
"users:delete": {Action: "delete", Resource: "users"},
"users:*": {Action: "*", Resource: "users"},
"sessions:read": {Action: "view", Resource: "sessions"},
"sessions:create": {Action: "create", Resource: "sessions"},
"sessions:delete": {Action: "delete", Resource: "sessions"},
"sessions:*": {Action: "*", Resource: "sessions"},
"apikeys:read": {Action: "view", Resource: "apikeys"},
"apikeys:write": {Action: "edit", Resource: "apikeys"},
"apikeys:create": {Action: "create", Resource: "apikeys"},
"apikeys:delete": {Action: "delete", Resource: "apikeys"},
"apikeys:*": {Action: "*", Resource: "apikeys"},
"organizations:read": {Action: "view", Resource: "organizations"},
"organizations:write": {Action: "edit", Resource: "organizations"},
"organizations:create": {Action: "create", Resource: "organizations"},
"organizations:delete": {Action: "delete", Resource: "organizations"},
"organizations:*": {Action: "*", Resource: "organizations"},
"roles:read": {Action: "view", Resource: "roles"},
"roles:write": {Action: "edit", Resource: "roles"},
"roles:create": {Action: "create", Resource: "roles"},
"roles:delete": {Action: "delete", Resource: "roles"},
"roles:*": {Action: "*", Resource: "roles"},
"permissions:read": {Action: "view", Resource: "permissions"},
"permissions:write": {Action: "edit", Resource: "permissions"},
"permissions:create": {Action: "create", Resource: "permissions"},
"permissions:delete": {Action: "delete", Resource: "permissions"},
"permissions:*": {Action: "*", Resource: "permissions"},
"admin:full": {Action: "*", Resource: "*"},
"admin:users": {Action: "*", Resource: "users"},
"admin:orgs": {Action: "*", Resource: "organizations"},
"app:identify": {Action: "identify", Resource: "app"},
"public:read": {Action: "view", Resource: "public"},
"users:verify": {Action: "verify", Resource: "users"},
}
ScopeToRBACMapping maps legacy scope strings to RBAC (action, resource) pairs This enables backward compatibility with existing scopes while migrating to RBAC
Functions ¶
func APIKeyAlreadyExists ¶
func APIKeyAlreadyExists(prefix string) *errs.AuthsomeError
func APIKeyCreationFailed ¶
func APIKeyCreationFailed(err error) *errs.AuthsomeError
CRUD operation errors
func APIKeyDeletionFailed ¶
func APIKeyDeletionFailed(err error) *errs.AuthsomeError
func APIKeyExpired ¶
func APIKeyExpired() *errs.AuthsomeError
func APIKeyInactive ¶
func APIKeyInactive() *errs.AuthsomeError
func APIKeyRotationFailed ¶
func APIKeyRotationFailed(err error) *errs.AuthsomeError
func APIKeyUpdateFailed ¶
func APIKeyUpdateFailed(err error) *errs.AuthsomeError
func APIKeyVerificationFailed ¶
func APIKeyVerificationFailed(reason string) *errs.AuthsomeError
func CheckScopeOrRBAC ¶
func CheckScopeOrRBAC(scopes []string, rbacPermissions []string, requiredAction, requiredResource string) bool
CheckScopeOrRBAC checks if a scope string OR RBAC permission grants access This is the flexible check for backward compatibility
func GenerateSuggestedRole ¶
GenerateSuggestedRole analyzes scopes and suggests appropriate RBAC roles Returns suggested role names based on the scope patterns
func InsufficientPermission ¶
func InsufficientPermission(required string) *errs.AuthsomeError
func InsufficientScope ¶
func InsufficientScope(required string) *errs.AuthsomeError
Permission and scope errors
func InvalidAPIKeyHash ¶
func InvalidAPIKeyHash() *errs.AuthsomeError
func InvalidKeyFormat ¶
func InvalidKeyFormat() *errs.AuthsomeError
func InvalidRateLimit ¶
func InvalidRateLimit(rateLimit, maxRateLimit int) *errs.AuthsomeError
func IsSafeForPublicKey ¶
IsSafeForPublicKey checks if a scope is safe for publishable keys
func MapScopeToRBAC ¶
MapScopeToRBAC converts a legacy scope string to RBAC action and resource Returns ("", "") if no mapping exists
func MissingEnvContext ¶
func MissingEnvContext() *errs.AuthsomeError
Types ¶
type APIKey ¶
APIKey represents an API key with its metadata (DTO) Updated for V2 architecture: App → Environment → Organization
func FromSchemaAPIKey ¶
FromSchemaAPIKey converts a schema.APIKey to APIKey DTO
func FromSchemaAPIKeys ¶
FromSchemaAPIKeys converts multiple schema.APIKey to APIKey DTOs
type Config ¶
type Config struct {
DefaultRateLimit int `json:"default_rate_limit"`
MaxRateLimit int `json:"max_rate_limit"`
DefaultExpiry time.Duration `json:"default_expiry"`
MaxKeysPerUser int `json:"max_keys_per_user"`
MaxKeysPerOrg int `json:"max_keys_per_org"`
KeyLength int `json:"key_length"`
}
Config holds the API key service configuration
type CreateAPIKeyRequest ¶
type CreateAPIKeyRequest = base.CreateAPIKeyRequest
CreateAPIKeyRequest represents a request to create an API key Updated for V2 architecture
type EffectivePermissions ¶
type EffectivePermissions struct {
Scopes []string `json:"scopes"` // Legacy scope strings
Permissions []*Permission `json:"permissions"` // RBAC permissions
DelegatedFromCreator bool `json:"delegatedFromCreator"` // If creator permissions are included
ImpersonatingUser *xid.ID `json:"impersonatingUser,omitempty"` // If impersonating a user
}
EffectivePermissions represents all permissions that apply to an API key
func (*EffectivePermissions) CanAccess ¶
func (ep *EffectivePermissions) CanAccess(action, resource string) bool
CanAccess checks if effective permissions allow access (scopes OR RBAC)
func (*EffectivePermissions) HasPermission ¶
func (ep *EffectivePermissions) HasPermission(action, resource string) bool
HasPermission checks if effective permissions include a specific action/resource
func (*EffectivePermissions) HasScope ¶
func (ep *EffectivePermissions) HasScope(scope string) bool
HasScope checks if effective permissions include a specific scope
type EnvironmentRepository ¶ added in v0.0.5
type EnvironmentRepository interface {
FindByID(ctx context.Context, id xid.ID) (*schema.Environment, error)
}
EnvironmentRepository provides environment lookup for prefix generation This is a minimal interface to avoid tight coupling with the environment service
type ListAPIKeysFilter ¶
type ListAPIKeysFilter struct {
pagination.PaginationParams
AppID xid.ID `json:"appId" query:"app_id"`
EnvironmentID *xid.ID `json:"environmentId,omitempty" query:"environment_id"`
OrganizationID *xid.ID `json:"organizationId,omitempty" query:"organization_id"`
UserID *xid.ID `json:"userId,omitempty" query:"user_id"`
Active *bool `json:"active,omitempty" query:"active"`
}
ListAPIKeysFilter represents filter parameters for listing API keys Supports flexible filtering by app, environment, organization, and user
type ListAPIKeysResponse ¶
type ListAPIKeysResponse = pagination.PageResponse[*APIKey]
ListAPIKeysResponse is a type alias for the paginated response
type Permission ¶
type Permission struct {
ID xid.ID `json:"id"`
Action string `json:"action"` // e.g., "view", "edit", "delete", "*"
Resource string `json:"resource"` // e.g., "users", "posts", "*"
Source string `json:"source,omitempty"` // "key", "creator", "impersonation"
}
Permission represents an RBAC permission (simplified DTO)
type RBACPermission ¶
type RBACPermission struct {
Action string // e.g., "view", "edit", "create", "delete", "*"
Resource string // e.g., "users", "sessions", "apikeys", "*"
}
RBACPermission represents a parsed RBAC permission
func ConvertScopesToRBAC ¶
func ConvertScopesToRBAC(scopes []string) []RBACPermission
ConvertScopesToRBAC converts an array of scope strings to RBAC permissions Useful for migrating existing API keys from scopes to RBAC roles
type Repository ¶
type Repository interface {
// Create/Read operations
CreateAPIKey(ctx context.Context, key *schema.APIKey) error
FindAPIKeyByID(ctx context.Context, id xid.ID) (*schema.APIKey, error)
FindAPIKeyByPrefix(ctx context.Context, prefix string) (*schema.APIKey, error)
// List with pagination
ListAPIKeys(ctx context.Context, filter *ListAPIKeysFilter) (*pagination.PageResponse[*schema.APIKey], error)
// Update operations
UpdateAPIKey(ctx context.Context, key *schema.APIKey) error
UpdateAPIKeyUsage(ctx context.Context, id xid.ID, ip, userAgent string) error
DeactivateAPIKey(ctx context.Context, id xid.ID) error
DeleteAPIKey(ctx context.Context, id xid.ID) error
// Count operations
CountAPIKeys(ctx context.Context, appID xid.ID, envID *xid.ID, orgID *xid.ID, userID *xid.ID) (int, error)
// Maintenance
CleanupExpiredAPIKeys(ctx context.Context) (int, error)
}
Repository defines the interface for API key storage operations Following Interface Segregation Principle (ISP) - works with schema types
type Role ¶
type Role struct {
ID xid.ID `json:"id"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
}
Role represents an RBAC role (simplified DTO)
type RoleRepository ¶
type RoleRepository interface {
// Role assignment
AssignRole(ctx context.Context, apiKeyID, roleID xid.ID, orgID *xid.ID, createdBy *xid.ID) error
UnassignRole(ctx context.Context, apiKeyID, roleID xid.ID, orgID *xid.ID) error
BulkAssignRoles(ctx context.Context, apiKeyID xid.ID, roleIDs []xid.ID, orgID *xid.ID, createdBy *xid.ID) error
BulkUnassignRoles(ctx context.Context, apiKeyID xid.ID, roleIDs []xid.ID, orgID *xid.ID) error
ReplaceRoles(ctx context.Context, apiKeyID xid.ID, roleIDs []xid.ID, orgID *xid.ID, createdBy *xid.ID) error
// Role queries
GetRoles(ctx context.Context, apiKeyID xid.ID, orgID *xid.ID) ([]*schema.Role, error)
HasRole(ctx context.Context, apiKeyID, roleID xid.ID, orgID *xid.ID) (bool, error)
GetAPIKeysWithRole(ctx context.Context, roleID xid.ID, orgID *xid.ID) ([]*schema.APIKey, error)
// Permission queries
GetPermissions(ctx context.Context, apiKeyID xid.ID, orgID *xid.ID) ([]*schema.Permission, error)
// Creator permissions (for delegation)
GetCreatorPermissions(ctx context.Context, creatorID xid.ID, orgID *xid.ID) ([]*schema.Permission, error)
GetCreatorRoles(ctx context.Context, creatorID xid.ID, orgID *xid.ID) ([]*schema.Role, error)
}
RoleRepository interface for RBAC operations on API keys This is implemented by repository.APIKeyRoleRepository
type RotateAPIKeyRequest ¶
type RotateAPIKeyRequest = base.RotateAPIKeyRequest
RotateAPIKeyRequest represents a request to rotate an API key Updated for V2 architecture
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service handles API key operations Updated for V2 architecture: App → Environment → Organization
func NewService ¶
func NewService(repo Repository, auditSvc *audit.Service, cfg Config) *Service
NewService creates a new API key service
func (*Service) AssignRole ¶
func (s *Service) AssignRole(ctx context.Context, apiKeyID, roleID xid.ID, orgID *xid.ID, createdBy *xid.ID) error
AssignRole assigns a role to an API key
func (*Service) BulkAssignRoles ¶
func (s *Service) BulkAssignRoles(ctx context.Context, apiKeyID xid.ID, roleIDs []xid.ID, orgID *xid.ID, createdBy *xid.ID) error
BulkAssignRoles assigns multiple roles to an API key
func (*Service) CanAccess ¶
func (s *Service) CanAccess(ctx context.Context, apiKey *APIKey, action, resource string, orgID *xid.ID) (bool, error)
CanAccess checks if an API key can perform a specific action on a resource This checks both scopes (legacy) and RBAC permissions (new)
func (*Service) CleanupExpired ¶
CleanupExpired removes expired API keys
func (*Service) CreateAPIKey ¶
CreateAPIKey creates a new API key
func (*Service) DeleteAPIKey ¶
DeleteAPIKey deletes an API key
func (*Service) GetAPIKey ¶
func (s *Service) GetAPIKey(ctx context.Context, appID, id, userID xid.ID, orgID *xid.ID) (*APIKey, error)
GetAPIKey retrieves an API key by ID
func (*Service) GetEffectivePermissions ¶
func (s *Service) GetEffectivePermissions(ctx context.Context, apiKeyID xid.ID, orgID *xid.ID) (*EffectivePermissions, error)
GetEffectivePermissions computes all effective permissions for an API key This includes: 1. API key's own permissions (scopes + roles) 2. If delegation enabled: creator's permissions 3. If impersonation set: target user's permissions
func (*Service) GetPermissions ¶
func (s *Service) GetPermissions(ctx context.Context, apiKeyID xid.ID, orgID *xid.ID) ([]*Permission, error)
GetPermissions retrieves all permissions for an API key through its roles
func (*Service) ListAPIKeys ¶
func (s *Service) ListAPIKeys(ctx context.Context, filter *ListAPIKeysFilter) (*ListAPIKeysResponse, error)
ListAPIKeys lists API keys with filtering and pagination
func (*Service) RotateAPIKey ¶
RotateAPIKey rotates an API key (creates a new key with same settings)
func (*Service) SetEnvironmentRepository ¶ added in v0.0.5
func (s *Service) SetEnvironmentRepository(envRepo EnvironmentRepository)
SetEnvironmentRepository sets the environment repository for prefix generation This is set after service initialization to avoid circular dependencies
func (*Service) SetRoleRepository ¶
func (s *Service) SetRoleRepository(roleRepo RoleRepository)
SetRoleRepository sets the role repository (for RBAC integration) This is set after service initialization to avoid circular dependencies
func (*Service) UnassignRole ¶
func (s *Service) UnassignRole(ctx context.Context, apiKeyID, roleID xid.ID, orgID *xid.ID, actorID *xid.ID) error
UnassignRole removes a role from an API key
func (*Service) UpdateAPIKey ¶
func (s *Service) UpdateAPIKey(ctx context.Context, appID, id, userID xid.ID, orgID *xid.ID, req *UpdateAPIKeyRequest) (*APIKey, error)
UpdateAPIKey updates an API key
func (*Service) VerifyAPIKey ¶
func (s *Service) VerifyAPIKey(ctx context.Context, req *VerifyAPIKeyRequest) (*VerifyAPIKeyResponse, error)
VerifyAPIKey verifies an API key and returns the associated key info
type UpdateAPIKeyRequest ¶
type UpdateAPIKeyRequest = base.UpdateAPIKeyRequest
UpdateAPIKeyRequest represents a request to update an API key
type VerifyAPIKeyRequest ¶
type VerifyAPIKeyRequest = base.VerifyAPIKeyRequest
VerifyAPIKeyRequest represents a request to verify an API key
type VerifyAPIKeyResponse ¶
type VerifyAPIKeyResponse = base.VerifyAPIKeyResponse
VerifyAPIKeyResponse represents a response from API key verification