> ## Documentation index
> Fetch the complete documentation index at: https://developer.rhombus.com/llms.txt
> Use it to discover all available pages before exploring further.

# Permissions and Key Rotation

> Give each Rhombus integration the least access it needs: what each credential inherits, how OAuth scopes limit a user's role, rotating API keys, certificates and OAuth tokens without downtime, and finding your integration's actions in the audit log.

Every Rhombus credential acts with a **role**: the role on the API key, the signed-in user's role for an OAuth token (limited by the token's scopes), or the minting credential's role for a federated token. The role decides which locations and devices a request can see and which features it can use. Give each integration its own credential with the narrowest role that works.

## What each credential can do

| Credential                           | Acts with                                                                                                                                           | Changes when                                                                                 |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| API key                              | The role chosen when the key was created                                                                                                            | You edit the key's role (applies within 60 seconds)                                          |
| Partner key in a client organization | The role that client organization granted your partner account                                                                                      | The client changes your partner access                                                       |
| OAuth access token                   | The role of the user who authorized the app, limited to the token's [scopes](https://developer.rhombus.com/authentication/permissions#oauth-scopes) | That user's role changes                                                                     |
| API key created with an OAuth token  | The role passed when it was created (one the user may assign)                                                                                       | You edit the key's role. Revoking the OAuth grant deletes the key                            |
| Federated token                      | The role of the credential that minted it, at mint time                                                                                             | It doesn't: mint a new token. It stops working when the credential that minted it is revoked |

