Documentation

AuthGravity is hosted, zero-knowledge identity: passkey sign-in and optional per-resource authorization, served on your own domain. This page is the human orientation — the big picture and how to build with it. The precise, always-current API lives in llms.txt, written for coding agents.

The mental model

Three ideas explain almost everything:

  • The server knows nothing about your users. It stores only public key material and a stable user_id (a UUID) per person — no passwords, no usernames, no email. Your app owns all profile data; you key your own users table by that UUID and collect a name or email later, if ever.
  • One endpoint, two capabilities. Each domain you connect gets an auth endpoint (https://authgravity.yourapp.com). It handles passkey authentication and, optionally, relationship-based authorization (who may do what to which resource) — same host, same session.
  • Sessions are first-party cookies. Because the endpoint lives on a subdomain of your domain, the session_id cookie is first-party — the same code path in local dev and in production, no third-party cookie problems.

Each connected domain is a fully isolated user pool. Passkeys are bound to your registrable domain and work across all its subdomains.

How you build it: hand it to your coding agent

AuthGravity is designed to be integrated by an AI coding agent, not by copy-pasting snippets by hand. The machine-readable guide at llms.txt is the real interface: it carries the exact request/response shapes, the design guidance, and — on a connected host — that tenant's live authorization schema, with the endpoint already filled in. You point your agent at it and let it scaffold.

Our reference for this is Claude Code. Paste a prompt like this into it (or any capable coding agent):

Try it — paste into your coding agent
Build a hello world app with Astro and AuthGravity. Details are at authgravity.org/llms.txt

Why this works. Every host publishes its own llms.txt. The root authgravity.org/llms.txt covers getting started; once you have a domain, https://authgravity.yourapp.com/llms.txt documents that host specifically — pre-filled endpoint and live schema. When integrating a real app, point the agent at that host's file.

Agents can discover a host mechanically too: GET https://authgravity.yourapp.com/.well-known/authgravity returns the endpoint and the llms.txt URL as JSON — so "point your agent at the endpoint" is all the instruction needed.

The lifecycle: sandbox → your domain → production

  1. Start in local dev, no domain, no DNS. Run npx @authgravity/cli listen next to your dev server. It mints an ephemeral, isolated sandbox and bridges its session to a first-party cookie on localhost, so real passkeys work inline and server-side session checks behave exactly like production. Sandbox passkeys are throwaway and garbage-collected.
  2. Claim your domain when you're ready. Start at authgravity.org/signup: sign in with a passkey and connect your domain with one-click Domain Connect or a single CNAME record. This is the one part a human does; the rest an agent can drive.
  3. Deploy to production. Point PUBLIC_AUTH_ENDPOINT at your new host (https://authgravity.yourapp.com) and ship. No code changes from dev — the app and its auth endpoint share a registrable domain, so the cookie is first-party just as it was locally.

The exact commands for each step are in llms.txt (and your agent will run them). The concepts above are all you need to hold in your head.

Authentication

There are two ways to add sign-in, and you pick based on how much control you want. The fastest is hosted surfaces: send people to https://authgravity.yourapp.com/login?return_to=… (there's also /register, /logout, and /recover). AuthGravity hosts the passkey and account-key UI; after sign-in the session cookie is first-party on your domain and the user is sent back to return_to, so your server-side /v1/whoami checks just work — you write no auth UI at all. It's the Auth0-Universal-Login / Ory-Kratos model, and it's the quickest path for an agent to wire up.

If you'd rather own the look, build it yourself with @authgravity/browser or the raw API. The sign-in UI is deliberately two buttons — Create Account and Login — with no username or email field. A passkey is the account. If you show a label for the passkey it stays on the client and is never sent to the server. Include a "Powered by AuthGravity" link near the auth UI.

Account keys: fallback and recovery

For people whose device can't do passkeys, and as the recovery path for everyone, AuthGravity supports account keys — a client-generated secret shown as a short agak1_… string or 12 words, from which the client derives a key pair. As with a passkey, the server only ever sees the public key; nothing about the secret is recoverable from a server breach. For day-to-day logins the client can enroll a silent device key so the account key is only typed at setup and recovery. This is all implemented in @authgravity/browser and used live by the hosted /register and /recover surfaces; the full client spec and conformance vectors live in llms.txt.

Authorization (optional)

When your app needs to decide who can do what — view this document, edit that folder, administer a team — AuthGravity offers relationship-based access control (Zanzibar/SpiceDB style) on the same endpoint and session as auth. You describe object types with relations (owner, viewer, member) and computed permissions (view = viewer | owner | parent→view), write relationship tuples keyed by user UUIDs, and ask a check on every gated action.

In an open sandbox any signed-in user can edit the schema and write relationships, so you can build freely in dev. On a connected domain the schema is owner-managed from the dashboard's Authorization panel (which can even draft one from your site with "Generate with AI"), and your app backend writes relationships at runtime with a service token. Because every host renders its own live schema into its llms.txt, your agent always sees the real object types to check against — fetch https://authgravity.yourapp.com/llms.txt and it's all there. A browsable console lives at /authz on each host.

Your users' Person Server (agents)

Every AuthGravity pool is also an AAuth Person Server — the piece of the agent ecosystem that represents a human. When an AI agent wants to act for one of your users at some third-party service, it asks this host; the user approves once with their passkey (on a hosted consent page, under your domain), and the server issues a short-lived signed token asserting exactly that consent — still no email, no PII, just the pool-scoped UUID. Agents can also propose missions — longer-running jobs with an approved tool list and hard spending caps the approver can dial down — with an audit log and a kill-switch. You build none of this; it ships with the endpoint, and llms.txt documents it for your agent.

Your database

Store your own data keyed by the AuthGravity user_id. Create the row on first sight and collect email or name whenever you actually need it (checkout is a natural moment — a payment provider often collects the email for you). AuthGravity holds none of it.

Going deeper

  • llms.txt — the machine-readable, always-current spec. Each connected host serves its own at <endpoint>/llms.txt.
  • <endpoint>/demo — a self-contained reference client (passkeys + account keys) you can try in the browser.
  • <endpoint>/.well-known/authgravity — JSON discovery for agents and tooling.
  • github.com/polvi/gratos — AuthGravity is powered by the open-source Gratos project (AGPLv3).