> For the complete documentation index, see [llms.txt](https://docs.fortifiedid.se/access/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fortifiedid.se/access/key-components/modules/oidc/device-authorization-flow.md).

# Device Authorization Flow

OAuth 2.0 Device Authorization Flow support in the OIDC module.

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](/access/key-components/authenticators/protocol-managers/oidc/device-authorization-flow.md).

## 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

{% hint style="info" %}
**Module name:** `OIDCModule`
{% endhint %}

{% tabs %}
{% tab title="Properties" %}

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

*\* mandatory when Device Flow is enabled for at least one relying party*
{% endtab %}

{% tab title="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
                }
            }
        ]
    }
}
```

{% endtab %}
{% endtabs %}

## 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](/access/key-components/modules/oidc/oidc-module.md)
* [Relying Party](/access/key-components/modules/oidc/relying-party.md)
* [Device Authorization Flow authenticator](/access/key-components/authenticators/protocol-managers/oidc/device-authorization-flow.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.fortifiedid.se/access/key-components/modules/oidc/device-authorization-flow.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
