Skip to main content
The device flow lets a command-line tool authenticate a human without handling their credentials and without running a local redirect server. The tool shows a code, the human approves it in a browser, the tool polls until a token appears.
This flow lives on the platform, at api.noorle.com, and the human-facing approval page is on the Portal. It is not served by the identity boundary at auth.noorle.com — the boundary advertises only the authorization-code grant. The two issue different tokens signed with different key material.

The shape

Step 1 — request a device code

The response carries: The user-code alphabet excludes visually ambiguous characters, so a code read aloud or off a screen is unambiguous.

Step 2 — the human approves

Send them to verification_uri_complete if you can; otherwise print the plain URL and the code separately, because a code that has to be retyped is a code that gets typo’d.
Print the verification_uri the response gave you rather than a URL you hard-coded. The Portal host it points at is environment-specific, and the response is the authority on it.

Step 3 — poll for the token

The device code goes in the code field, not a device_code field. That is the shape this endpoint accepts.
While waiting, the endpoint returns HTTP 400 with {"error": "authorization_pending"}. Every terminal outcome comes back the same way — a structured 400 with an error field — including a decline: access_denied if the human rejected the request, expired_token once the ten minutes are up, or invalid_grant once the code is no longer usable. There is no separate 403 for a decline; branch on error, not on the status code. On success:
There is no refresh_token. The device-code grant is the only grant this host accepts, so nothing can redeem one — run the device flow again when the hour is up, or use an API key for unattended clients.
The session is cleaned up on success, so a device code is genuinely single-use.

What you get back

Access token. A JWT signed HS256, valid one hour. Send it as Authorization: Bearer …. Not a permission set. There is no read/write/admin scope split on Noorle. The token names the account it is good for, and authority comes from the approving user’s role and grants.
Plan for the hour. When an access token expires, run the device flow again — the human approves once more and you get a fresh token.

Using the token

The token’s issuer is stamped with the management-API host that served it, and validation checks that issuer. A token minted against one environment does not validate against another.

Storing it

The token is a bearer credential for one hour. Treat it accordingly:
  • A file with owner-only permissions, or the OS keychain.
  • Never a world-readable location, never a shell history, never a log line.
  • In a container, pass it as an environment variable rather than baking it into an image.

Security notes

The device code is the secret. Anyone holding it can poll for the token. It never goes on screen, never in a URL you display, never in a log. The user code is not a secret, but a wrong code is a code entered against someone else’s pending request. Ten minutes of validity bounds the exposure. Both codes are single-use. A successful exchange deletes the session.

Device flow or API key?

Use the device flow when a person is present and their identity should be on the record — the token carries their principal, so the audit trail names them. Use an API key when nobody is present. The device flow needs a human at a browser by construction, which an unattended job does not have.

Troubleshooting


Next: JWT Tokens — what is actually inside these tokens, and which issuer signed them.