Threat model
What IdentSphere defends against, and what it explicitly does not.
In scope
Account takeover via credential stuffing
- Defense: Argon2id hashing (resists offline brute-force).
- Defense: TOTP MFA, passkeys.
- Caller's responsibility: rate-limit
/loginand/password/forgot(the SDK does NOT ship a built-in rate limiter). - Caller's responsibility: pre-validate against breach databases (HIBP) if you need that level of defense.
Account enumeration
- Defense:
/loginreturns identical errors for unknown email and wrong password. - Defense:
/password/forgotand/email-otp/requestalways return 204, regardless of email status. - Residual risk: timing attacks. Hosts deeply concerned about timing can add a randomized delay in front of these endpoints.
Session hijacking via XSS
- Defense:
HttpOnlyon the access token cookie — JS cannot read it. - Defense: short access-token TTL (default 15 min).
- Caller's responsibility: don't ship XSS bugs. The cookie is not a silver bullet against malicious script with full DOM access.
Session hijacking via CSRF
- Defense: double-submit CSRF token (
identsphere_csrfcookie + matchingX-CSRF-Tokenheader on state-changing requests). - Defense:
SameSite=Laxon session cookies.
Refresh-token theft
- Defense: tokens rotate on every
/refresh. A replayed token finds no row and fails. (Future: replay revokes the family.) - Defense: refresh-cookie path scope is
route_prefix(default/v1/auth) — the host app's other routes never see this cookie.
MFA bypass via brute force
- Defense: 5-attempts-per-mfa_token lockout.
- Defense: TOTP codes are 6 digits with ±1 30-second window — 30 candidates per minute; with 5 attempts per 5-minute token the attacker has a 5e-6 chance of guessing.
- Defense: recovery codes are single-use, 10 chars alphanumeric ≈ 56 bits of entropy.
Social-OAuth open redirect
- Defense:
redirect_toquery parameter is validated to start with/and not start with//.
State-token replay
- Defense: OAuth state tokens are stored in
session_cachewith 10-min TTL and burned on use. - Defense: MFA tokens carry a
jticlaim that's burned after use.
Password reset abuse
- Defense: reset tokens are single-use, 1-hour TTL, SHA-256 hashed in DB.
- Defense: successful reset revokes ALL active sessions for the user.
Stolen avatar / object-storage abuse
- Defense: avatar uploads are capped at 5 MiB.
- Defense: content-type whitelist (JPEG/PNG/GIF/WebP).
- Caller's responsibility: storage bucket should have proper IAM policies; the SDK doesn't enforce server-side image validation beyond content-type sniffing.
Out of scope
The SDK explicitly does NOT defend against:
Rate limiting
The SDK ships NO rate limiting. Mount your own at the edge
(tower-governor, nginx limit_req, Cloudflare, etc.).
Bot detection
No CAPTCHA, no behavioral analytics, no device fingerprinting (beyond the
trusted-browser User-Agent binding). Wire your own (hCaptcha, Turnstile,
etc.) in front of /register and /login if you need it.
Compromised email accounts
If an attacker controls the user's email inbox, they can:
- Reset the password.
- Receive email OTP codes.
- Accept invitations.
The SDK cannot defend against this — the email is the recovery factor of last resort.
Stolen identsphere_trust cookie + matching User-Agent
The trusted-browser cookie binds to the User-Agent header but not to the
underlying device. An attacker who exfiltrates the cookie AND forges a
matching UA can bypass MFA on a fresh session. The 30-day TTL bounds the
window; revoking via DELETE /v1/auth/trusted-browsers/:id
closes it immediately.
Phishing of TOTP codes
TOTP codes can be phished. The attacker collects email + password + a fresh TOTP code via a fake login page and replays them within 30 seconds. Defense: use passkeys (phishing-resistant) instead of TOTP wherever possible.
DDoS
No DDoS protection. Run IdentSphere behind a CDN that can absorb floods (Cloudflare, Fastly, etc.).
Compromised identsphere-server host
If an attacker gains code execution on the identsphere-server process, they can read every plaintext password, MFA secret, etc. that flows through. Defense in depth here is at the host / infra layer.
Threat actors NOT considered
- Nation-state actors with side-channel access to the hardware.
- Insider attackers with
DATABASE_URLaccess. - Attackers with access to the Postgres backup tapes.
These are out of scope at every reasonable software layer; encryption at rest, infra hardening, and ops practice are what address them.
Reporting issues
Email security@example.com (host-defined). Standard 90-day responsible disclosure window. PGP key on request.