07 Registering Devices
This chapter documents device registration for CLI signing operations.
7.1 Prerequisites
| Requirement | Lab | Staging | Production |
|---|---|---|---|
sshteam CLI installed and executable |
Required | Required | Required |
| Browser access for device approval | Required | Required | Required |
| User account with valid team access | Required | Required | Required |
| Trusted TLS certificate path to server | Optional | Recommended | Required |
| Device naming convention for inventory | Optional | Recommended | Required |
7.2 Device Authorization Protocol Overview
graph TD
A[CLI starts init with scope signing] --> B[Request device code]
B --> C[User opens verify URL in browser]
C --> D[User authenticates and approves device]
D --> E[CLI polls token endpoint]
E --> F{Approval status}
F -->|pending| E
F -->|denied or expired| G[Stop and rerun init]
F -->|approved| H[Issue DPoP-bound access and refresh tokens]
H --> I[Store device record and encrypted key material]
I --> J[Device can request certificate signing]
SSH Teams uses OAuth 2.0 Device Authorization with DPoP for CLI device registration.
Registration path for user devices:
- CLI starts device flow with
scope=signingat/oauth2/device_authorization. - User approves in browser at
/device/verify. - CLI polls
/oauth2/tokenuntil approved. - Server issues DPoP-bound access + refresh tokens and stores device record.
Key timing defaults:
- Device code lifetime: 600 seconds.
- Poll interval: 5 seconds.
- Signing access token lifetime: 24 hours.
- Signing refresh token lifetime: 30 days.
Important distinction:
scope=signingis for user CLI device registration and certificate issuance.scope=joinis used by server join scripts and is separate from user device registration.
7.3 Start Device Authorization
Run CLI initialization from the operator machine:
sshteam init https://<hostname>
Server argument note:
sshteam initaccepts either a full URL orhost[:port].- When scheme is omitted, HTTPS is assumed.
- After this device is initialized, later
sshteamcommands can omit--serverwhen the default/single server applies.
Expected CLI behavior:
Manual capture placeholders (CLI output):
- Placeholder image:
images/07-registering-devices/cli-init-device-code.png - Suggested capture moment: terminal showing
Visit: https://<hostname>/device/verify?user_code=...andWaiting for authorization...
If device approval or polling fails, use 12-troubleshooting-handbook.md#124-device-flow-failures.
7.4 Browser Verification and Approval
Open the verification URL shown by CLI in a browser.
Approval flow details:
- Navigate to
/device/verify?user_code=<code>&device_code=<code>. - If not authenticated, SSH Teams redirects to login with a
continueparameter. - After login, the
Approve Deviceform is shown. - Submit approval; SSH Teams redirects to a dedicated approved page with confirmation and recorded device details, including approver source IP and approved-at timestamp.
Screenshot automation note:
- Device verification supports screenshot mode at:
https://<hostname>/device/verify?screenshot=1
- Approved page supports screenshot mode at:
https://<hostname>/device/approved?screenshot=1
- Devices list supports screenshot mode at:
https://<hostname>/devices/screenshot?screenshot=1https://<hostname>/devices/screenshot?screenshot=1&variant=revoked
Browser approval screenshots:


7.5 Token Issuance and Refresh
After approval, CLI polls /oauth2/token with DPoP proof.
Polling states handled by CLI:
authorization_pending: continue polling.slow_down: increase poll delay.access_denied: stop; user denied approval.expired_token: stop; run init again.
On success:
- Access and refresh tokens are stored under
~/.sshteam/<serverKey>/config.json. - DPoP private key is encrypted and persisted by the device store.
- Device approval record stores approver identity, team context, source IP, and approved-at timestamp.
Refresh behavior:
- Commands such as
sshteam signauto-refresh access tokens using refresh token + DPoP proof when token is near expiry. - If refresh token is missing/expired or device was revoked, re-run
sshteam init https://<hostname>.
7.6 Viewing and Revoking Devices
Open My Devices from dashboard (/devices).
Device management behavior:
- UI loads device list from
GET /api/v1/devices. - Revoke action calls
DELETE /api/v1/devices/{deviceId}. - Revocation is immediate; the device token becomes unusable.
- Revoke is idempotent (repeating revoke does not create additional state changes).
Device inventory screenshots:


Recommended operator check:
- After revocation, run a signing command from that device and confirm token/device rejection.
7.7 Device Registration Troubleshooting
Common issues and fixes:
-
Authorization code expiredin CLI:- Re-run
sshteam init https://<hostname>and approve promptly.
- Re-run
-
Authorization was denied:- Re-run init and approve in browser.
-
CLI times out waiting for approval:
- Confirm URL was opened and approval submitted with the same
user_code.
- Confirm URL was opened and approval submitted with the same
-
invalid_dpop_proofor DPoP key mismatch:- Re-initialize device to generate a fresh key and token pair.
-
Refresh token failures (
invalid_grant, expired token):- Re-run init for that device.
-
Signing requests fail after revoke:
- Expected; device is revoked. Re-register if access is still required.