HAP - Detailed User Guide
A capability-by-capability reference for using the Headless Auth Platform. It assumes you can
run the service and have an admin key — start with Getting started
for first-run and a glossary, and the Integration guide for the core
login flow. To run HAP on your own machine (e.g. to authenticate apps you develop locally), see
Local login guidelines — a Docker-CLI quickstart for the published
image. Endpoints are per-tenant under /t/{tenant_slug}/…; admin endpoints use X-Admin-Key
(+ X-Tenant-Id).
Everything below is available today. See Roadmap for what isn't yet.
1. Tenants, applications & providers (admin)
- Create a tenant —
POST /v1/tenants(platform admin). Generates the tenant's signing key and a default role; its discovery document then resolves at/t/{slug}/.well-known/openid-configuration. - Create an application —
POST /v1/applications(tenant admin). Returns aclient_id; confidential clients (web,machine_to_machine) also get a one-timeclient_secret. Setredirect_uris(matched exactly),scopes, andhome_url— the page a person is sent to when they pick the application from their application selector. Optionally setself_enrollment_enabledto advertise it to your whole tenant. - Create an identity provider —
POST /v1/providersfor social/OIDC or SAML, including a SCIM bearer token when SCIM is enabled.
2. Identities & passwords
- Register —
POST /v1/auth/register(enforces the tenant password policy). - Verify email —
POST /v1/auth/verify-email/requestthen/confirmwith the token. - Reset password —
POST /v1/auth/password-reset/request(always returns the same response — no account enumeration) then/confirm; a successful reset revokes existing sessions. - Admin user management —
GET/POST/PATCH/DELETE /v1/identities(scoped admin key); responses never include credential material; delete is a soft-delete with PII erasure. - Behind the scenes: passwords use Argon2id; repeated failures lock the account for a configurable window; legacy hashes are upgraded on next login.
2a. Who may create an account (tenant admin)
Every tenant decides who may self-register. A tenant administrator sets this in the admin
console at /t/{slug}/hosted/admin → Sign-up, or through
GET/PUT /v1/registration-policy — no platform-wide credential is involved either way.
- Invitation only — one switch. Nobody can create their own account by any self-service route (password sign-up, one-time code by email or SMS, magic link, first arrival at Hosted Login). People you add, and people an application invites, still join normally, and everyone who already has an account signs in exactly as before — the switch governs arrival, not sign-in.
- Allowed email domains — switch the list on and enter the domains that may sign up, one per line. Everyone else is refused.
- Blocked email domains — the same, in reverse. A blocked domain is refused even if it also appears in the allowed list.
- The two lists are kept when you switch them off, and kept (but not applied) while Invitation only is on — so closing sign-up for a week does not lose the domain policy you configured.
- Domains are bare domains — no
@, no wildcards — and match exactly:acme.comdoes not includemail.acme.com. A bad entry is refused by name and nothing is saved. - Two things worth knowing: sign-in through an external identity provider is configured separately and is not closed by Invitation only; and an enabled domain list also constrains email aliases (§ git-commit attribution), because the addresses are checked by the same rules.
Adding someone yourself — the console's Add user also offers Email them an invitation (off by default). Ticked, the person gets a link as well as an account; whether they click it or simply sign in, they end up on the same single account.
3. Logging in & tokens (OAuth 2.0 / OIDC)
The core flow — discovery → login → authorize (PKCE) → token → user-info — is documented step-by-step in the Integration guide. Key points:
- Grants:
authorization_code,refresh_token,client_credentials. - PKCE S256 is mandatory; redirect URIs must match exactly.
- Refresh-token rotation: each use issues a new refresh token; reusing an old one is treated as theft and revokes the whole token family.
- Introspection / revocation:
POST /oauth2/introspectand/oauth2/revoke.
3a. Where people land when no application sent them
Someone who signs in at HAP itself — a bookmark, or the Sign in again link after signing out —
is not coming from an application, so there is nothing to return them to. They land on the
application selector at /t/{slug}: the applications they may use, from which
choosing one forwards them there, already signed in.
- Parameter-free, so any application can link to it as "choose another application".
/t/{slug}/menuand/menu/{slug}are shorter aliases that redirect to it, for a person to read out or type — application code should link to/t/{slug}itself. (The older/t/{slug}/hosted/appsstill serves the same page but is being retired.) - The page is shown even when only one application qualifies — it also carries sign-out and, for a tenant administrator, the console link, and those must stay reachable.
- An application with no
home_urlis listed with an error rather than hidden. - Headless equivalent:
GET /v1/me/applicationswith the person's session token.
Signing in to an application that admits any authenticated user also records that they use it.
The record does nothing while the application stays open; it exists so that switching it to
restricted later does not lock out the people already using it. Full detail, including what is
deliberately not recorded, in the application selector guide.
4. Sessions & step-up (AAL)
- List your sessions —
GET /v1/sessions(with a bearer access token); each shows device and location context. - Revoke one / all —
DELETE /v1/sessions/{id}andDELETE /v1/sessions("log out everywhere"). Admins can revoke all sessions for any identity. - Step-up: when an action requires a higher assurance level than the session holds, the
authorize endpoint returns
interaction_requiredwithrequired_acr(e.g.,aal2). After the user completes a second factor, the same session is elevated — no fresh login.
5. Multi-factor authentication (MFA)
- TOTP (authenticator app):
POST /v1/mfa/totp/enroll→ show theotpauth_uri/secret →POST /v1/mfa/totp/confirmwith a code. Later,POST /v1/mfa/totp/verifyraises the session to AAL2. Codes can't be reused within their window. - Email/SMS one-time passcodes:
POST /v1/mfa/otp/send{channel}thenPOST /v1/mfa/otp/verify. Issuance is rate-limited; codes expire and lock after too many attempts.
6. Passkeys (WebAuthn / FIDO2)
- Register:
POST /v1/webauthn/register/begin→ your client performs the WebAuthn ceremony →POST /v1/webauthn/register/finish. - Log in (incl. usernameless):
POST /v1/webauthn/login/begin→ ceremony →POST /v1/webauthn/login/finish, which creates a session (AAL2 when user-verified). - Clone protection: the signature counter must increase; a cloned authenticator is detected and the credential is flagged.
7. Federation (social, OIDC, SAML)
- Social / OIDC login:
GET /v1/providers/{id}/loginreturns the upstream redirect URL; after the user returns,GET /v1/providers/{id}/callbacklinks to an existing identity (by verified email or provider subject) or just-in-time provisions a new one. - Enterprise SSO (SAML SP): post a signed SAML assertion to
/v1/saml/{id}/acs; the platform validates the signature, audience, expiry, and replay, then provisions per verified domain. SP metadata is at/v1/saml/{id}/metadata. - Platform as IdP:
POST /v1/saml/issueissues a signed SAML assertion (with identity + application custom claims) to a downstream SAML service-provider application.
8. Authorisation (RBAC)
- Roles:
POST /v1/rbac/roles(name + permissions). Assign/revoke:POST/DELETE /v1/identities/{id}/roles. Effective permissions (union of active, non-expired assignments) are embedded in the access token'spermissionsclaim.
9. AI-native risk
- Every login attempt is scored from contextual signals (new device, unusual location, impossible travel, velocity, credential-stuffing patterns). Under an adaptive tenant policy the result maps to allow / challenge / block.
- Breached-password check: enable it in the tenant password policy; passwords are checked against known-breached corpora via a privacy-preserving range query (only a partial hash prefix ever leaves the system).
- Security suggestions:
GET /v1/ai/suggestions, then accept/dismiss.
10. Operations
- Webhooks:
POST /v1/webhooks(returns a signing secret once). Deliveries are HMAC- signed (X-HAP-Signature), retried with backoff, and auto-disabled after repeated failure. - SCIM 2.0:
/scim/v2/Users(create / get / patch active / delete), bearer-authenticated per provider, to sync users from a company directory. - Audit & SIEM: every mutating action is written to an append-only, time-partitioned audit log that can be streamed to an external sink.
Roadmap (not yet available)
LDAP/AD direct login; OAuth device-code grant; formal compliance certification (today: supporting controls and audit evidence); SAML SP-initiated AuthnRequest & single logout; live session-anomaly step-up.