Add hosted login to your application
Your backend starts login, validates the callback and manages your application’s session. Oathvera hosts credential entry and enforces the configured authentication policy. Keep application data and business rules in your own product.
Configuration
Section titled “Configuration”| Setting | Source and treatment |
|---|---|
| Issuer | Copy the selected environment’s complete HTTPS issuer. Pin it in server configuration. |
| Client ID | Copy the selected server-web client; use it as the expected ID-token audience. |
| Client secret | Inject through your backend’s secret store. Record expiry and rotation ownership. |
| Callback | Register the exact URL handled by your backend, such as https://app.example.test/auth/callback. |
| Scopes | Use openid; add registered email profile if needed. Add API permissions only with an explicit resource grant. |
| Post-logout destination | Register a stable signed-out page if using hosted logout. |
No customer integration needs Oathvera’s D1 credentials, Cloudflare account, private Worker bindings or console cookies. Your application’s own session persistence is a separate responsibility.
Routes and expected behavior
Section titled “Routes and expected behavior”These paths are examples you implement in your framework; they are not automatically provided by an Oathvera package.
| Application route | Behavior |
|---|---|
GET / or /app |
With a valid application session, open the product. With no session, start hosted login immediately. |
GET /auth/start |
Create a fresh browser-bound state/nonce/PKCE transaction; redirect to Oathvera. |
GET /auth/callback |
Consume the pending transaction once, exchange the code, validate identity, establish a new application session and redirect to the product. |
| Protected page/API | Check current session authority and the product’s required permissions before returning protected data. |
POST /auth/logout |
Check origin and CSRF, end local access, and execute the chosen grant/hosted-session logout sequence. |
/signed-out and /auth/error |
Public terminal states with an explicit sign-in/retry action; exclude them from automatic login middleware. |
Do not put a second “Continue with Oathvera” landing page in front of a product that requires sign-in. Keep automatic navigation for top-level HTML requests: APIs should return a structured 401 or unavailable response rather than HTML redirects. An authority outage should show a recoverable error while withholding protected data, not restart authentication repeatedly.
Login and callback
Section titled “Login and callback”- Generate independent cryptographically random state, nonce and PKCE verifier values. Store them in a short-lived, expiring server transaction bound to a Secure, HttpOnly, SameSite=Lax browser cookie on HTTPS. Use an atomic one-time consume operation; an ordinary read followed by delete can race.
- Derive
<issuer>/oauth2/authorizefrom the pinned issuer and use the exact authorization parameters. The initial redirect can use this documented path without a discovery fetch on the critical path. Never derive the trusted issuer or destination from callback/query input. - On callback, reject missing/duplicate
code,stateoriss; match the browser transaction, state and exact configured issuer. Handle cancellation/errors without creating a session. Exchange the code once using PKCE and HTTP Basic client authentication. - Validate client-qualified discovery and the JWKS destination against the pinned issuer. Verify the ID token’s ES256 signature, issuer, client audience, times and original nonce using a maintained library. Decoding a JWT is not verification.
- Apply the profile and account-mapping rules below, replace the pre-login session identifier, and keep provider tokens encrypted server-side. Send only an opaque application-session cookie to the browser. Redirect to an allowlisted local destination, never an arbitrary
returnToURL.
Discovery and JWKS may be cached within their HTTP cache policy and a bounded application maximum. Code exchange, profile/session authority and permissions must not reuse cached success. Keep callback responses no-store, remove sensitive query strings from logs, and use a restrictive referrer policy. Follow the OIDC validation rules and Oathvera’s narrower compatibility contract.
Identity and profile
Section titled “Identity and profile”Persist an external identity mapping keyed by the exact (iss, sub) and associate it with your product’s user ID. Oathvera subjects are pairwise: a different client or authentication hostname can produce a different subject. Never transfer ownership or link an existing account solely because email addresses match.
| Requested scope | Current profile output |
|---|---|
openid |
Protocol identity, including sub. |
email |
Email address and explicit boolean email_verified. |
profile |
Optional nonempty name. No general avatar/custom-profile contract. |
Scoped profile claims can appear in the signed ID token and in GET <issuer>/oidc/userinfo. If you call UserInfo, authenticate with the server-held human access token, require success and require its sub to equal the verified ID-token subject. For verified-email admission, require a usable email and email_verified === true; fail closed or provide an explicit verification-required screen if proof is absent. Email domain membership alone is not verification.
Create a new product account only after these checks and your own admission rules pass. Handle repeated callbacks and concurrent first logins using unique identity constraints and atomic product-account binding. Decide account migration separately for an existing product.
Sessions and access after login
Section titled “Sessions and access after login”For a server application following Oathvera’s current revocation model, call GET <issuer>/oidc/session with the human access token before granting protected access. Require HTTP 200, active === true, matching issuer/client/subject and future expiry. This returns session status without retrieving profile data. Do not cache an allow result across requests; the local cookie or an old signed ID token alone cannot prove current authority.
Access tokens expire after five minutes. Implement serialized, atomic refresh before expiry; store the replacement refresh token and discard the old one. Concurrent requests must coordinate through your shared session store, not independent per-instance locks. A lost code/refresh response has an uncertain outcome: do not blindly replay it. See sessions and credentials.
Authentication is separate from API authorization. For an Oathvera-protected API, the API performs the online permission check with its own expected resource, action and organization context, then enforces product record ownership. A client grant, successful login or verified email does not by itself grant business access.
Logout, failures and application shells
Section titled “Logout, failures and application shells”Choose and document whether logout ends the local application session, its Oathvera grant, or the hosted session too. Always make local access end even if the upstream call fails; record/retry provider cleanup securely without restoring the local session. Hosted logout currently requires an active matching grant and hosted cookie, so do not revoke first and assume that endpoint will still succeed. Test the exact logout sequence.
Exclude callback, error and signed-out routes from redirect middleware. For installed web apps, make authentication routes and protected bootstrap network-only and keep them out of offline response caches. Update stale shells that still show the old login page; a service worker must never serve a cached authenticated response as current access. Preserve unsaved product work through your normal recovery design.
Before deployment, complete the production handoff, including bounded network calls, session-store restarts, refresh concurrency and revocation checks. The local sample intentionally demonstrates a smaller subset.