> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fluffbuzz.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Devices

# `fluffbuzz devices`

Manage device pairing requests and device-scoped tokens.

## Commands

### `fluffbuzz devices list`

List pending pairing requests and paired devices.

```
fluffbuzz devices list
fluffbuzz devices list --json
```

Pending request output shows the requested access next to the device's current
approved access when the device is already paired. This makes scope/role
upgrades explicit instead of looking like the pairing was lost.

### `fluffbuzz devices remove <deviceId>`

Remove one paired device entry.

When you are authenticated with a paired device token, non-admin callers can
remove only **their own** device entry. Removing some other device requires
`operator.admin`.

```
fluffbuzz devices remove <deviceId>
fluffbuzz devices remove <deviceId> --json
```

### `fluffbuzz devices clear --yes [--pending]`

Clear paired devices in bulk.

```
fluffbuzz devices clear --yes
fluffbuzz devices clear --yes --pending
fluffbuzz devices clear --yes --pending --json
```

### `fluffbuzz devices approve [requestId] [--latest]`

Approve a pending device pairing request by exact `requestId`. If `requestId`
is omitted or `--latest` is passed, FluffBuzz only prints the selected pending
request and exits; rerun approval with the exact request ID after verifying
the details.

Note: if a device retries pairing with changed auth details (role/scopes/public
key), FluffBuzz supersedes the previous pending entry and issues a new
`requestId`. Run `fluffbuzz devices list` right before approval to use the
current ID.

If the device is already paired and asks for broader scopes or a broader role,
FluffBuzz keeps the existing approval in place and creates a new pending upgrade
request. Review the `Requested` vs `Approved` columns in `fluffbuzz devices list`
or use `fluffbuzz devices approve --latest` to preview the exact upgrade before
approving it.

```
fluffbuzz devices approve
fluffbuzz devices approve <requestId>
fluffbuzz devices approve --latest
```

### `fluffbuzz devices reject <requestId>`

Reject a pending device pairing request.

```
fluffbuzz devices reject <requestId>
```

### `fluffbuzz devices rotate --device <id> --role <role> [--scope <scope...>]`

Rotate a device token for a specific role (optionally updating scopes).
The target role must already exist in that device's approved pairing contract;
rotation cannot mint a new unapproved role.
If you omit `--scope`, later reconnects with the stored rotated token reuse that
token's cached approved scopes. If you pass explicit `--scope` values, those
become the stored scope set for future cached-token reconnects.
Non-admin paired-device callers can rotate only their **own** device token.
Also, any explicit `--scope` values must stay within the caller session's own
operator scopes; rotation cannot mint a broader operator token than the caller
already has.

```
fluffbuzz devices rotate --device <deviceId> --role operator --scope operator.read --scope operator.write
```

Returns the new token payload as JSON.

### `fluffbuzz devices revoke --device <id> --role <role>`

Revoke a device token for a specific role.

Non-admin paired-device callers can revoke only their **own** device token.
Revoking some other device's token requires `operator.admin`.

```
fluffbuzz devices revoke --device <deviceId> --role node
```

Returns the revoke result as JSON.

## Common options

* `--url <url>`: Gateway WebSocket URL (defaults to `gateway.remote.url` when configured).
* `--token <token>`: Gateway token (if required).
* `--password <password>`: Gateway password (password auth).
* `--timeout <ms>`: RPC timeout.
* `--json`: JSON output (recommended for scripting).

Note: when you set `--url`, the CLI does not fall back to config or environment credentials.
Pass `--token` or `--password` explicitly. Missing explicit credentials is an error.

## Notes

* Token rotation returns a new token (sensitive). Treat it like a secret.
* These commands require `operator.pairing` (or `operator.admin`) scope.
* Token rotation stays inside the approved pairing role set and approved scope
  baseline for that device. A stray cached token entry does not grant a new
  rotate target.
* For paired-device token sessions, cross-device management is admin-only:
  `remove`, `rotate`, and `revoke` are self-only unless the caller has
  `operator.admin`.
* `devices clear` is intentionally gated by `--yes`.
* If pairing scope is unavailable on local loopback (and no explicit `--url` is passed), list/approve can use a local pairing fallback.
* `devices approve` requires an explicit request ID before minting tokens; omitting `requestId` or passing `--latest` only previews the newest pending request.

## Token drift recovery checklist

Use this when Control UI or other clients keep failing with `AUTH_TOKEN_MISMATCH` or `AUTH_DEVICE_TOKEN_MISMATCH`.

1. Confirm current gateway token source:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
fluffbuzz config get gateway.auth.token
```

2. List paired devices and identify the affected device id:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
fluffbuzz devices list
```

3. Rotate operator token for the affected device:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
fluffbuzz devices rotate --device <deviceId> --role operator
```

4. If rotation is not enough, remove stale pairing and approve again:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
fluffbuzz devices remove <deviceId>
fluffbuzz devices list
fluffbuzz devices approve <requestId>
```

5. Retry client connection with the current shared token/password.

Notes:

* Normal reconnect auth precedence is explicit shared token/password first, then explicit `deviceToken`, then stored device token, then bootstrap token.
* Trusted `AUTH_TOKEN_MISMATCH` recovery can temporarily send both the shared token and the stored device token together for the one bounded retry.

Related:

* [Dashboard auth troubleshooting](/web/dashboard#if-you-see-unauthorized-1008)
* [Gateway troubleshooting](/gateway/troubleshooting#dashboard-control-ui-connectivity)
