Gives every client its own key, from pairing or made by hand, in place of the one shared API token. The old token keeps working everywhere until the Home Assistant integration moves to keys, and goes in the release after that. Also adds a What's new page and an install offer to the web client.
Client keys
- Give each client its own key: the Android app when it pairs, a browser when System Bridge opens it, and anything else with New key under Settings > Devices or
system-bridge client key create "<name>". A key made by hand is shown once. Only its SHA-256 hash is kept, inkeys.json(docs) - List every client with a key under Settings > Devices, with its name, how it got its key, when it was made and last used, and whether its key has been sent in a URL. Remove signs it out at once
- Make an owner key on first start, in the
owner-keyfile only your user can read. The CLI signs in with it, andsystem-bridge client key owner --replacemakes a new one (docs) - Accept
Authorization: Beareron every route, and sign a WebSocket in with{"type": "auth", "key": "..."}as its first message. A wrong key getsBAD_KEYand the socket closes (docs) - Add
GET,POSTandDELETE /api/keysto list, make and remove keys, andPOST /api/keys/exchangeto trade the old token for a client's own key (docs) - Sign media file URLs on the server with
POST /api/media/file/url, so a URL handed to a cast speaker never holds a key (docs) - Take a key as
?key=on/api/mcponly, for MCP clients that take nothing but a URL, such as Home Assistant's MCP integration set up by hand. That URL is never logged (docs) - Take a pairing code typed in by hand as the pairing page shows it, grouped with dashes, or with spaces or in lower case
- Keep the old API token working in all its old places until the Home Assistant integration has moved to keys
Web client
- Sign in with the browser's own key, trading a saved API token for one the first time
- Open the web client from the tray, at startup or with
system-bridge client opensigned in with a one-time pairing code rather than the token, and keep the address out of the logs - Add a What's new page with the newest release notes, from the new
GET /api/releases(docs) - Offer to install the web client as an app, and update it when System Bridge updates
- Use Groundwork's pairing, copy, action button, install banner and version watch elements
- Call the connection's secret a key rather than an API key
Security
- Stop sending notification, settings and power broadcasts to WebSocket clients that haven't signed in (#4623)
Android
- Send the phone's key as
Authorization: Bearer, and trade a phone's old token for its own key when the app opens
CLI
- Add
system-bridge client key create,list,removeandowner - Sign the CLI's own requests,
client open,client data watch,client quitandagent call, in with the owner key - Add the System Bridge agent skill
Connector
- Python: send
Authorization: Bearerand sign the socket in with its first message. AddHTTPClient.exchange_key(),HTTPClient.pair(),HTTPClient.media_file_url()and akeysmodule tested against Groundwork's vectors.helpers.media_file_url()is deprecated, andRequestno longer carriestoken - Python: read the version from
/api/health, which needs no key, and support System Bridge 5.28.6 and later, so an older System Bridge says it needs updating rather than failing to sign in - TypeScript: send
Authorization: Bearer, sign the socket in with its first message, addexchangeKey(), and treatBAD_KEYas anAuthenticationError - Python: export the module models from
systembridgeconnector.models.modules, for strict typing
System
- Treat
System Versionas an unset DMI value in the system module's device info
Docs
- Document client keys, the Keys API, pairing for browsers, signed media URLs and signing in on the WebSocket and MCP server
- Document What's new and
/api/releases, and all six Android quick settings tiles
Dependencies
- Update Groundwork to 0.48.0 in the web client and the Android app's pairing page, and add
@timmo001/groundwork-auth0.48.0 - Update effect to 4.1.4, Vite to 8.3.8 and @tanstack/charts to 1.5.0
- Update github.com/shirou/gopsutil/v4 to v4.26.10 and github.com/vcaesar/screenshot to v0.40.1
- Update @timmo001/docs-kit to 0.48.0 for the docs
Maintenance
- Add hk hooks with the shared lints, a root Prettier config and the shared stale workflow
- Update Nix dependency hashes
Full Changelog: 5.28.5...5.29.0