Documentation
¶
Overview ¶
Package apikey provides machine authentication (roadmap S1): issuable, scoped, rotatable, revocable, expirable API keys / service principals so non-human callers authenticate without a user token. Only the sha256 of a key's secret is stored; the public prefix is the lookup handle. A verified key becomes an ActorSystem whose Scopes authorize it through the authz evaluator's machine fast-path (a scope acts like an RBAC grant, still subject to ABAC deny).
Index ¶
- type Authenticator
- type KeyInfo
- type Principal
- type Store
- func (s *Store) Issue(ctx context.Context, db database.TenantDB, name string, scopes []string, ...) (token string, id uuid.UUID, err error)
- func (s *Store) List(ctx context.Context, db database.TenantDB) ([]KeyInfo, error)
- func (s *Store) Revoke(ctx context.Context, db database.TenantDB, id uuid.UUID) error
- func (s *Store) Rotate(ctx context.Context, db database.TenantDB, oldID uuid.UUID) (token string, newID uuid.UUID, err error)
- func (s *Store) Verify(ctx context.Context, plat database.TxManager, token string) (Principal, error)
- type StoreOption
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Authenticator ¶
type Authenticator struct {
// contains filtered or unexported fields
}
Authenticator verifies a Bearer API key and maps it to an ActorSystem. Wire it (or a composite that also tries OIDC) into httpx.SecureHandler.
func NewAuthenticator ¶
func NewAuthenticator(store *Store, plat database.TxManager) *Authenticator
NewAuthenticator builds the authenticator over the platform TxManager used for cross-tenant key verification.
func (*Authenticator) Authenticate ¶
Authenticate reads the Bearer token; if it is an API key (wowapi_ prefix) it verifies it and returns the machine actor, else KindUnauthenticated so a composite authenticator can try another scheme.
type KeyInfo ¶
type KeyInfo struct {
ID uuid.UUID
Name string
Prefix string
Scopes []string
ExpiresAt *time.Time
RevokedAt *time.Time
LastUsed *time.Time
}
KeyInfo is a non-secret view of a key for listing.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store issues, verifies, rotates, and revokes API keys.
func NewStore ¶
func NewStore(idgen model.IDGen, opts ...StoreOption) *Store
NewStore builds a Store.
func (*Store) Issue ¶
func (s *Store) Issue(ctx context.Context, db database.TenantDB, name string, scopes []string, expiresAt *time.Time) (token string, id uuid.UUID, err error)
Issue mints a key for the current tenant with the given scopes and optional expiry, records only the secret's hash, and returns the plaintext token ONCE — it cannot be recovered later. Runs in the caller's tenant transaction.
func (*Store) Revoke ¶
Revoke marks a key revoked (tenant-scoped). Idempotent; KindNotFound if the id is not an active key of this tenant.
func (*Store) Rotate ¶
func (s *Store) Rotate(ctx context.Context, db database.TenantDB, oldID uuid.UUID) (token string, newID uuid.UUID, err error)
Rotate mints a NEW secret for the same logical principal — a new key row inheriting the old key's name, scopes, and expiry — and returns the new token ONCE. It is the safe two-call rotation: the old key stays valid so callers can cut over with zero downtime, then Revoke(oldID) once migrated. Runs in the caller's tenant transaction; audited as apikey.rotate. KindNotFound if oldID is not an active key of this tenant.
func (*Store) Verify ¶
func (s *Store) Verify(ctx context.Context, plat database.TxManager, token string) (Principal, error)
Verify authenticates a token cross-tenant (as app_platform, since the tenant is unknown pre-auth): it parses the prefix, loads the key, constant-time compares the secret hash, checks revocation/expiry, bumps last_used_at, and returns the Principal. Every failure is a KindUnauthenticated error with a non-specific message (no oracle for which check failed).
type StoreOption ¶
type StoreOption func(*Store)
StoreOption customizes a Store.
func WithAudit ¶
func WithAudit(w *kaudit.Writer) StoreOption
WithAudit records an audit_logs entry (in the caller's tenant tx) for every key issuance, rotation, and revocation (roadmap S1/CA-3).