94e5b9e355
KSF values are stored per user, if admin change value, client will detect it and regenerate the envelop This pervent users being stuck
81 lines
4.5 KiB
SQL
81 lines
4.5 KiB
SQL
-- ════════════════════════════════════════════════════════════════════════════
|
|
-- Per-envelope OPAQUE KSF parameters
|
|
-- ════════════════════════════════════════════════════════════════════════════
|
|
-- Client-side Argon2id key-stretching parameters (memory / iterations / lanes)
|
|
-- used at OPAQUE register time, stored per-envelope. Complements the three
|
|
-- existing OPAQUE columns (envelope, ciphersuite_version, registered_at)
|
|
-- introduced by 20261001000002_auth_opaque.sql.
|
|
--
|
|
-- ## Why per-envelope
|
|
--
|
|
-- OPAQUE's KSF runs entirely client-side. The server publishes the CURRENT
|
|
-- default via GET /api/auth/opaque/params, and the client feeds those values
|
|
-- into `argon2::Argon2` before the OPRF blinding step. The resulting
|
|
-- stretched password becomes part of the input the AKE integrity-checks
|
|
-- against the envelope. **If the client ever uses a different KSF than the
|
|
-- one that was used at register time, the AKE fails and the server returns
|
|
-- InvalidCredentials.**
|
|
--
|
|
-- Consequence: without per-envelope storage, changing
|
|
-- OXICLOUD_AUTH_OPAQUE_KSF_* invalidates every existing envelope. Users hit
|
|
-- a mass "invalid credentials" lockout and the only recovery is
|
|
-- `oxicloud-cli opaque reset` to force re-registration.
|
|
--
|
|
-- With per-envelope storage: `/api/auth/opaque/login/lookup` returns the
|
|
-- envelope's own KSF params alongside hasOpaque=true. The client uses those
|
|
-- for the login handshake (matching what was used at register), and NEW
|
|
-- registrations pick up the current server defaults. Config changes stop
|
|
-- being a lockout vector.
|
|
--
|
|
-- ## Migration handling for existing envelopes
|
|
--
|
|
-- Columns are nullable — existing envelopes minted before this migration
|
|
-- carry NULL and the client falls back to the server's published /params
|
|
-- values for the login handshake. That preserves the pre-migration
|
|
-- behaviour (works as long as the server's current config matches what
|
|
-- was in effect at register time). After a user re-registers (silent
|
|
-- migration on next password change, or explicit CLI reset + re-login),
|
|
-- the columns get populated with the client's declared values and future
|
|
-- config changes stop affecting that envelope.
|
|
--
|
|
-- We DO NOT backfill with a hardcoded historical default here — different
|
|
-- OxiCloud deployments have carried different defaults over the branch's
|
|
-- life, and picking one would be wrong for the others. NULL + fallback to
|
|
-- current /params is the safest posture.
|
|
--
|
|
-- ## Columns
|
|
--
|
|
-- opaque_ksf_memory_kib INTEGER — client-side Argon2id memory cost
|
|
-- in KiB, as CLIENT-DECLARED at
|
|
-- register/finish time.
|
|
-- opaque_ksf_iterations INTEGER — client-side iteration count.
|
|
-- opaque_ksf_parallelism INTEGER — client-side parallelism lanes.
|
|
--
|
|
-- All three move as one atomic set (populated together at register_finish,
|
|
-- nulled together at clear_registration). Sibling to `opaque_ciphersuite_version`
|
|
-- but distinct: ciphersuite version is a schema/algorithm identifier
|
|
-- (Ristretto255-SHA512-3DH-Argon2id v1); KSF params tune the Argon2id
|
|
-- cost within that ciphersuite.
|
|
|
|
ALTER TABLE auth.users
|
|
ADD COLUMN opaque_ksf_memory_kib INTEGER,
|
|
ADD COLUMN opaque_ksf_iterations INTEGER,
|
|
ADD COLUMN opaque_ksf_parallelism INTEGER;
|
|
|
|
COMMENT ON COLUMN auth.users.opaque_ksf_memory_kib IS
|
|
'Argon2id memory cost (KiB) the CLIENT used at OPAQUE register time.
|
|
Baked in per-envelope so future changes to OXICLOUD_AUTH_OPAQUE_KSF_*
|
|
do not invalidate existing envelopes — the /login/lookup endpoint
|
|
returns this value alongside hasOpaque=true, and the client uses it
|
|
on the login handshake. NULL for envelopes minted before per-envelope
|
|
storage landed; those envelopes still work as long as the server''s
|
|
current /params matches what they were registered under.';
|
|
|
|
COMMENT ON COLUMN auth.users.opaque_ksf_iterations IS
|
|
'Argon2id iteration count the CLIENT used at OPAQUE register time.
|
|
See opaque_ksf_memory_kib for the per-envelope-storage rationale.';
|
|
|
|
COMMENT ON COLUMN auth.users.opaque_ksf_parallelism IS
|
|
'Argon2id parallelism (lanes) the CLIENT used at OPAQUE register time.
|
|
See opaque_ksf_memory_kib for the per-envelope-storage rationale.';
|