Shared sign-in across applications
Documentation index · CLI setup
Awwwth keeps the central identity session on its own origin. Each application has a separate local session. When app B needs a session, it redirects the browser through Awwwth; an existing verified central session signs the same user into app B without another password prompt.
This works across different app domains because it uses top-level browser navigation, rather than third-party cookies or hidden iframes. The redirect can briefly appear in the address bar.
Requirements
- Both apps use the same Awwwth issuer and account directory.
- Each app has its own registered client ID, secret, and callback URL.
- Both app gateways run with their own session encryption keys.
- The user opens both apps in the same browser profile.
- The identity server has the automatic-authorization changes deployed.
Company profiles keep separate subjects and scoped sessions while using shared credentials from the main Awwwth identity. Existing independent accounts require explicit linking after fresh authentication to both verified accounts. Use the verified sub and tenant scope to associate application records. Automatic browser SSO still requires the appropriate directory session; shared credentials alone are not a cross-directory session cookie.
Run two apps locally
Start the identity server at http://localhost:4100 using the repository quick start. Register two platform applications, or two applications owned by the same company:
| App | Public gateway | Private backend | Registered callback |
|---|---|---|---|
| A | http://localhost:3000 | http://127.0.0.1:3001 | http://localhost:3000/auth/awwwth/callback |
| B | http://localhost:4000 | http://127.0.0.1:4001 | http://localhost:4000/auth/awwwth/callback |
In app A's project directory:
npx awwwth \
--issuer http://localhost:4100 \
--app-origin http://localhost:3000 \
--upstream http://127.0.0.1:3001 \
--client-id app_REPLACE_WITH_APP_A_ID
In app B's project directory:
npx awwwth \
--issuer http://localhost:4100 \
--app-origin http://localhost:4000 \
--upstream http://127.0.0.1:4001 \
--client-id app_REPLACE_WITH_APP_B_ID
Enter the corresponding secret at each hidden prompt. Start each backend privately on its assigned port. In separate terminals in each app directory, run:
node --env-file=.env.awwwth .awwwth/server.mjs
- Open
http://localhost:3000, sign in, and verify the account if needed. Complete any initial authorization screen. - Open
http://localhost:4000in the same browser profile. It should return through Awwwth already signed in. - From each app, request
/auth/awwwth/sessionand compareuser.sub. Both should match. - Sign out of the central Awwwth account session. The next session request in either app should return 401.
Authorization policy
Registered applications are trusted for automatic authorization within their directory. The default provider flow does not require separate consent for every application when a verified session exists. Register only applications that should receive supported identity scopes.
| Request or account state | Result |
|---|---|
| Default request with active, verified session | Issue an authorization code automatically |
| No central session | Show sign-in |
| Unverified account | Require account verification before authorization |
prompt=consent | Show explicit consent |
prompt=login or max_age=0 | Require fresh authentication for the request |
prompt=none with a usable session | Issue a code without UI |
prompt=none without a usable session | Return login_required or interaction_required |
| App in another directory | Require that directory's identity session |
Sessions, expiry, and logout
The provider's session lasts up to 30 days unless revoked. Gateway sessions last no longer than the five-minute access token. Each authenticated gateway request checks token activity with the provider.
When the gateway session expires, the next page navigation starts authorization again. The still-valid central session normally makes that automatic. API calls receive 401 with a login URL; the frontend must navigate to sign-in to renew. Version 0.1.0 does not store refresh tokens or refresh sessions in the background.
POST /auth/awwwth/logout signs out of one app and revokes that app's current grant. The central session remains active, so revisiting the app can sign the user in again. To end shared sign-in, sign out at the Awwwth account site. Revoke all central sessions when the intention is to sign out across browser sessions and devices.
Disconnecting an application revokes current grants. Under the registered-app trust policy, a later authorization request may connect it again. Disconnection is not a permanent opt-out from automatic authorization.
Automated verification
bun run test:sso
This test starts a disposable PostgreSQL cluster, the actual provider, and two separate Node gateway processes. It checks shared identity after one login, revocation in both apps, forged-header rejection, invalid callbacks, cross-origin mutations, prompt behavior, and tenant isolation.
Install Node.js 22+ and PostgreSQL's initdb and postgres on PATH, and run as a non-root user. The test creates and removes its own cluster under /tmp; it never uses the deployment database URL.