feat(dpop): add documentation
This commit is contained in:
@@ -62,6 +62,14 @@ OPAQUE (RFC 9807) is a zero-knowledge password-authenticated key exchange: the p
|
||||
| `OXICLOUD_AUTH_OPAQUE_KSF_ITERATIONS` | `1` | Client-side Argon2id iteration count (OWASP interactive-auth recommendation). |
|
||||
| `OXICLOUD_AUTH_OPAQUE_KSF_PARALLELISM` | `1` | Client-side Argon2id parallelism lanes (OWASP recommendation). Higher only helps on multi-core hardware and can hurt single-core / older mobile devices. |
|
||||
|
||||
### DPoP — session cookie binding (RFC 9449)
|
||||
|
||||
DPoP cryptographically binds a session cookie to a browser-held ECDSA keypair (P-256, non-extractable via `SubtleCrypto`). Every request carries a signed proof the middleware verifies against the session's binding. Closes the info-stealer replay threat: a cookie copied to another machine is useless without the private key. Non-browser clients (Nextcloud sync via app passwords, CLI via device-authorization) never bind and are exempted at the middleware regardless of mode. See `docs/plan/dpop.md` for the full rollout plan.
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `OXICLOUD_DPOP_MODE` | `off` | Enforcement mode. `off` = middleware pass-through (default, ship-safe). `opportunistic` = verify when a proof is present, log `dpop.header_missing_but_session_bound` audit when absent on a bound session, but allow the request through (rollout mode — catches client bugs). `required` = bound sessions MUST present a valid proof or 401. Unbound sessions always exempt. Recommended rollout: `off` → `opportunistic` for 2-4 weeks → `required`. For DPoP to be meaningful, cookies must be `Secure` (`OXICLOUD_COOKIE_SECURE=true` in production over HTTPS) and reverse-proxy `X-Forwarded-Proto` / `X-Forwarded-Host` must reach the app so the `htu` claim canonicalises correctly. |
|
||||
|
||||
### Rate Limiting & Account Lockout
|
||||
|
||||
| Variable | Default | Description |
|
||||
|
||||
+40
@@ -250,6 +250,46 @@ DATABASE_URL=postgres://postgres:postgres@localhost:5432/oxicloud
|
||||
# helps on multi-core devices and hurts single-core / older mobile)
|
||||
#OXICLOUD_AUTH_OPAQUE_KSF_PARALLELISM=1
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# DPOP — session cookie binding to a browser-held keypair (RFC 9449)
|
||||
# -----------------------------------------------------------------------------
|
||||
# Each SPA session generates a P-256 ECDSA keypair with `extractable: false`
|
||||
# in the browser at login time; the JWK thumbprint is sent as `dpop_jkt`
|
||||
# and stored on the session row. Every subsequent request carries a signed
|
||||
# DPoP proof header the middleware verifies against the session's binding.
|
||||
#
|
||||
# Threat closed: an info-stealer that copies the cookie to another machine
|
||||
# cannot replay the session — the private key never leaves the browser
|
||||
# (SubtleCrypto stores it in the crypto subsystem; JS can only call
|
||||
# `sign()` on the handle, never `exportKey()`).
|
||||
#
|
||||
# Non-browser clients (Nextcloud sync, mobile apps via Basic Auth on app
|
||||
# passwords, CLI via device-authorization) never bind a keypair — their
|
||||
# session rows have `dpop_jkt IS NULL` and the middleware exempts them
|
||||
# regardless of mode. So enabling this does NOT break your NC clients.
|
||||
#
|
||||
# Values: off | opportunistic | required
|
||||
# off — middleware pass-through, no verification. Default. Ship-
|
||||
# safe while the client rollout catches up.
|
||||
# opportunistic — verify when a proof is present, reject invalid ones;
|
||||
# allow when absent (log a warning if the session was
|
||||
# bound). Rollout mode — catches client bugs before
|
||||
# flipping enforcement.
|
||||
# required — bound sessions MUST present a valid proof or 401.
|
||||
# Unbound sessions still work (see NC-client note above).
|
||||
#
|
||||
# Recommended rollout: off → opportunistic (2-4 weeks, watch audit for
|
||||
# `dpop.header_missing_but_session_bound` counts trending to zero) →
|
||||
# required. See `docs/plan/dpop.md` for the full rollout plan.
|
||||
#
|
||||
# NB: for DPoP to be meaningful, cookies must be `Secure` (HTTPS) —
|
||||
# there's no point cryptographically binding a session that ships over
|
||||
# plain HTTP. Set `OXICLOUD_COOKIE_SECURE=true` in production. Also
|
||||
# ensure `X-Forwarded-Proto` + `X-Forwarded-Host` reach the app if
|
||||
# you're behind a reverse proxy — the middleware reads those to build
|
||||
# the canonical `htu` claim the proof binds to.
|
||||
#OXICLOUD_DPOP_MODE=off
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# RATE LIMITING & ACCOUNT LOCKOUT
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user