Authentication
Sign in, renew and end a session. The access token is returned in the body; the refresh token lives only in the startupos_session HttpOnly cookie.
Sign in a demo persona and obtain an access token
Exchanges a persona id and that persona's password for a Keycloak access token using the password grant. Only the demo personas can be signed in here; any other `userId` is rejected with 400. The server holds no password. On success the response sets the `startupos_session` cookie (HttpOnly, `SameSite=Lax`, path `/api/auth`, `Secure` in production).
Renew the access token from the session cookie
Redeems the refresh token held in the `startupos_session` cookie and returns a new access token. There is no request body. The cookie is rewritten with the refresh token Keycloak returns. If Keycloak refuses the token the cookie is cleared; if Keycloak is unreachable the cookie is kept.
End the session
Clears the `startupos_session` cookie and, when a refresh token is present, asks Keycloak to end it. The cookie is cleared whatever Keycloak answers, so the call always succeeds.