IAM-09: api-token-service-accounts
internal/serviceaccount: Service-Accounts als eigenstaendige Identitaetsklasse (eigene Tabelle service_accounts, getrennt von internal/user — Zitadel- Vorbild). Store.IssueToken gibt den Klartext-Token NUR einmal an den Aufrufer zurueck, gespeichert wird ausschliesslich der SHA-256-Hash (Akzeptanzkriterium 1). Scopes und optionale Ablaufzeit sind Teil des Tokens selbst (Akzeptanzkriterium 2). Store.Verify prueft Widerruf/Ablauf/Scope bei JEDEM Aufruf direkt gegen die Datenbank — kein Cache dazwischen, ein widerrufenes Token wird ab dem naechsten Request sofort abgewiesen (Akzeptanzkriterium 3). Pruefungen (ausgefuehrt auf root@192.168.1.131, go build/vet/test PASS): 1. Token ausschliesslich gehasht gespeichert (Stichprobe in der Datenbank) — TestIssueToken_StoresOnlyHash: token_hash-Spalte direkt gelesen, enthaelt nachweislich nicht den Klartext, 32-Byte-SHA-256-Laenge bestaetigt. PASS. 2. Widerrufenes Token wird beim naechsten Request zuverlaessig abgewiesen — TestRevoke_TakesEffectImmediately: Verify vor Widerruf erfolgreich, sofort danach ErrTokenInvalid. PASS. 3. Scope-Verletzung wird korrekt abgewiesen — TestVerify_RejectsInsufficientScope: Token mit scope=read wird fuer scope=write abgewiesen (ErrScopeInsufficient), fuer scope=read akzeptiert. PASS. Zusaetzlich: TestVerify_RejectsExpiredToken belegt die optionale zeitliche Befristung aus Akzeptanzkriterium 2. PASS. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
3d20d86a4f
commit
95275407b1
@@ -0,0 +1,2 @@
|
||||
DROP TABLE IF EXISTS api_tokens;
|
||||
DROP TABLE IF EXISTS service_accounts;
|
||||
@@ -0,0 +1,20 @@
|
||||
-- Service-Accounts & API-Token (IAM-09, siehe core-kanban/tickets/IAM-09.md).
|
||||
-- Service-Accounts sind eine eigenstaendige Identitaetsklasse neben
|
||||
-- menschlichen Benutzern (users), nicht dieselbe Tabelle (Zitadel-Vorbild).
|
||||
CREATE TABLE service_accounts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- token_hash enthaelt NIEMALS den Klartext-Token, nur dessen SHA-256-Hash.
|
||||
CREATE TABLE api_tokens (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
service_account_id UUID NOT NULL REFERENCES service_accounts(id),
|
||||
token_hash BYTEA NOT NULL UNIQUE,
|
||||
scopes TEXT[] NOT NULL DEFAULT '{}',
|
||||
expires_at TIMESTAMPTZ,
|
||||
revoked_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
Reference in New Issue
Block a user