One binary. Every surface an auth server needs.
Signet is the better-auth wire protocol, certified — hosted by us, or on your own metal under an enterprise licence. The certified API, the operator dashboard, the docs, and the compatibility receipt all travel inside one Rust binary — nothing phones home.
[server]
listen = "0.0.0.0:3000"
base_url = "https://auth.example.com"
[database]
adapter = "postgres" # or SIGNET_DATABASE_URL
# users, sessions + secrets live in YOUR PostgresSchedule of surfaces
What one Signet instance serves.
| Route | What it is |
|---|---|
| /api/auth/* | The certified better-auth wire — sign-up, sign-in, session, OAuth, OIDC. Differential conformance 280 / 280 with gap 0; separately, end-to-end acceptance 14 / 14. |
| / | Front door — the certification receipt rendered as the hero, plus a what/why/three-step-integrate landing. |
| /admin | Operator dashboard (admin-key gated) — users, session revoke and ban, events and audit export, dead-letter replay. Zero-JS, server-rendered, CSRF-protected. |
| /docs | Embedded quickstart plus the generated config reference and lifecycle-ops docs (upgrade, backup, restore, export). Zero external fetch — it travels inside the binary. |
| /certification | The compatibility receipt (HTML and JSON, rendered from one source so they cannot drift): conformance 280 / 280, end-to-end acceptance 14 / 14, gap 0, build identity, and an honest operating-envelope and support posture. |
| /llms.txt | Machine on-ramp for AI agents — enumerates this instance's real certified endpoints and the compatibility profile. |
The docs are not a separate site — every deployed instance serves its own /docs and /llms.txt from inside the binary, so they can never drift from the build you are running.
The certified wire
Every auth surface, accounted for.
The API reference, distilled to product proof. Every row traces to the repo README.md or to the embedded /docs a running instance serves — if it is not in those, it is not on this page.
| Surface | Wire tokens | What you get |
|---|---|---|
| Sign-up | sign-up auto_sign_in | Account creation on the certified wire. Flip auto_sign_in and a new user is signed in immediately after sign-up, rather than requiring a separate sign-in. |
| Sign-in | sign-in/email | Email sign-in — the path the embedded docs themselves use as the per-path rate-limit example, so the door you most want to throttle is the easiest one to single out. |
| Sessions | session expires_in fresh_age | Lifetime defaults to seven days (expires_in) and refreshes on use (update_age); a configurable fresh_age window gates sensitive actions. |
| OAuth + OIDC | social_providers pkce | Social sign-in on the same certified wire — google and github carry built-in defaults, custom providers declare their endpoints, PKCE available. An optional oauth_proxy plugin ships. |
| Password policy | password | 8–128 characters by default; scrypt cost with a tunable parallelism factor. |
| Breached-password check | haveibeenpwned | Optional Have I Been Pwned range check — point the range endpoint at a self-hosted mirror and even this check stays inside your walls. |
| Verification + reset delivery | delivery dead_letter | Verification codes and reset links leave by signed-JSON webhook (HMAC-SHA256, sent as x-signet-signature) or SMTP — or not at all. Failed sends can dead-letter for replay from the admin surface. |
| Rate limiting | rate_limit | Built-in and on by default — 100 requests per 10-second window out of the box, with per-path override rules. |
| Liveness + machine schema | /health open-api/generate-schema | Confirm liveness at /health; browse the wire's machine schema at /api/auth/open-api/generate-schema. |
Sources: README.md (the surfaces table, the quickstart) and the embedded /docs — read a live instance's copy, served from inside the binary.
The drop-in
Point a better-auth client at it.
Write signet.toml with this instance's public origin and a PostgreSQL adapter, provide the secret out-of-band, and boot — migrations run on start. Then point any existing better-auth client at /api/auth on this origin.
import { createAuthClient } from "better-auth/client";
// Your existing better-auth client — point baseURL
// at your Signet instance. The wire is the contract.
export const authClient = createAuthClient({
baseURL: "https://auth.example.com/api/auth",
});
// The same calls you already write — they just work.
await authClient.signIn.email({ email, password });- Write
signet.tomlwith the public origin and a PostgreSQL DSN. - Provide the secret and database URL out-of-band, then boot — migrations run on start.
- Point your better-auth client at
/api/auth. The wire is the contract — it reads the same hosted or on-prem.
Working in a framework? The quickstart has a copy-paste path for Next.js, React, React Router v7, Node/Express, and plain JavaScript.
The escape hatch
Own it — your users, your data, your metal.
Every user, session, and secret lives in your own PostgreSQL, behind an /admin operator surface you control. Signet is the same binary whether we run it or you do: start on a managed instance and, the day you need to, take it onto your own hardware under an enterprise licence — without changing a line of client code. The wire does not change.
And the exit is not a favour we grant. You can leave with your data at any time, with no cooperation from Signet or its authors required — pg_dump, pg_restore, boot. An enterprise licence puts the binary itself in your hands, so if we disappeared tomorrow your auth keeps running, and the wire never changes.
Ownership runs to the configuration too: every setting lives in signet.toml in your own repository, not a hosted console. Configuration is the dashboard →
The receipt
What the receipt records — and what it does not.
The differential conformance sweep is 280 / 280: better-auth’s own suite is run once against the reference implementation and once against Signet, then the results are diffed. The denominator is set by the reference implementation — it counts the tests the reference passes. Signet matches every one of those tests, so the compatibility gap — the count where the reference passes and Signet does not — is 0.
Separately, end-to-end acceptance is 14 / 14: better-auth’s unmodified client drives real sign-up, session, organization, and two-factor flows. Both runs were recorded 2026-07-25. The receipt is a recorded pointer to those runs, not an implied cryptographic attestation — and every instance serves its own copy so you can verify it yourself.
| Property | Value |
|---|---|
| Compatibility profile | better-auth 1.6.23 |
| Profile version | Signet compatibility profile v1 |
| Differential conformance | 280 / 280 |
| Compatibility gap | 0 |
| End-to-end acceptance | 14 / 14 |
| Recorded | 2026-07-25 |
| Operating envelope | Not published. The max users, sustained request rate, and resource footprint under load have not been measured, so no capacity number is claimed. A measured envelope will be added once recorded. |
Provisioning a new instance is one operator action that ends in a receipt — a live /health check plus an end-to-end sign-up, sign-in, and get-session smoke against the live URL. Proven from zero on 2026-07-21: health 200, smoke 3/3.
Run the real engine.
Early access is the real certified binary, not a trial. Get on the list and we will stand up your instance.