API keys
Admin, API and webhooks (/admin/integrations). Needs module.integrations
and the integration.manage permission.
Issuing a key
Section titled “Issuing a key”Create a key, give it a name that says what it is for, and choose its scopes.
The key is shown once. Copy it then. Only a hash is stored, so a leaked database does not hand over working credentials, and neither can we recover a key you lost. Issue a new one instead.
Scopes
Section titled “Scopes”A key’s scopes are permissions, the same set roles use. A key cannot exceed them.
Give a key the narrowest set that does its job. The two questions worth asking:
- Does it need to write at all? Most integrations read. A read-only key cannot surprise you.
- Does it need this whole area? A key that reads devices does not need
client.view.
Where keys are used
Section titled “Where keys are used”| Surface | How |
|---|---|
| The REST API | Authorization: Bearer <key> |
| The MCP server | The same bearer token |
The MCP server is worth thinking about when scoping. tools/list returns only
the tools a key’s scopes permit, so two keys see two different catalogues. A
read-only key cannot see, let alone call, a mutating tool.
Revoking
Section titled “Revoking”Revoke a key from the same screen. It stops working immediately.
Revoke rather than delete when you want the record of it having existed. Both are audited.
Rotation
Section titled “Rotation”There is no automatic expiry. Rotate on a schedule you set, and definitely when:
- somebody with access to the key leaves,
- the key has been in a script, a config file or a chat message,
- you are not sure where it has been.
Rotating is: issue a new key, update the client, confirm it works, revoke the old one. In that order, so there is no gap.
Treat them like passwords
Section titled “Treat them like passwords”A key is a credential that acts within your tenant with its scopes. It belongs in a secret store, not in a repository, a shared document, or a message.
Auditing
Section titled “Auditing”Issuing, revoking and deleting a key are all recorded in the audit log.
Actions taken with a key are also audited, attributed to the key rather than to a person. That is what makes a per-integration key better than a shared one: when something unexpected happens, you know which integration did it.
Naming
Section titled “Naming”Name keys after the thing using them, not after the person who created them.
Asset register sync is useful in an audit log. James test is not, especially
after James has left and nobody knows whether it is safe to revoke.