Durable API keys
Configure a durable API-key store for the dashboard and mint keys that reach only the workspaces you choose.
Prerequisites
Section titled “Prerequisites”- An Omnia install with the dashboard enabled and
dashboard.apiKeys.enabled: true(the chart default). - To create keys in the dashboard, a role that can manage your own API keys. The API keys tab on Settings appears only for roles that can view them.
Choose a key store
Section titled “Choose a key store”Set dashboard.apiKeys.store to one of three values. The chart default is memory.
memory: keys live in the management-api process and vanish on every restart. Each replica holds its own. Use it for development only.postgres: keys live in Postgres. Create and revoke work in the dashboard.file: keys come from a mounted Kubernetes Secret and are read-only. Creating or revoking keys in the dashboard is refused.
All stores keep only bcrypt hashes. The full key is shown once, when you create it.
management-api serves every API-key route and checks every key, from the store these values name.
-
For
postgres, set a connection URL, or a Secret that holds it under the keyOMNIA_AUTH_API_KEYS_POSTGRES_URL:dashboard:apiKeys:store: postgresexistingPostgresSecret: omnia-apikeys-postgresUse
postgresUrlinstead for a literal URL. Withauth.mode: builtinand a builtin Postgres URL configured, you can omit both and the store reuses that URL. The chart fails to render ifstore: postgreshas no URL from any of these sources.Leaving
storeatmemorywhilepostgresUrlorexistingPostgresSecretis set switches the store topostgres. -
For
file, put the key file in a Secret in the release namespace and name it inkeysSecret:dashboard:apiKeys:store: filekeysSecret: omnia-api-keysThe chart mounts the Secret at the directory of
dashboard.apiKeys.filePath(default/etc/omnia/api-keys/keys.json), so the Secret key must match the file name,keys.jsonby default. The chart fails to render ifkeysSecretis empty. -
Apply the change:
Terminal window helm upgrade omnia oci://ghcr.io/altairalabs/charts/omnia --devel \--namespace omnia-system --reuse-values -f values.yaml
See Dashboard authentication reference for the key header formats and the key endpoints, and Authentication for how keys are checked.
Generating file-store keys
Section titled “Generating file-store keys”The file store reads keys.json, which holds a keys array. Each entry takes id, userId, name, keyPrefix, keyHash, role, expiresAt and createdAt. It also accepts optional workspaces, ownerEmail and ownerGroups fields.
-
From the root of the Omnia repository, with Go installed, generate a key and its entry.
--userand--nameare required.--roleisadmin,editororviewer(defaultviewer).--expiresis days until expiry (default90,0for never). The values below are illustrative.Terminal window go run ./hack/generate-api-key --user=ci-bot --name="CI pipeline" --role=editor --expires=0The command prints the key once, as
omnia_sk_followed by 43 base64url characters, and the JSON entry to add to thekeysarray. Keep the key for the client. With--jsonit prints one JSON object instead, with the key underkeyand the entry underentry. -
Put the entry in
keys.json, and addworkspaces,ownerEmailorownerGroupsby hand if the key needs them. -
Create the Secret:
Terminal window kubectl create secret generic omnia-api-keys \--namespace omnia-system --from-file=keys.json=./keys.json
management-api checks the mounted file at most every 5 seconds and reloads it when it changes.
Scope a key to workspaces
Section titled “Scope a key to workspaces”By default a key carries the minting user’s full access, so it can act in every workspace that user can reach. A per-key allowlist narrows that to the workspaces you name.
Create a scoped key
Section titled “Create a scoped key”- Open Settings, select the API keys tab, and select Create Key.
- Enter a name and an expiration.
- Tick one or more workspaces under Restrict to workspaces.
- Select Create Key, then copy the key from the API Key Created dialog. It cannot be shown again.
Leaving every workspace unticked creates an unrestricted key. The Restrict to workspaces list is hidden when you can access no workspaces.
To create the key over the API, send POST /api/settings/api-keys with a workspaces array. The values below are illustrative:
{ "name": "ci-prod-only", "workspaces": ["prod-workspace"]}If workspaces is present but is not an array of non-empty strings, the request fails with 400 and no key is created. An empty or omitted array creates an unrestricted key.
At creation the key records the owner’s email (or username) and group membership. That lets it resolve the owner’s per-workspace role without a live session.
A scoped key is denied outright for any workspace outside its list, and workspace listings leave those workspaces out. It never gets the platform-admin shortcut, even when its owner is a platform admin. Inside an allowed workspace it acts with the owner’s own role.
A scoped key manages only keys within its own scope. It can create a key only if that key’s list is inside its own, so it cannot create an unrestricted key. GET /api/settings/api-keys lists only the owner’s keys whose lists are inside its own. DELETE /api/settings/api-keys/{id} revokes only those keys, and answers 404 for any other key, the same as for a key that does not exist. A session, or an unrestricted key, lists and revokes every key its owner holds.
Deploy-profile tokens
Section titled “Deploy-profile tokens”On a workspace’s Settings page, the Deploy tab has an Export deploy profile button. When the key store allows creation, it mints a key named deploy-<workspace> with workspaces: ["<workspace>"], so the token reaches only that workspace.
If a key with that name already exists, the dialog asks whether to regenerate or reuse it. Regenerating revokes the old key before minting a new one. Reusing mints nothing, and the output holds a placeholder for the token you saved earlier. With the file store nothing is minted either, and the output holds a placeholder to fill in.
Verify
Section titled “Verify”-
List workspaces with the new key. Replace
<dashboard-url>and<key>:Terminal window curl -s -H "Authorization: Bearer <key>" https://<dashboard-url>/api/workspacesThe
workspacesarray holds only the workspaces on the key’s allowlist. An unrestricted key lists every workspace its owner can reach. -
For a durable store, restart management-api and repeat the request. It should still succeed.
Terminal window kubectl rollout restart deployment/<management-api-deployment> --namespace omnia-system
Troubleshooting
Section titled “Troubleshooting”The Create Key button is missing
Section titled “The Create Key button is missing”The file store is read-only, and the dashboard shows “Keys managed via Kubernetes Secret” on the tab. Switch to postgres to create keys in the dashboard, or add the key to keys.json and update the Secret.
A scoped key gets 403 on every request
Section titled “A scoped key gets 403 on every request”The key was minted without an owner snapshot, so it resolves no workspace role, and a scoped key cannot fall back to platform admin. management-api logs a warning that names the key. Create the key again.