token management
View agent refresh tokens for a site and revoke them when an agent should no longer be able to reconnect.
Location: Admin Panel -> agent tokens (/admin/tokens)
Permissions
The admin token page is superadmin-only. The backing site APIs require the GLOBAL_SETTINGS_WRITE capability, so site admins and members cannot use this page.
token list
The page starts with a site selector and a refresh button. After a site is selected, it loads active token records from /api/sites/{siteId}/agent-tokens.
| column | description |
|---|---|
| machine ID | Machine hostname recorded when the agent paired or exchanged its installer registration code. |
| version | Agent version that created the token, or N/A when unavailable. |
| status | Expiry status for the refresh token. Current long-duration tokens usually show Never expires because new token records omit expiresAt. |
| created | When the refresh token record was created. |
| last used | When the agent last used this refresh token to request a new Firebase ID token. |
| actions | Per-token revoke action. |
The API also returns internal fields such as the token record ID, createdBy, and agentUid, but the current UI does not display them.
refresh-token records
Agent refresh tokens are stored server-side in the agent_refresh_tokens collection. The document ID is the SHA-256 hash of the refresh token, so the durable refresh-token record does not store the raw token in plaintext. During device-code pairing, the raw token is held only on the short-lived pairing document until the agent's single-use poll consumes it and deletes that document.
Each token record contains:
| field | description |
|---|---|
siteId | Site the token authorizes. |
machineId | Machine hostname. The refresh endpoint rejects requests when the submitted machine ID does not match this value. |
version | Agent version from the pairing or registration exchange. |
createdBy | User who generated or authorized the token flow. |
createdAt | Server timestamp for token creation. |
lastUsed | Server timestamp updated atomically on refresh. |
agentUid | Firebase Auth UID for the agent identity. |
expiresAt | Optional expiry. If absent, the refresh token does not expire automatically. |
The token list is sorted newest-first by createdAt.
lifecycle
1. A pairing or installer flow creates a short-lived registration artifact:
- installer registration codes expire after 24 hours
- device-code pairing phrases expire after 10 minutes
2. After authorization, the server creates:
- a Firebase ID token for immediate agent use
- a long-lived random refresh token
- a hashed refresh-token record in `agent_refresh_tokens`
3. The agent stores the raw refresh token locally in
`C:\ProgramData\Owlette\.tokens.enc`.
4. The agent caches the one-hour Firebase ID token and refreshes before expiry.
5. Each successful refresh updates `lastUsed` and returns a new one-hour Firebase ID token.The local token file is encrypted with a machine-specific key derived from the Windows MachineGuid and hostname. It stores the refresh token, cached access token, access-token expiry, and site ID.
rotation behavior
Refresh-token rotation is manual. The refresh endpoint does not issue a replacement refresh token during normal access-token refresh; it only returns a new one-hour Firebase ID token.
To rotate an agent refresh token, revoke the existing token and re-register the agent with a new pairing or installer registration flow. The new flow creates a new refresh-token record and a new raw token stored on the machine.
revoking tokens
revoke one token
- Select the site.
- Find the machine row in the token table.
- Click revoke.
- Confirm the dialog.
The page sends the token record ID to /api/sites/{siteId}/agent-tokens/revoke, and the server deletes that one agent_refresh_tokens document after confirming it belongs to the selected site.
revoke all tokens for a site
When the selected site has active tokens, the page shows revoke all.
- Click revoke all.
- Confirm the destructive dialog.
- The server deletes every refresh-token record for that site and returns the revoked count.
This is a site-wide action. Every agent in the selected site must be re-registered before it can regain refresh-token access.
machine-scoped revoke
The revoke API also accepts a machineId and can delete all token records for that machine in the selected site. The current admin page does not expose a machine-scoped bulk action; it only exposes per-token revoke and site-wide revoke all.
effect on agents
Revocation deletes the refresh-token record immediately. A running agent may continue using a still-valid cached Firebase ID token until that token expires. On the next refresh attempt, the server rejects the deleted refresh token, and the agent clears its encrypted local credentials.
After that point the agent reports an authentication error or no refresh token, disconnects from Firestore-backed sync, and must be paired again with a new registration or device-code flow.
when to revoke
- Decommissioning a machine - revoke the token before removing or repurposing the machine.
- Security concern - revoke immediately if the machine or local token file may be compromised.
- Duplicate registrations - revoke stale tokens after reinstalling or re-pairing an agent.
- Credential rotation - revoke and re-register when a new refresh token is required.
system presets
System presets are the platform template library for software deployments. They are global installer presets, not process configuration presets.
email alerts
Owlette sends email notifications for machine health, process, threshold, Cortex, and display-event alerts. Superadmins manage alert rules in Admin Panel -> alerts (/admin/alerts) and test email delivery in Admin Panel -> email (/admin/email). Individual recipients manage their own delivery preferences in account settings -> alerts.