Configuration templates
The three layers are flexible, but most applications start from one of a handful of shapes. Pick the closest template below, drop the rules into your application in the With portal, then adjust.
In the tables below, *.example.com style values are placeholders — replace them with your own. Each layer can hold more than one rule; within a layer, rules are OR’d.
Standard web app (passwordless)
Section titled “Standard web app (passwordless)”Passkeys plus email one-time codes, open sign-up, redirect back to your site. The most common starting point.
| Layer | Rules |
|---|---|
| 1 — Authentication | PASSKEY_USERNAMELESS, PASSKEY_REASONED, EMAIL_VERIFICATION |
| 2 — Realize | EMAIL → { "allowedEmails": ["*"] } |
| 3 — Return | CALLBACK → { "allowedCallbackDomains": ["app.example.com"] } |
Web app with social sign-in
Section titled “Web app with social sign-in”The passwordless template plus “Sign in with …” buttons. Add only the providers you want; each is one Layer 1 rule.
| Layer | Rules |
|---|---|
| 1 — Authentication | PASSKEY_USERNAMELESS, PASSKEY_REASONED, EMAIL_VERIFICATION, GOOGLE_OAUTH, GITHUB_OAUTH, DISCORD_OAUTH |
| 2 — Realize | EMAIL → { "allowedEmails": ["*"] } |
| 3 — Return | CALLBACK → { "allowedCallbackDomains": ["app.example.com"] } |
Note that Steam-, Battle.net-, and X-only accounts have no verified email, so an EMAIL-only Layer 2 rejects them. If you offer those providers, pair the EMAIL rule with STEAM_ID / EVERYONE as appropriate (see the public-app template below).
Internal / team tool (domain-restricted)
Section titled “Internal / team tool (domain-restricted)”Only people with an email on your company’s domain may sign in.
| Layer | Rules |
|---|---|
| 1 — Authentication | PASSKEY_USERNAMELESS, PASSKEY_REASONED, EMAIL_VERIFICATION |
| 2 — Realize | EMAIL → { "allowedEmails": ["*@yourcompany.com"] } |
| 3 — Return | CALLBACK → { "allowedCallbackDomains": ["tool.yourcompany.com"] } |
To force those users through your own identity provider instead of (or in addition to) the gate above, see Sign in with your IdP and Domain login policy.
Steam game (silent, in-game login)
Section titled “Steam game (silent, in-game login)”A game shipped through Steam that logs the player in without a browser.
| Layer | Rules |
|---|---|
| 1 — Authentication | STEAM_TICKET → { "allowedSteamAppIds": [480] } |
| 2 — Realize | STEAM_ID → { "allowedSteamIds": ["*"] } |
| 3 — Return | DIRECT_ISSUE |
Replace 480 with your real Steam App ID. To let the same players also sign in through a browser “Sign in with Steam” button, add a STEAM_OPENID Layer 1 rule — it resolves to the same Steam identity. End-to-end flow: Native clients.
CLI / headless service (AccessKey)
Section titled “CLI / headless service (AccessKey)”A command-line tool or service that authenticates as a known, already-existing account with a pre-issued credential.
| Layer | Rules |
|---|---|
| 1 — Authentication | ACCESS_KEY_DIRECT |
| 2 — Realize | SECTOR_SUBJECT → { "allowedSectorSubjects": ["sub_..."] } (or an EMAIL rule that matches the bound account) |
| 3 — Return | DIRECT_ISSUE |
AccessKeys cannot create new accounts — they always act as a specific existing account, so Layer 2 pins that account. See Native clients.
OIDC relying party
Section titled “OIDC relying party”Expose the application to a standard OpenID Connect client (authorization_code + PKCE).
| Layer | Rules |
|---|---|
| 1 — Authentication | PASSKEY_USERNAMELESS, PASSKEY_REASONED, EMAIL_VERIFICATION (plus any social providers) |
| 2 — Realize | EMAIL → { "allowedEmails": ["*"] } |
| 3 — Return | OIDC → { "redirectUris": ["https://app.example.com/oidc/callback"], "allowedScopes": ["openid", "email", "profile", "offline_access"], "tokenEndpointAuthMethod": "private_key_jwt" } |
Use "tokenEndpointAuthMethod": "none" for a public client (PKCE is required either way). End-to-end setup: OIDC relying parties.
Desktop app (browser polling)
Section titled “Desktop app (browser polling)”A desktop or Electron app that opens the system browser for login, then polls for the result.
| Layer | Rules |
|---|---|
| 1 — Authentication | PASSKEY_USERNAMELESS, PASSKEY_REASONED, EMAIL_VERIFICATION |
| 2 — Realize | EMAIL → { "allowedEmails": ["*"] } |
| 3 — Return | STATUS_POLL |
See the browser-polling flow for the /establish → /status-poll → /redeem sequence.
Genuinely public app (no identity gate)
Section titled “Genuinely public app (no identity gate)”Anyone who can clear Layer 1 is allowed in — including accounts with no verified email (Steam-only, Battle.net-only). Use this when you do not want to restrict who can sign in at all.
| Layer | Rules |
|---|---|
| 1 — Authentication | whichever methods you offer (e.g. PASSKEY_USERNAMELESS, EMAIL_VERIFICATION, STEAM_TICKET, …) |
| 2 — Realize | EVERYONE |
| 3 — Return | CALLBACK / STATUS_POLL / DIRECT_ISSUE / OIDC — whatever your client uses |
EVERYONE is unconditional, so it dominates any other Layer 2 rule via the OR semantics. Use it deliberately — see Realize rules.
After you pick a template
Section titled “After you pick a template”- Narrow per request.
/establishcan tighten any layer for a single inquiry viaauthenticationConstraints/realizeConstraints/returnMethods— useful for, say, an admin-only login link. See the overview. - Decide what profile data you request. Whether the app receives the user’s email or name is a separate setting — see Identity claims and sharing.
- Set token lifetimes. Each rule can override the access- and refresh-token TTLs; leave them
nullto inherit the platform defaults.