Core concepts

Security

The point of ZKAuth is that a server compromise can’t hand an attacker your users’ passwords, because the server never had them. Here’s how that holds up, and where the boundaries are.

Cryptography

Password authentication is built on zero-knowledge proofs rather than stored password hashes:

  • Groth16 zk-SNARKs over the BN128 curve verify knowledge of the password-derived secret.
  • Poseidon hashing inside the circuit, with Argon2id for key-stretching at the edges.
  • The engine stores a verifier value, not the password, and not a reversible hash of it.
Where the verifier lives. The Groth16 verifier runs in the ZKAuth engine, not in this dashboard. The dashboard issues keys, proxies browser flows, and records usage.

Replay & tamper protection

  • Proof freshness: each proof is single-use. Replays are rejected on the hot path (backed by a Redis freshness record).
  • Tamper rejection: a modified proof fails verification outright.
  • Device binding: deviceInfo ties an attempt to a device fingerprint; mismatches can be challenged.

Tenant isolation & keys

  • Keys are tenant-bound: a zka_live_ or zka_test_ key only acts on its own project.
  • Bearer-only requests (no API key) and invalid keys are rejected.
  • Rate limits apply per client to blunt automated abuse.
  • API-key audit entries and security events give you a trail to inspect.

Validate a key any time:

bash
curl https://api.zkauth.dev/api/v1/client/me \  -H "x-api-key: zka_live_your_api_key"

Callbacks & hosted fallback pages

  • Email verification, new-device approval/denial, and password reset links are handled by ZKAuth first.
  • Redirects only continue to an exact project allowlist match. Unknown or unsafe redirects fall back to hosted ZKAuth result pages.
  • Developers should handle zkauth_action, success, error, and token parameters on their own callback page.

Webhook safety

  • Webhook secrets must stay server-side and should be rotated after exposure.
  • Consumers should verify signatures over the raw request body and reject stale timestamps to prevent replay.
  • Handlers should be idempotent because retries can deliver the same event more than once.
  • ZKAuth records delivery attempts so developers can inspect response status, success, and retry behavior.

Operational best practices

  • Keep keys server-side. Never ship a key in a client bundle; proxy browser flows through your backend.
  • Use HTTPS everywhere. The API enforces it; your app should too.
  • Separate environments. Test keys for dev/CI, live keys for production, rotated independently.
  • Store sessions in http-only cookies, not local storage.
  • Do not log secrets. This includes API keys, session JWTs, verification tokens, reset tokens, device approval tokens, webhook secrets, database URLs, and provider keys.

Account security controls

Beyond the login itself, the engine exposes per-user controls you can build into your account UI:

  • TOTP MFA: setup, verify, and status, with one-time recovery codes.
  • Session management: list active sessions and revoke them individually or all-but-current.
  • Emergency reset: account recovery gated by a 72-hour delay, so a stolen inbox can’t instantly take over an account.
  • Security events & alerts: a stream you can surface to users or operators.

Transparency & evidence

Security writing is easy to fake, so the engine lets you check rather than trust. These read-only endpoints report how it is actually configured:

  • /security/crypto-policy: the live cryptographic parameters (curve, hash, Argon2id settings).
  • /security/standards: standards mappings, published without claiming certification.
  • /security/pq-readiness: an honest post-quantum readiness posture.
  • /security/evidence and /security/assurance/policy: assurance records for operator and auditor review.
Why this exists. We would rather hand you the evidence than ask for trust. If a claim here ever drifts from what these endpoints report, treat the endpoints as the source of truth.

Troubleshooting

SymptomLikely cause
401 / invalid keyWrong or missing x-api-key, or a test key used against live data. Validate with GET /api/v1/client/me.
Login rejected for a valid passwordA replayed or stale proof, or a device-fingerprint mismatch. Retry a fresh login; the client generates a new proof.
Passkey ceremony failsWEBAUTHN_RP_ID / WEBAUTHN_ORIGIN don’t match the serving domain. See Deployment.
Slower hosted callsServerless cold starts, proxy work, and remote database latency. Budget user-facing timeouts accordingly.

What we don’t claim

Security writing should be precise, so here is the honest boundary. As of today, ZKAuth does not claim:

  • SOC 2, HIPAA, or any completed external audit or certification.
  • Post-quantum security.
  • Broad authenticator compatibility guarantees for WebAuthn.

Usage is tracked, but billing is not yet enforced. We’ll update this page when any of that changes, not before.

Early access. ZKAuth and zkauth-client are in active development. Pin a client version and review release notes before upgrading.