Device code flow¶
The way clients obtain a bearer token. It needs no client registration, no redirect URI and no client secret, which makes it suitable for CLIs, CI runners and scripts as well as applications.
1. Request a device code¶
curl -X POST https://api.taigacloud.com/v2/oauth2/device/code \
-H "Content-Type: application/json" \
-d '{"device_name": "my-ci-runner"}'
device_name is how the token will be identified later when you review or
revoke it, and must be between 5 and 100 characters.
{
"device_code": "…",
"user_code": "A1B2C3D4E5F6",
"verification_uri": "https://api.taigacloud.com/oauth2/device/verify?user_code=A1B2C3D4E5F6",
"expires_in": 600,
"interval": 5
}
2. Approve it¶
Open verification_uri in a browser and sign in. The link already carries the
user_code, so there is nothing to type — print it and let the person running
your tool click it.
You have expires_in seconds (10 minutes) to complete this before the
device code lapses and you have to start again.
3. Poll for the token¶
curl -X POST https://api.taigacloud.com/v2/oauth2/device/token \
-H "Content-Type: application/json" \
-d '{"grant_type": "device_code", "device_code": "…"}'
Poll no faster than interval seconds. Until the approval happens you get:
| Status | Meaning | What to do |
|---|---|---|
428 |
Authorization pending | Keep polling at interval. |
400 |
Invalid or expired device code | Start again from step 1. |
Once approved it returns both tokens:
{
"access_token": { "token": "…", "token_type": "bearer", "expires_in": 3600 },
"refresh_token": { "token": "…", "token_type": "bearer", "expires_in": 604800 }
}
The token is nested
Each credential is an object, and the value you send in the
Authorization header is access_token.token — not access_token. This
differs from the flat shape some OAuth libraries expect, so a generic
device-flow client may need a small adapter.
Refreshing¶
Access tokens last an hour; refresh tokens last seven days. Exchange one for a new pair at the same endpoint:
curl -X POST https://api.taigacloud.com/v2/oauth2/device/token \
-H "Content-Type: application/json" \
-d '{"grant_type": "refresh_token", "refresh_token": "…"}'
Each refresh token is single use, and using one twice is treated as a
compromise: the request fails with 401 Refresh token reuse detected. Store
the new refresh token from every response and discard the old one — a client
that retries a refresh with the token it already spent will lock itself out.
Managing issued tokens¶
Every device flow you complete registers a device against your account.
GET /v2/oauth2/registered_devices |
List devices holding tokens. |
POST /v2/oauth2/registered_devices/{deviceUUID}/revoke |
Revoke one device's tokens. |
DELETE /v2/oauth2/registered_devices/{deviceUUID} |
Remove a device. |
Revoke anything you no longer recognise, and anything belonging to a machine you have decommissioned. This is also the remedy if a token leaks — see /reference for the full parameters.
Handling tokens¶
- Treat both tokens as secrets. Anything holding one can act as you.
- Never put a token in a URL, a log line, or a source file. Use an environment variable or a secret store.
- Give each machine its own device registration, so one can be revoked without disturbing the others.