# Device Authorization Flow

Documentation owner: product `access`; documentation version: `3.9.1`.
Source: `content/products/access/3.9.1/key-components/modules/oidc/device-authorization-flow.mdx` at commit `eaf7a020437971baeee95e87eaf963636040ac71`.

This page describes the OIDC module support for **OAuth 2.0 Device Authorization Flow**.

The user-facing verification flow is configured on the authenticator side. See [Device Authorization Flow authenticator](/products/access/key-components/authenticators/protocol-managers/oidc/device-authorization-flow/).

## About

Device Authorization Flow is useful when the relying party cannot do a normal redirect-driven browser flow, for example on:

* TV devices
* kiosks
* limited-input devices
* similar cross-device login scenarios

The relying party starts the flow through `device_authorize`, the user completes authentication through a separate verification flow, and the relying party polls the token endpoint until the result is ready.

## Endpoints

The OIDC module adds support for:

* `POST /device_authorize`
* `POST /token` with `grant_type=urn:ietf:params:oauth:grant-type:device_code`

The OIDC discovery metadata should also expose a `device_authorization_endpoint`.

## Module configuration

:::note
**Module name:** `OIDCModule`
:::

### Properties

| Name | Description | Default value | Mandatory |
| --- | --- | --- | --- |
| `device_verification_uri` | User-facing verification URI returned to the relying party in the `device_authorize` response. This must be configured when at least one RP has `device_flow.enabled=true`. | N/A | true |
| `discovery_meta.device_authorization_endpoint` | Device Authorization endpoint published in discovery metadata. | N/A | true |
| `discovery_meta.grant_types_supported` | Should include `urn:ietf:params:oauth:grant-type:device_code` when Device Flow is enabled. | N/A | true |
| `rps[].device_flow.enabled` | Enables Device Authorization Flow for the relying party. | `false` | false |
| `rps[].device_flow.interval` | Polling interval returned to the relying party. | `5` | false |
| `rps[].device_flow.device_code_ttl` | Device code time to live in seconds. | `1800` | false |

_\* mandatory when Device Flow is enabled for at least one relying party_

### Example

```json
{
    "name": "OIDCModule",
    "enabled": true,
    "config": {
        "http_context": "/oidc",
        "http_port": 8080,
        "tenant_op_path": "/tenant1",
        "device_verification_uri": "https://login.example.com/access/authn/device",
        "discovery_meta": {
            "issuer": "https://login.example.com/oidc/tenant1",
            "token_endpoint": "https://login.example.com/oidc/tenant1/token-endpoint",
            "device_authorization_endpoint": "https://login.example.com/oidc/tenant1/device_authorize",
            "jwks_uri": "https://login.example.com/oidc/tenant1/.well-known/openid-configuration/jwks",
            "grant_types_supported": [
                "authorization_code",
                "urn:ietf:params:oauth:grant-type:device_code"
            ]
        },
        "keystore": {
            "path": "/fortified_test/keystore.p12",
            "password": "secret",
            "type": "PKCS12"
        },
        "sign_jwt_keystore_password": "secret",
        "sign_jwt_keystore_alias": "jwt",
        "rps": [
            {
                "client_id": "tv-client",
                "client_secret": "secret",
                "redirect_uri": [
                    "https://www.example.com/callback"
                ],
                "device_flow": {
                    "enabled": true,
                    "interval": 5,
                    "device_code_ttl": 1800
                }
            }
        ]
    }
}
```

## device\_authorize request

Example:

```http
POST /oidc/tenant1/device_authorize
Authorization: Basic dHYtY2xpZW50OnNlY3JldA==
Content-Type: application/x-www-form-urlencoded

scope=openid
```

Equivalent `curl` request:

```bash
curl -u tv-client:secret \
  -X POST \
  -d "scope=openid" \
  https://login.example.com/oidc/tenant1/device_authorize
```

## device\_authorize response

Example:

```json
{
    "device_code": "f2d189221cda27d41b6894b0cb055261",
    "user_code": "4B15-55ED",
    "verification_uri": "https://login.example.com/access/authn/device",
    "verification_uri_complete": "https://login.example.com/access/authn/device?user_code=4B15-55ED",
    "expires_in": 1800,
    "interval": 5
}
```

## Token polling

The relying party polls the token endpoint using:

```http
POST /oidc/tenant1/token-endpoint
Authorization: Basic dHYtY2xpZW50OnNlY3JldA==
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=f2d189221cda27d41b6894b0cb055261
```

Equivalent `curl` request:

```bash
curl -u tv-client:secret \
  -X POST \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
  -d "device_code=f2d189221cda27d41b6894b0cb055261" \
  https://login.example.com/oidc/tenant1/token-endpoint
```

Possible responses include:

* `authorization_pending`
* `slow_down`
* `expired_token`
* successful token response

Example pending response:

```json
{
    "error": "authorization_pending",
    "error_description": "The end-user has not yet completed the authorization flow"
}
```

Example successful response:

```json
{
    "access_token": "...",
    "id_token": "...",
    "token_type": "Bearer",
    "expires_in": 60
}
```

## Session behavior

The implementation uses the shared Access session model for:

* device session state
* user-code lookup
* polling status
* completion cleanup

Important behavior:

* the same `user_code` can be used again while the flow is still `PENDING`
* after the first successful token response, the device-flow session state is cleaned up
* the implementation supports clustered/session-replicated environments

## Discovery metadata

When Device Flow is enabled, discovery metadata should include:

* `device_authorization_endpoint`
* the `device_code` grant in `grant_types_supported`

## Related pages

* [OIDC module](/products/access/key-components/modules/oidc/oidc-module/)
* [Relying Party](/products/access/key-components/modules/oidc/relying-party/)
* [Device Authorization Flow authenticator](/products/access/key-components/authenticators/protocol-managers/oidc/device-authorization-flow/)
