Documentation
¶
Index ¶
- Constants
- Variables
- func CheckScope(scopeJSON []byte, jobAlias string) bool
- func DecodeScope(scopeJSON []byte) (*models.KeyScope, error)
- func GenerateKey() (plaintext, prefix string, err error)
- func HasRole(keyRole, required models.Role) bool
- func HashKey(plaintext, secret string) (string, error)
- func IsScoped(scopeJSON []byte) (bool, error)
- func RequiredRole(method, path string) (models.Role, bool)
- func ScopeJobs(scopeJSON []byte) ([]string, error)
- type AuditEntry
- type AuditLogger
- type AuditQueryRequest
- type CreateKeyRequest
- type CreateKeyResponse
- type RateLimiter
- type Service
- func (s *Service) AdminKeyExists() (bool, error)
- func (s *Service) Bootstrap() (string, error)
- func (s *Service) CreateKey(req *CreateKeyRequest) (*CreateKeyResponse, error)
- func (s *Service) JobAliasByBackfillID(ctx context.Context, id uuid.UUID) (string, error)
- func (s *Service) JobAliasByID(ctx context.Context, id uuid.UUID) (string, error)
- func (s *Service) JobAliasByRunID(ctx context.Context, id uuid.UUID) (string, error)
- func (s *Service) ListKeys() ([]models.APIKey, error)
- func (s *Service) RevokeKey(id uuid.UUID) error
- func (s *Service) RotateKey(id uuid.UUID, gracePeriod time.Duration, actor string) (*CreateKeyResponse, error)
- func (s *Service) StartLastUsedFlusher(ctx context.Context)
- func (s *Service) ValidateKey(plaintext string) (_ *models.APIKey, retErr error)
- type ServiceOption
Constants ¶
const ( OutcomeSuccess = "success" OutcomeDenied = "denied" OutcomeError = "error" )
AuditOutcome enumerates the possible outcomes for an audit log entry.
const ( ActionAuthAttempt = "auth.attempt" ActionAuthDenied = "auth.denied" ActionKeyCreate = "api_key.create" ActionKeyRevoke = "api_key.revoke" ActionKeyRotate = "api_key.rotate" ActionJobCreate = "job.create" ActionJobDelete = "job.delete" ActionJobPause = "job.pause" ActionJobUnpause = "job.unpause" ActionRunTrigger = "run.trigger" ActionRunRetry = "run.retry" ActionBackfill = "run.backfill" ActionJobdefApply = "jobdef.apply" ActionCachePrune = "cache.prune" ActionCacheDelete = "cache.delete" ActionLogLevel = "log.set_level" ActionDBQuery = "database.query" ActionWebhookDenied = "webhook.denied" )
AuditAction enumerates well-known auditable actions.
const ( // KeyHashSchemeSHA256 is the unkeyed hash format (used when no secret is configured). KeyHashSchemeSHA256 = "sha256" // KeyHashSchemeHMACSHA256 is the keyed production hash format. KeyHashSchemeHMACSHA256 = "hmac-sha256" )
const (
// KeyPrefixLive is the scannable prefix for production API keys.
KeyPrefixLive = "csk_live_"
)
Variables ¶
Functions ¶
func CheckScope ¶
CheckScope validates whether the key is allowed to act on the given job alias. A nil/empty scope means unrestricted access.
func DecodeScope ¶
DecodeScope normalizes the persisted scope payload into a structured model. Nil, empty, or empty-job scopes are treated as unrestricted.
func GenerateKey ¶
GenerateKey produces a new API key and its display prefix. Returns (plaintext_key, key_prefix, error). The plaintext key must be shown exactly once at creation time.
func HashKey ¶
HashKey returns the stored API-key hash string: HMAC-SHA256 when a secret is configured, plain SHA-256 otherwise.
func RequiredRole ¶
RequiredRole returns the minimum role needed for a given HTTP method + path.
Types ¶
type AuditEntry ¶
type AuditEntry struct {
Actor string
Action string
ResourceType string
ResourceID string
SourceIP string
Outcome string
Metadata map[string]interface{}
}
AuditEntry holds the fields for a single audit log write.
type AuditLogger ¶
type AuditLogger struct {
// contains filtered or unexported fields
}
AuditLogger writes structured audit log entries to the database.
func NewAuditLogger ¶
func NewAuditLogger(db *gorm.DB) *AuditLogger
NewAuditLogger creates a new audit logger.
func (*AuditLogger) Log ¶
func (a *AuditLogger) Log(entry AuditEntry) error
Log writes an audit entry to the database.
func (*AuditLogger) Query ¶
func (a *AuditLogger) Query(req *AuditQueryRequest) ([]models.AuditLog, error)
Query returns audit log entries matching the given filters.
type AuditQueryRequest ¶
type AuditQueryRequest struct {
Since *time.Time
Until *time.Time
Actor string
Action string
Limit int
Offset int
}
AuditQueryRequest holds filters for querying the audit log.
type CreateKeyRequest ¶
type CreateKeyRequest struct {
Description string
Role models.Role
Scope *models.KeyScope
CreatedBy string
ExpiresAt *time.Time
}
CreateKeyRequest holds the parameters for creating a new API key.
type CreateKeyResponse ¶
CreateKeyResponse is returned on key creation — the only time the plaintext is available.
type RateLimiter ¶
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter tracks failed authentication attempts per source IP using a sliding window counter.
func NewRateLimiter ¶
func NewRateLimiter(limit int, interval time.Duration) *RateLimiter
NewRateLimiter creates a rate limiter that allows `limit` failures per `interval` per source IP.
func (*RateLimiter) Cleanup ¶
func (r *RateLimiter) Cleanup()
Cleanup removes expired windows. Call periodically to prevent memory growth.
func (*RateLimiter) IsLimited ¶
func (r *RateLimiter) IsLimited(ip string) bool
IsLimited returns true if the IP has exceeded the failure threshold.
func (*RateLimiter) RecordFailure ¶
func (r *RateLimiter) RecordFailure(ip string) bool
RecordFailure increments the failure count for the given IP. Returns true if the IP is now rate-limited.
func (*RateLimiter) RetryAfter ¶
func (r *RateLimiter) RetryAfter(ip string) int
RetryAfter returns the number of seconds until the rate limit window resets for the given IP. Returns 0 if not limited.
func (*RateLimiter) StartCleanup ¶
func (r *RateLimiter) StartCleanup(done <-chan struct{})
StartCleanup runs a periodic cleanup goroutine.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service provides API key management and validation.
func NewService ¶
func NewService(db *gorm.DB, opts ...ServiceOption) *Service
NewService creates a new auth service backed by the given database.
func (*Service) AdminKeyExists ¶
AdminKeyExists returns true if at least one non-revoked, non-expired admin key exists.
func (*Service) Bootstrap ¶
Bootstrap generates the initial admin key on first startup with auth enabled. Returns the plaintext key (to be printed to stdout once) or empty string if an admin key already exists.
func (*Service) CreateKey ¶
func (s *Service) CreateKey(req *CreateKeyRequest) (*CreateKeyResponse, error)
CreateKey generates a new API key and persists its hash.
func (*Service) JobAliasByBackfillID ¶
JobAliasByBackfillID resolves the job alias for a backfill identifier.
func (*Service) JobAliasByID ¶
JobAliasByID resolves the job alias for a job identifier.
func (*Service) JobAliasByRunID ¶
JobAliasByRunID resolves the job alias for a job run identifier.
func (*Service) ListKeys ¶
ListKeys returns all API keys (without hashes, which are excluded by the model JSON tag).
func (*Service) RotateKey ¶
func (s *Service) RotateKey(id uuid.UUID, gracePeriod time.Duration, actor string) (*CreateKeyResponse, error)
RotateKey creates a new key and sets expires_at on the old key to allow a grace period.
func (*Service) StartLastUsedFlusher ¶
StartLastUsedFlusher runs a background goroutine that periodically flushes buffered last_used_at timestamps to the database. This keeps the hot auth path free of writes.
type ServiceOption ¶
type ServiceOption func(*Service)
ServiceOption customizes auth service behavior.
func WithKeyHashSecret ¶
func WithKeyHashSecret(secret string) ServiceOption
WithKeyHashSecret configures the server-side secret used for HMAC-SHA256 key hashes.
func WithNow ¶
func WithNow(now func() time.Time) ServiceOption
WithNow overrides the service clock. Intended for tests.
func WithSleep ¶
func WithSleep(sleep func(time.Duration)) ServiceOption
WithSleep overrides the service sleep function. Intended for tests.
func WithValidationFailureMinLatency ¶
func WithValidationFailureMinLatency(d time.Duration) ServiceOption
WithValidationFailureMinLatency configures the minimum latency for auth failures.