Signing in
PULSE has two ways in: a username and password, and Google sign-in. Both end the same way. The backend returns an access token and a refresh token, and the app sends the access token as a bearer token on every gRPC call.
Which options you see
The login screen reads GET /auth/config, which returns two fields:
| Field | Meaning |
|---|---|
google_client_id | The public Google OAuth client. Empty means no Sign in with Google button. |
password_auth | false only when the deployment sets AUTH_GOOGLE_ONLY=true. Then the username and password form is hidden. |
Username and password
The form calls IdentityService.Login with a username and a password.
You sign in with your username, not your email address.
A wrong username or password returns invalid credentials, and so does an
account that exists but has no usable password (accounts created for Google
sign-in get a random, unusable one).
Google sign-in
The app posts the Google ID token to POST /auth/google. The backend:
- Checks that the token was issued for this deployment’s OAuth client and carries a verified email.
- Checks the email against the deployment’s allowlist (
AUTH_ALLOWED_EMAILS). Google sign-in fails closed. If the allowlist is empty, nobody gets in through Google. - Finds your account by email, or creates one with the viewer role on first sign-in. A role the operator granted in advance is kept.
If you are not on the allowlist you get this account is not authorized for this instance.
Roles
Each account has one role, stored on its user row:
| Role | Granted by |
|---|---|
admin | The break-glass admin account, or an operator grant |
editor | An operator grant (writer or editor) |
viewer | New Google accounts by default, or an operator grant (reader or viewer) |
Admins see an Admin entry in the navigation. It opens the shared members and roles page, and the server checks your role again on every call there. See Users and access.
How long a session lasts
| Token | Lifetime |
|---|---|
| Access token | 24 hours |
| Refresh token | 7 days, single use |
| The session behind both | At most 30 days from sign-in |
Each sign-in creates one server-side session. The app exchanges a refresh token
at POST /auth/refresh for a new pair in the same session. Each refresh token
works once.
Signing out ends the session everywhere it is used. IdentityService.Logout
revokes the session, and the access token, the refresh token, and every token
refreshed from them stop working at once. On the Account page (click your
avatar), you can also end every session on every device.