Roles are managed in the console under [**Settings → Roles**](https://console.rhombussystems.com/settings/roles). A role combines location and device access (admin, read-only, live-only or none) with feature permissions such as access control, alarm monitoring, saved video, and API administration.

## OAuth scopes

An OAuth app asks for **scopes** when the user signs in, and the user sees them on the consent screen. A token can do only what **both** the user's role and the token's scopes allow: the effective permission is the role intersected with the scopes. A scope never grants anything the role doesn't.

| Scope      | Consent screen                                                              | Covers                                                                                                                                                                                                         |
| ---------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `read`     | Read: view cameras, footage and settings                                    | Operations whose names start with `get`, `find`, `search`, `list`, `export`, `count`, `query`, `lookup`, `fetch`, `download`, `view`, `describe` or `preview`; media and live video; the event WebSocket       |
| `write`    | Write: change settings and data                                             | Every other operation                                                                                                                                                                                          |
| `physical` | Physical: unlock doors and elevators, lockdown, alarms, speakers and robots | Door and elevator unlocks (integration unlocks included), lockdown, state overrides, relays, first-in, arm and disarm, escalation to an alarm, speaker playback, the robot live socket, and sending talk audio |

- Apps request scopes space-delimited in the `scope` parameter at `/oauth/authorize` (`scope=read write`). Unknown values are ignored, and an app that requests no scope gets all three.
- The token response's `scope` lists what was granted, and the discovery and protected-resource documents list `scopes_supported`.
- Creating, rotating or renewing API keys with an OAuth token needs all three scopes.
- The [API Reference](https://developer.rhombus.com/api-reference/overview) shows the scope each operation needs.

A request outside the token's scopes returns 403 `PERMISSION_REQUIRED` with a header that names the missing scope:

```text
WWW-Authenticate: Bearer error="insufficient_scope", scope="physical"
```

An OAuth token without `read` is refused at the event WebSocket handshake. Talk audio is checked per message: sending audio without `physical` closes the socket with code `1008`.

How to request scopes in the sign-in flow is in [Sign in with Rhombus](https://developer.rhombus.com/oauth-authentication).

## Least privilege

- **One key per integration.** A key's name shows in the audit log, and you can rotate or delete one integration without touching the others.
- **A role per job**, not one powerful key for everything:

| Job                                          | Role needs                                                                                          |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Device health dashboard                      | Read-only access to the locations it reports on                                                     |
| Door unlock from a help-desk tool            | Access control on the doors' locations only                                                         |
| Export footage for investigations            | Read-only device access plus saved video                                                            |
| Event pipeline (webhooks or WebSocket)       | Read-only access to every location whose events it needs; events for anything else aren't delivered |
| Minting federated tokens for a camera viewer | Live-only or read-only access to those cameras; the tokens inherit it                               |

- **Request only the OAuth scopes you need.** A dashboard needs only `read`. Leave out `physical` unless the app unlocks doors, controls alarms or drives robots.
- **Give keys an expiry.** A key with `expiresAtMs` stops working on its own if it's forgotten; keys created by another API key always have one.
- **Keys created before roles were required may have no role**, which means full access to the organization. Replace them with keys that have an explicit role.
- **Physical actions** (unlocking doors, lockdown, alarm escalation) deserve their own key, or the `physical` scope only in the OAuth app that needs it, and, for anything automated or AI-driven, a human approval step in your application.

## Rotate an API key

Rotate keys on your own schedule, before they expire, and whenever one may have leaked. [`rotateApiToken`](https://developer.rhombus.com/authentication/api-keys#rotate-a-key) issues a replacement with the same role and keeps the old key working for an overlap you choose:

1. Call `POST /api/integrations/org/rotateApiToken` (partner keys: `POST /api/partner/rotateApiToken`) with the old key's `tokenUuid` and an `overlapSec` long enough to deploy: one day by default, at most 30 days. For a certificate key, send a new `csr` too.
2. Deploy the new `apiKey` (and `cert`, for a certificate key) everywhere the old key is used.
3. Confirm the integration works with the new key before `previousKeyExpiresAtMs`.
4. At `previousKeyExpiresAtMs`, the old key stops working. To end it sooner, delete it.

In the console, the same result takes four steps: create a new key with the same role ([API keys and certificates](https://developer.rhombus.com/authentication/api-keys#create-an-api-key)), deploy it, confirm it works, then delete the old key.

**If a key may have leaked,** create its replacement and delete the leaked key right away rather than waiting out an overlap. Deletion takes effect within 60 seconds on every host, and open event and media WebSockets that used the key are closed.

**Certificate keys:** certificates last 365 days. Keep the key and get a new certificate with [`renewApiTokenCert`](https://developer.rhombus.com/authentication/api-keys#renew-a-certificate), or rotate the key with a new CSR to replace both.

## OAuth tokens

- **Access tokens last one hour.** Refresh with the refresh token at `https://auth-web.rhombussystems.com/oauth/token` (`grant_type=refresh_token`). Confidential clients send their client ID and secret; public clients (PKCE only, `token_endpoint_auth_method` `none`) send only `client_id`.
- **Every refresh returns a new refresh token**, and the old one stops working, so store the new one each time. Presenting a replaced refresh token within 30 seconds is refused; after 30 seconds it revokes the whole grant, including the API keys created with it.
- **A refresh token unused for 90 days expires.** A failed refresh returns 400 `invalid_grant`; send the user through sign-in again.
- **Revoke a grant** by posting the refresh token to `https://auth-web.rhombussystems.com/oauth/token/revoke` (form-encoded `token` and `client_id`, plus `client_secret` for confidential clients). Its access tokens stop working within 60 seconds, the API keys the app created with it are deleted, and federated tokens minted with it stop working. Deleting an OAuth app revokes all of its grants.

EU organizations use `auth-web.eu.rhombussystems.com`. See [Sign in with Rhombus](https://developer.rhombus.com/oauth-authentication).

## Federated tokens

Federated tokens end when their `durationSec` runs out: one hour by default, at most 24 hours. A token stops working sooner when you revoke it with `POST /api/org/revokeFederatedSessionToken`, or when the credential that minted it is revoked: the API key deleted, the OAuth grant revoked, or the mobile app session ended. Keep them short and device-scoped ([Federated tokens](https://developer.rhombus.com/authentication/federated-tokens)).

## Audit trail

Actions taken with an API key (changes, unlocks, exports) are recorded in the organization's audit log under the key's name, shown as `API - <key name>`. Partner actions are recorded in the client organization. Read it in the console, or with [`getAuditFeed`](https://developer.rhombus.com/api-reference/report-webservice/get-audit-feed) (the key needs permission to view reports).
