Add owner-agnostic service tokens

Introduces ServiceKey, a parallel primitive to APIKey for server-to-server
auth where the owner is not an authkit user (e.g. an application or tenant
row the consumer manages). owner_id has no FK and no RBAC linkage; cascade
on owner-delete is the consumer's responsibility. AuthenticateServiceKey
returns *ServiceKey directly rather than *Principal since service tokens
have no user.

Also exports MintOpaqueSecret / HashOpaqueSecret / ParseOpaqueSecret so
both API-key and service-key code share one mint/parse implementation
instead of duplicating it. Deps.ServiceKeys is required (panics in New
if nil) — existing call sites must add ServiceKeys: stores.ServiceKeys.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
juancwu 2026-04-26 19:54:26 +00:00
commit 4942e4dbdc
16 changed files with 664 additions and 24 deletions

View file

@ -60,6 +60,22 @@ type APIKey struct {
RevokedAt *time.Time
}
// ServiceKey is an owner-agnostic API key for server-to-server auth. Unlike
// APIKey, OwnerID is not constrained to authkit_users — OwnerKind labels the
// owner namespace (e.g. "application", "tenant") and consumers manage their
// own cascade-on-delete.
type ServiceKey struct {
IDHash []byte
OwnerID uuid.UUID
OwnerKind string
Name string
Abilities []string
LastUsedAt *time.Time
CreatedAt time.Time
ExpiresAt *time.Time
RevokedAt *time.Time
}
type Role struct {
ID uuid.UUID
Name string