# Passport Auth integration guide for AI coding agents Use this guide to integrate Passport Auth into an application. Passport Auth is a deploy-per-app auth service. It exposes hosted auth pages and public auth API endpoints under the same public web origin. The public API lives under `/api/v1/auth`. Required integration input: - Ask for `PASSPORT_AUTH_URL` before implementation. This is the self-hosted Passport Auth URL, for example `https://auth.example.com`. - Use `PASSPORT_AUTH_URL` as the base URL for hosted pages and public API calls. - Do not assume `passport.alactic.net` is the auth service URL; that domain hosts this documentation. - If the app has its own backend APIs, ask for Passport Auth Dashboard Settings > Token verification values: public key PEM or JWKS, issuer, audience, algorithm, and key id. Core flow: 1. Configure the app origin and callback URL in the Passport Auth dashboard. 2. Generate a PKCE code verifier in the application. 3. Derive a SHA-256 base64url code challenge from the verifier. 4. Start auth by redirecting to a hosted page or calling the public API from custom auth screens. 5. Receive `?code=` on the app callback URL. 6. Exchange `{ code, code_verifier }` at `POST /api/v1/auth/token`. 7. Store the returned access token, refresh token, and user using the app's session model. 8. Use `GET /api/v1/auth/me` with `Authorization: Bearer ` for the current user. 9. Use `POST /api/v1/auth/refresh` to rotate refresh tokens. 10. Use `POST /api/v1/auth/logout` and clear local session state on logout. 11. For protected app backend routes, verify the access token locally with RS256 public-key verification before trusting user claims. Hosted pages: - Open `${PASSPORT_AUTH_URL}/login?redirect_url=&code_challenge=` for sign in. - Open `${PASSPORT_AUTH_URL}/register?redirect_url=&code_challenge=` for account creation. - Hosted pages handle password, OTP, magic link, Google OAuth, and reset flows when those methods are enabled. - The app callback receives only an authorization code, never tokens. Custom pages: - Call `POST /api/v1/auth/register` with `name`, `email`, `password`, `redirect_url`, and `code_challenge`. - Then call `POST /api/v1/auth/register/verify` with `email` and `otp`. - Call `POST /api/v1/auth/password/login` with `email`, `password`, `redirect_url`, and `code_challenge`. - Call `POST /api/v1/auth/otp/start`, then `POST /api/v1/auth/otp/verify`. - Call `POST /api/v1/auth/magic-link/start`; the email link should complete auth and return to the app callback. - Call `GET /api/v1/auth/google/start?redirect_url=&code_challenge=` and navigate to the returned `authorization_url`. Token exchange: ```http POST ${PASSPORT_AUTH_URL}/api/v1/auth/token Content-Type: application/json { "code": "authorization_code_from_callback", "code_verifier": "original_pkce_verifier" } ``` Token response: ```json { "access_token": "jwt", "refresh_token": "opaque_refresh_token", "token_type": "bearer", "expires_in": 7776000, "user": { "id": "user_id", "name": "Jane Appleseed", "email": "jane@example.com", "role": "user", "email_verified": true, "user_metadata": {} } } ``` Backend access-token verification: - Passport Auth public access tokens are JWTs signed with `RS256`. - Passport Auth keeps the private signing key. The app backend must only receive public verification material. - Store verifier config in backend environment variables, for example: ```env PASSPORT_AUTH_URL=https://auth.example.com PASSPORT_AUTH_JWKS='{"keys":[...]}' PASSPORT_AUTH_ISSUER=passport-auth PASSPORT_AUTH_AUDIENCE=passport-auth-app ``` - Alternatively store `PASSPORT_AUTH_PUBLIC_KEY_PEM` instead of `PASSPORT_AUTH_JWKS` if the JWT library accepts PEM keys. - On every protected backend request, read `Authorization: Bearer ` and verify the access token locally. - Required JWT checks: `alg == RS256`, matching `kid`, valid signature, `iss`, `aud`, `exp`, and `type == access`. - After verification, use `sub` as the Passport Auth user id. Treat `email` and `role` as trusted only after verification succeeds. - Return 401 for missing, expired, tampered, wrong-issuer, wrong-audience, or non-access tokens. - Refresh tokens are opaque random tokens. Do not verify refresh tokens in the app backend; send them only to `POST /api/v1/auth/refresh` or `POST /api/v1/auth/logout`. - Do not call `/me` on every backend request if local RS256 verification is configured. Use `/me` for client current-user lookup or occasional live account status checks. Important implementation rules: - Keep the PKCE verifier client-side only until token exchange. - Do not put access tokens or refresh tokens into redirect URLs. - Validate missing or failed token exchange states and show a retry sign-in action. - Store refresh tokens according to the app's security model. - If using browser storage, prefer short-lived access-token memory storage plus refresh handling appropriate for the app. - Always clear local tokens on logout. - In production, redirect URLs must exactly match configured Passport Auth redirect URLs. - In development, localhost and 127.0.0.1 URLs with ports are allowed when Passport Auth runs in development mode. Public API reference: - `GET /api/v1/auth/request/validate` - `POST /api/v1/auth/register` - `POST /api/v1/auth/register/verify` - `POST /api/v1/auth/password/login` - `POST /api/v1/auth/otp/start` - `POST /api/v1/auth/otp/verify` - `POST /api/v1/auth/magic-link/start` - `POST /api/v1/auth/magic-link/consume` - `POST /api/v1/auth/password-reset/start` - `POST /api/v1/auth/password-reset/confirm` - `GET /api/v1/auth/google/start` - `GET /api/v1/auth/google/callback` - `POST /api/v1/auth/token` - `POST /api/v1/auth/refresh` - `POST /api/v1/auth/logout` - `GET /api/v1/auth/me`