auth

package
v0.0.0-...-bda2491 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	OutcomeSuccess = "success"
	OutcomeDenied  = "denied"
	OutcomeError   = "error"
)

AuditOutcome enumerates the possible outcomes for an audit log entry.

View Source
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.

View Source
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"
)
View Source
const (
	// KeyPrefixLive is the scannable prefix for production API keys.
	KeyPrefixLive = "csk_live_"
)

Variables

View Source
var (
	ErrKeyNotFound = errors.New("api key not found")
	ErrKeyRevoked  = errors.New("api key revoked")
	ErrKeyExpired  = errors.New("api key expired")
	ErrForbidden   = errors.New("insufficient permissions")
)

Functions

func CheckScope

func CheckScope(scopeJSON []byte, jobAlias string) bool

CheckScope validates whether the key is allowed to act on the given job alias. A nil/empty scope means unrestricted access.

func DecodeScope

func DecodeScope(scopeJSON []byte) (*models.KeyScope, error)

DecodeScope normalizes the persisted scope payload into a structured model. Nil, empty, or empty-job scopes are treated as unrestricted.

func GenerateKey

func GenerateKey() (plaintext, prefix string, err error)

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 HasRole

func HasRole(keyRole, required models.Role) bool

HasRole returns true if the key's role is at or above the required level.

func HashKey

func HashKey(plaintext, secret string) (string, error)

HashKey returns the stored API-key hash string: HMAC-SHA256 when a secret is configured, plain SHA-256 otherwise.

func IsScoped

func IsScoped(scopeJSON []byte) (bool, error)

IsScoped reports whether the scope payload restricts access to specific jobs.

func RequiredRole

func RequiredRole(method, path string) (models.Role, bool)

RequiredRole returns the minimum role needed for a given HTTP method + path.

func ScopeJobs

func ScopeJobs(scopeJSON []byte) ([]string, error)

ScopeJobs returns the normalized scoped job aliases or nil when unrestricted.

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

type CreateKeyResponse struct {
	Plaintext string         `json:"key"`
	Key       *models.APIKey `json:"api_key"`
}

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

func (s *Service) AdminKeyExists() (bool, error)

AdminKeyExists returns true if at least one non-revoked, non-expired admin key exists.

func (*Service) Bootstrap

func (s *Service) Bootstrap() (string, error)

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

func (s *Service) JobAliasByBackfillID(ctx context.Context, id uuid.UUID) (string, error)

JobAliasByBackfillID resolves the job alias for a backfill identifier.

func (*Service) JobAliasByID

func (s *Service) JobAliasByID(ctx context.Context, id uuid.UUID) (string, error)

JobAliasByID resolves the job alias for a job identifier.

func (*Service) JobAliasByRunID

func (s *Service) JobAliasByRunID(ctx context.Context, id uuid.UUID) (string, error)

JobAliasByRunID resolves the job alias for a job run identifier.

func (*Service) ListKeys

func (s *Service) ListKeys() ([]models.APIKey, error)

ListKeys returns all API keys (without hashes, which are excluded by the model JSON tag).

func (*Service) RevokeKey

func (s *Service) RevokeKey(id uuid.UUID) error

RevokeKey sets revoked_at on the specified key.

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

func (s *Service) StartLastUsedFlusher(ctx context.Context)

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.

func (*Service) ValidateKey

func (s *Service) ValidateKey(plaintext string) (_ *models.APIKey, retErr error)

ValidateKey looks up a plaintext API key, verifies it is active, and returns the key record. On success it asynchronously updates last_used_at.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL