Skip to content

Configure OAuth 2.0 device flow

You’ll configure a UDS Package to use the OAuth 2.0 Device Authorization Grant so that CLI tools, automation scripts, or headless devices can obtain tokens without a browser redirect. Once configured, the application can initiate a device code flow and present users with a short code to enter on a separate device.

  • UDS Core deployed
  • UDS CLI installed
  • A UDS Package CR for the application that needs device flow

The Device Authorization Grant is designed for applications that either have no browser or cannot handle redirect-based authentication (for example, CLI tools, IoT devices, or CI/CD pipelines where a browser redirect is impractical).

This flow creates a public client — a client with no secret. Two important constraints apply to public clients in UDS Core:

  • standardFlowEnabled must be explicitly set to false — the UDS operator will reject the Package CR if it is not. Public clients in UDS Core are restricted to device flow only.
  • publicClient: true is incompatible with serviceAccountsEnabled: true
  1. Configure the Package CR for device flow

    Add an SSO client with publicClient: true, standardFlowEnabled: false, and the oauth2.device.authorization.grant.enabled attribute:

    package.yaml
    apiVersion: uds.dev/v1alpha1
    kind: Package
    metadata:
    name: fulcio
    namespace: fulcio-system
    spec:
    sso:
    - name: Sigstore Login
    clientId: sigstore
    standardFlowEnabled: false
    publicClient: true
    attributes:
    oauth2.device.authorization.grant.enabled: "true"
  2. Apply the Package CR to the cluster

    (Recommended) Include package.yaml as a manifest in your application’s Zarf package. See Packaging applications for general packaging guidance.

    Terminal window
    uds zarf package create --confirm
    uds zarf package deploy zarf-package-*.tar.zst --confirm

    Or apply the Package CR directly for quick testing:

    Terminal window
    uds zarf tools kubectl apply -f package.yaml

    The UDS Operator creates the Keycloak client in the UDS realm when the Package CR is applied.

Confirm the client was created with the correct configuration:

  1. Log in to the Keycloak admin UI (uds realm)
  2. Go to Clients and find your client ID
  3. Verify:
    • Standard flow is Off
    • OAuth 2.0 Device Authorization Grant is On (under AdvancedAdvanced Settings)

Test the device flow:

Terminal window
# Initiate device authorization (replace <domain> and <client-id> with your values)
curl -s -X POST \
"https://sso.<domain>/realms/uds/protocol/openid-connect/auth/device" \
-d "client_id=<client-id>" \
| jq .

A successful response includes a device_code, user_code, and verification_uri for the user to complete authentication on a separate browser.

Problem: Device code request returns 401 or “client not found”

Section titled “Problem: Device code request returns 401 or “client not found””

Symptoms: The device authorization endpoint returns an error when the application tries to initiate the flow.

Solution: Verify the client was created in the UDS realm (not the master realm) and that publicClient: true is set. Public clients do not require a client secret, so the request should only include the client_id.

Problem: Need device flow and browser login on the same application

Section titled “Problem: Need device flow and browser login on the same application”

Symptoms: The application needs both flows but they cannot coexist on one client.

Solution: Add two SSO clients to the Package CR — one for device flow (public, no standard flow) and one for the standard browser redirect flow (confidential, standard flow enabled):

spec:
sso:
# Browser redirect flow client
- name: My App Browser
clientId: my-app
redirectUris:
- "https://my-app.example.com/callback"
# Device flow client (separate public client)
- name: My App Device
clientId: my-app-device
standardFlowEnabled: false
publicClient: true
attributes:
oauth2.device.authorization.grant.enabled: "true"

Problem: Users can complete device flow but cannot access SSO-protected resources

Section titled “Problem: Users can complete device flow but cannot access SSO-protected resources”

Symptoms: Token obtained via device flow is rejected by SSO-protected applications.

Solution: Authservice validates tokens against a specific client. A device flow token issued to a public client will not have the correct aud claim for an SSO-protected application unless you configure an audience mapper. See Configure service account clients for an example of adding audience mappers — the same approach applies here.

These guides and concepts may be useful to explore next: