Platform keys and rotation
The keys and secrets the AIOE API holds, how to make each one, and what happens when you change it.
Besides its database password, the API holds a handful of keys. Each one comes from the environment, belongs in your secret store, and has its own consequences when you change it. This page lists them, shows how to make them, and says what to expect when you rotate one.
The keys
| Variable | What it protects | If unset |
|---|---|---|
AIOE_SECRETS_KEY | Seals (AES-256-GCM) the secrets administrators keep for agents' tools, people's linked source-control accounts, and workbench backups. | The platform keeps none of them, and says so. |
AIOE_SIGNING_KEY | The platform's Ed25519 key. It signs remote-control requests sent over the overlay and short-lived peer tokens; workbenches and nodes check them against /.well-known/aioe-jwks.json. | Each replica generates its own key at start. Fine for one replica, wrong for more. |
AIOE_GATEWAY_SECRET | Shared between the API and the overlay gateway. | Remote control uses the relay only. |
AIOE_ENTRA_CLIENT_SECRET | The API registration's client secret, used to act for people in Azure DevOps. | Azure DevOps links with a personal token only. |
DATABASE_URL | Holds the database password. | Required when STORE=postgres. |
On Azure, the template's secure parameters secretsKey, signingKey, gatewaySecret and entraClientSecret set these for you.
Make a key
openssl rand -base64 32node -e "crypto.subtle.generateKey({name:'Ed25519'},true,['sign']).then(k=>crypto.subtle.exportKey('jwk',k.privateKey)).then(j=>console.log(JSON.stringify(j)))"openssl rand -base64 32The API refuses to start if AIOE_SECRETS_KEY is set but is not exactly 32 bytes once decoded.
Rotate a key
Set the new value in your secret store, then restart every API replica so they all read it (kubectl rollout restart deployment/aioe-api with Helm; a new revision on Azure). What follows depends on the key.
AIOE_SECRETS_KEY
Rotating this key loses what it sealed
Nothing sealed under the old key can be opened with the new one, and the platform does not re-seal for you.
After a rotation:
- Secrets kept for agents' tools must be entered again: in Secrets (and on each project's Policy tab), use Rotate on each one to give it a value under the new key.
- Linked source-control accounts are invalid: people link again under Settings, Source control.
- Workbench backups cannot be restored: each person's workbench backs up again.
Rotate this key only when you believe it was exposed, and plan for people to relink.
AIOE_SIGNING_KEY
Every replica must have the new value at the same time. The public key at /.well-known/aioe-jwks.json changes with it, and workbenches and nodes check signatures against what that address publishes. Peer tokens signed with the old key live at most ten minutes.
AIOE_GATEWAY_SECRET
The API and the gateway must agree. Change it on both, and restart both: the gateway's token file holds aioe_gw_<tenant>.<secret>, so rewrite that file too. Until both agree, remote control falls back to the relay.
AIOE_ENTRA_CLIENT_SECRET
Entra client secrets expire (a common choice is two years). Before the expiry date, create a new secret on the API registration under Certificates & secrets, set it on the API, restart, then delete the old one in Entra. People's Azure DevOps links carry on. On Azure:
az containerapp secret set -g <resource group> -n aioe-prod-api --secrets entra-client-secret="<new secret>"
az containerapp update -g <resource group> -n aioe-prod-api \
--set-env-vars AIOE_ENTRA_CLIENT_SECRET=secretref:entra-client-secretThe database password
Change the password in PostgreSQL, update DATABASE_URL (Helm: the aioe-api secret; Azure: run the deployment again with the new postgresAdminPassword), and restart the API.
Device and refresh tokens
You do not rotate the tokens AIOE issues to workbenches: they rotate themselves. An access token lives an hour and a refresh token thirty days, and every refresh issues a new pair and revokes the old refresh token. To cut one machine off, open it in the console and choose Revoke access. See Tenancy and tokens.