Docs · OpenID Connect
OpenID Connect for Holochain
hApp Auth speaks OpenID Connect and OAuth 2.1 as they are written, so the library you already use works. What is particular to the Holochain web is in the scopes, the subjects and the assurance levels.
The issuer
The issuer is https://happauth.com. Everything else is published in its discovery document, served from the edge with a long cache that is purged when keys rotate.
curl https://happauth.com/.well-known/openid-configuration
The protocol
| Area | hApp Auth | Why |
|---|---|---|
| Grant | Authorization code with PKCE S256, for every client. No implicit grant, no password grant. | OAuth 2.1; RFC 9700 |
| Authorization response | iss on every response | RFC 9207, mix-up defence |
| Codes | Single use; 10 minutes today, 60 seconds Coming | Short and spent |
| Access tokens | JWT (RFC 9068), 5 minutes, bound to one audience with resource indicators (RFC 8707) | Any resource can verify one locally |
| Refresh tokens | Opaque and rotating; reuse revokes the whole family | |
| ID token signing | RS256 always (discovery requires it); EdDSA and ES256 on request Coming | |
| Pushed requests | PAR for every client that opts in, required for confidential clients Coming | Ordinary OIDC and MCP libraries do not send PAR |
| Sender constraint | DPoP whenever the client offers it; otherwise short single-resource Bearer tokens Coming | MCP uses Bearer; DPoP is optional there |
| Logout | Revocation endpoint, short tokens, front-channel session end; back-channel only for pre-registered clients | |
| Revocation notice | When a person revokes a site, the site is told with a signed Security Event Token (RFC 8417) Coming | A site should not learn of it only when a refresh fails |
| FAPI 2.0 | Offered to confidential clients that ask; not applied to everyone | FAPI 2.0 forbids public clients and refresh rotation |
| FedCM | Not now | Chrome-only |
Clients without registration
A client is identified by a client ID metadata document: the client id is an HTTPS URL that serves the client’s metadata. There is no registration form, no approval and no secret. First-party clients are pre-registered with private_key_jwt.
- Redirect URIs sit on the client-id origin by default; localhost-only redirects are allowed and the person sees a warning line.
- The document is fetched with a 5 KB cap, no redirects, no special-use IP ranges and a short timeout, and cached by HTTP semantics.
- A logo you publish is fetched and cached by hApp Auth, never hot-linked into the consent screen.
The quickstart shows a complete document.
Subjects
First-party clients (hAppRadar, QuickhApp) receive a public subject. Every third-party site receives a pairwise subject, keyed on the client-id host: the same person has a different sub on every site, so two sites cannot join their records by it.
Assurance levels Coming
Every ID token will carry acr, so a site can ask more for what matters to it.
acr | Reached by |
|---|---|
urn:happauth:loa:passkey | A passkey ceremony this session |
urn:happauth:loa:github | GitHub sign-in this session |
urn:happauth:loa:email | An email code this session |
urn:happauth:loa:agent | An agent-key signature: proves a running conductor, not a present person |
Treat urn:happauth:loa:agent as convenience. Before an account-level action on your site, require a passkey session. hApp Auth holds itself to the same rule: its own account actions need a passkey within the last 15 minutes.
Scopes and claims
| Scope | Claims |
|---|---|
openid | sub, auth_time; acr, amr Coming |
profile | name, picture |
email | email, email_verified |
github Coming | github: { id, login, created_at } |
happ:agents Coming | For each network (DNA hash) the site names and the person ticks: the keys bound in that network and their pairwise id. Never the person’s full key list, which would undo pairwise subjects. |
happ:maintainer Coming | maintainer: [slug, ...] from hAppRadar claim proofs |
offline_access | A refresh token |
quickhapp:read, quickhapp:write | No claim. Resource scopes for QuickhApp’s agent server: request them with resource=https://quickhapp.com/mcp and the access token is bound to that server alone |
Agents and CLIs
MCP clients Coming find hApp Auth through the protected-resource metadata (RFC 9728) that every resource publishes, ask the person on the same consent screen as any site (“Claude Code wants to publish to your QuickhApp site”), and hold a short-lived token the person sees and can revoke on their account page.
Command-line tools Coming use the device grant (RFC 8628); the approval screen names the client and its scopes.
What the person sees
The consent screen leads with your hostname, above any name or logo you supply, then one plain line per scope with a toggle on the optional ones, and one button. It is always white and never takes your colours, so it looks the same on every site and a person can tell the real one from a copy.