Skip to content

Introduction

X511 is a zero-knowledge identity-verification gateway for HTTP servers. It intercepts requests to protected routes and serves an interactive verification challenge (HTTP 511 Network Authentication Required) until the user proves selected identity claims — minimum age, nationality, issuing state — using a supported zero-knowledge proof provider.

A successful verification grants the client a short-lived cookie. Subsequent requests pass straight through. The server learns only the boolean outcome (and an opaque per-user nullifier if the provider supplies one) — never the underlying passport data.

Early development — expect breaking changes

This library is new and actively developed. The API is not yet stable and may change without notice between versions, including breaking changes. Use with caution in production environments and pin your dependency to a specific version to avoid unexpected breakage.

What is HTTP 511?

RFC 6585 defines 511 Network Authentication Required as a status code for situations where the client must authenticate to gain network access — most commonly used by captive portals. X511 repurposes this semantics for identity-gating: instead of network credentials, the client must provide a zero-knowledge proof.

When an unauthenticated request hits a protected route, the server responds with:

HTTP/1.1 511 Network Authentication Required
Content-Type: text/html

The response body is an interactive HTML page that guides the user through the verification flow.

Zero-knowledge proofs

A zero-knowledge proof (ZKP) lets one party (the prover) convince another party (the verifier) that a statement is true without revealing any information beyond the truth of the statement itself.

In the context of identity gating:

  • The prover is the user's mobile app (Self or ZKPassport).
  • The verifier is the X511 backend.
  • The statement is "I am over 18" / "I hold an EU passport" / etc.

The backend learns only that the user satisfies the configured disclosures — not their date of birth, name, passport number, or any other identifying information.

Supported providers

ProviderDescription
SelfPrivacy-preserving identity verification using NFC passport reading and ZK proofs
ZKPassportPassport-based ZK identity proofs with programmable disclosure queries

Both providers follow the same broad pattern: the user scans a QR code with their mobile app, the app generates a ZK proof, and the backend verifies it without learning the underlying data. Custom providers can be added with defineProvider.

How the flow works

  1. An unverified request hits a route protected by verified().
  2. The server creates a pending session, builds per-provider payloads (Self universal link, ZKPassport domain), and returns the 511 HTML page.
  3. The user picks a provider, scans the QR or follows the deep link, and the mobile app submits a proof to the provider's verification route.
  4. The provider validates the proof and calls permit(sessionId, uniqueId?) on the session adapter.
  5. The page polls /sse over Server-Sent Events; when the access token appears it POSTs /claim and receives a Set-Cookie for x511.
  6. The user is redirected back to the originally requested resource and the cookie unlocks every subsequent request (until its TTL expires, or — in one-shot mode — until it is consumed once).

Where to go next

  • Getting started — install, configure, protect your first route.
  • Frameworks — full integration recipes for Hono, Elysia, Next.js, and AdonisJS.
  • API reference — every exported function, type, and constant.