-- +goose Up -- +goose StatementBegin -- OIDC / Keycloak SSO — Singleton-Settings (analog forward_proxy_settings). -- client_secret_enc: secrets.Box.Seal-Output (AES-256-GCM), NULL = nicht gesetzt. -- Rolle kommt bewusst NICHT aus dem Token, daher keine group/role-claim-Spalten. CREATE TABLE IF NOT EXISTS oidc_settings ( id INTEGER PRIMARY KEY DEFAULT 1, enabled BOOLEAN NOT NULL DEFAULT false, issuer_url TEXT NOT NULL DEFAULT '', client_id TEXT NOT NULL DEFAULT '', client_secret_enc BYTEA, scopes TEXT NOT NULL DEFAULT 'openid email profile', email_claim TEXT NOT NULL DEFAULT 'email', button_label TEXT NOT NULL DEFAULT 'Sign in with SSO', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT oidc_settings_singleton CHECK (id = 1) ); INSERT INTO oidc_settings (id) VALUES (1) ON CONFLICT DO NOTHING; -- Opportunistisches Linking: beim ersten SSO-Login wird der OIDC-'sub' -- gespeichert; weicht er später ab, wird der Login abgelehnt. Nullable, -- kein Backfill (Match-Schlüssel bleibt die verifizierte E-Mail). ALTER TABLE users ADD COLUMN IF NOT EXISTS oidc_subject TEXT; -- +goose StatementEnd -- +goose Down -- +goose StatementBegin ALTER TABLE users DROP COLUMN IF EXISTS oidc_subject; DROP TABLE IF EXISTS oidc_settings; -- +goose StatementEnd