Dodil AppID
Dodil AppID is identity for the end users of the applications you build on Dodil — your customers, business users, and guests. You create a pool, point your app at its issuer URL, and AppID handles sign-up, sign-in, password reset, email verification, sessions, and tokens. A hosted, brandable login page ships with it; so does a JSON API if you’d rather build your own screens.
It is deliberately modeled on the Supabase-Auth shape — an auth service for your app’s users — not an enterprise IdP you have to configure realm by realm.
Two identity planes — never mixed
Dodil has two kinds of people, and two services to match:
platform plane ──► Dodil IAM org users, service accounts, dk_ API keys
issuer: id.dodil.io (who builds the app)
app plane ──► Dodil AppID the app's own end users
issuer: appid.dodil.io/{org}/{pool} (who uses the app)The two planes never share an issuer, and an app user is never a platform principal — a token minted by your pool cannot touch K3 buckets, Ignite apps, or the registry. Your backend verifies pool tokens by iss and aud; the platform verifies its own the same way.
The pool
A pool is the unit of app identity. Each pool owns:
- an Ed25519 keypair → its own issuer
https://appid.dodil.io/{org}/{pool}, JWKS, and OIDC discovery document - a user store — managed by default, or your own K3 bucket or Postgres, with live migration between them
- connections (how users sign in — email + password today)
- settings and policies — signup on/off, email verification, token TTLs, redirect URIs, rate limits, CORS origins
- a role → permission catalog, expanded into every access token
- app tenants — sub-organizations inside the pool (workspaces, subsidiaries) with per-tenant roles
- branding for the hosted pages and transactional emails
A pool is rows plus a keypair — there is no per-pool server, realm, or infrastructure to operate.
What you get out of the box
- Hosted sign-in at
{issuer}/login— sign in, sign up, forgot password, all brandable (logo, colors, dark mode, layout, custom copy) via a JSON branding document. - OIDC authorization-code flow with PKCE (S256, mandatory) for SPAs and native apps — plus direct JSON
password/refresh_tokengrants if you own the UI. - EdDSA-signed JWTs with your roles, permissions, and tenant memberships as claims; rotating refresh tokens with reuse detection that burns the whole session family.
- User management from the console,
dodil appidCLI, or REST API — invite, ban, roles, password resets, session revocation. - Branded emails for verification and password reset.
How it fits with Dodil
- The control plane rides platform auth. Creating pools and managing users happens with your normal Dodil sign-in (
dodil auth login); an org owner can always manage their org’s pools. - User data can live in your bucket. Point the pool’s user store at a K3 bucket and the users are your rows — query them over the pg wire like any other table.
- Made for Ignite apps. Deploy your frontend/backend on Ignite , send users to the pool’s hosted login, verify the JWT in your handler.
In this section
- Quickstart — create a pool, sign up a user, run the full login flow in minutes
- Core Concepts — pools, connections, tokens, tenants, user stores, the two planes
- Auth and Access — who may manage pools, and how end-user auth actually works
- CLI Guide — the
dodil appidcommands - API Reference — the control-plane REST API and the public issuer API
- Recipes — hosted login for an SPA, verifying tokens in your backend, owning your user store
CLI: dodil appid — see Install the CLI .
Current release: v0.6.2. Email + password (
local) is the shipped connection; social OAuth (Google/GitHub/…), SAML, magic links, and MFA are on the roadmap, not in the product — this documentation only describes what works today.