Awwwth Docs

Awwwth / Shared sign-in

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:

AppPublic gatewayPrivate backendRegistered callback
Ahttp://localhost:3000http://127.0.0.1:3001http://localhost:3000/auth/awwwth/callback
Bhttp://localhost:4000http://127.0.0.1:4001http://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
  1. Open http://localhost:3000, sign in, and verify the account if needed. Complete any initial authorization screen.
  2. Open http://localhost:4000 in the same browser profile. It should return through Awwwth already signed in.
  3. From each app, request /auth/awwwth/session and compare user.sub. Both should match.
  4. 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 stateResult
Default request with active, verified sessionIssue an authorization code automatically
No central sessionShow sign-in
Unverified accountRequire account verification before authorization
prompt=consentShow explicit consent
prompt=login or max_age=0Require fresh authentication for the request
prompt=none with a usable sessionIssue a code without UI
prompt=none without a usable sessionReturn login_required or interaction_required
App in another directoryRequire 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.