Skip to main content

Sign-in and token refresh

In the current pilot a person signs in from the frontend's sign-in page by choosing a demo persona and typing a password. The browser never talks to Keycloak. The frontend's own route does, on the in-cluster address.

Sign-in and token refresh. The browser posts a persona id and password to the frontend. The frontend checks the id against an allow-list, asks Keycloak for a password grant, writes the refresh token into an HttpOnly cookie and returns the access token in the body. Later, when the access token is close to expiry, the browser posts to the refresh route with no body. The frontend redeems the cookie at Keycloak, rewrites the cookie and returns a new access token.

Details​

  • Allow-list. /api/auth/token accepts only the demo persona ids offered on the sign-in page. A password cannot be tried against any other account through this route.
  • Retries. The frontend retries a failed connection to Keycloak up to three more times, after 300, 700 and 1200 ms. It never retries a refusal.
  • Cookie. startupos_session is HttpOnly, SameSite=Lax, scoped to the path /api/auth, and Secure in production. Its lifetime follows the refresh token. It is absent from every other request.
  • Access token. It is returned in the response body, and the browser keeps it in localStorage, because it has to set an Authorization header. Its lifetime is 30 minutes (accessTokenLifespan 1800 in the realm script).
  • Rotation. Keycloak may issue a new refresh token on each renewal. The route writes it back to the cookie.
  • Failed renewal. A refusal clears the cookie. An unreachable provider does not, so a blip does not sign people out.

This is a demonstration sign-in. See Authentication model for what the pilot does and does not provide.

Sources: frontend/src/app/api/auth/{token,refresh,logout}/route.ts, frontend/src/app/api/auth/session.ts, frontend/src/lib/auth.ts, infra/keycloak/import-startupos-realm.sh.