Skip to main content

Integrating Your Application with ZITADEL using RFC 8628 OAuth 2.0 Device Authorization Flow

ZITADEL implements device authorization as per RFC 8628. This document demonstrates its use.

This documentation aims to guide you through the process of seamlessly integrating your application with ZITADEL, leveraging the capabilities of RFC 8628. ZITADEL is a powerful identity and access management (IAM) solution that provides robust authentication and authorization services for your applications. RFC 8628, also known as "OAuth 2.0 Device Authorization Grant", offers a standardized protocol for devices with limited input capabilities to obtain user authorization. By following the steps outlined here, you'll be able to empower your application with secure authentication and access control mechanisms provided by ZITADEL, ensuring a smooth and secure user experience.

What is RFC 8628?

RFC 8628, or the OAuth 2.0 Device Authorization Grant, defines a protocol for OAuth 2.0 clients that have limited input capabilities, such as devices with no browser or low-power sensors. It allows such devices to obtain user consent for authorizing access to protected resources by directing the user to a device-friendly authentication endpoint.

Why Integrate with Zitadel?

ZITADEL offers a comprehensive identity and access management solution, providing features like single sign-on (SSO), multi-factor authentication (MFA), user management, and more. By integrating your application with ZITADEL, you can leverage these powerful features to enhance the security and usability of your application without reinventing the wheel.

Getting Started

To begin integrating your application with Zitadel using RFC 8628, follow the steps outlined in this documentation. We'll walk you through the process, from setting up your application in the Zitadel console to handling user authentication and access tokens in your application code.

  1. Go to “Organization”/”Projects”.

  2. Under “Applications” click the “New” button.

    Device Authorization Flow in ZITADEL
  3. Select “Native” and enter a name for the application, and click “Continue”.

    Device Authorization Flow in ZITADEL
  4. Select “Device Code”. Click “Continue”.

    Device Authorization Flow in ZITADEL
  5. Check the details and click “Create”.

    Device Authorization Flow in ZITADEL
  6. Copy the “Client ID” and store it for later use.

    Device Authorization Flow in ZITADEL

Device Client Example

The ZITADEL OpenID Connect client and server library written for Go has a device client example, which can behave and authenticate as a device. In order to run this client, you need a recent version of Go (>=1.20) installed on your device.

The example requires two environment variables to be set:

  • ISSUER: server address of your instance or domain. You can find the issuer URL in the “URLs” section. In this example, it will be set to Do not use a trailing slash!

    Device Authorization Flow in ZITADEL
  • CLIENT_ID: the Client ID we obtained earlier.

Replace ISSUER and CLIENT_ID values with the ones you obtained and run the example as shown below:

CLIENT_ID="232685602728952637@device_auth" \
go run

You should see some info-level log output with response data and a line with login instructions as given below:

Please browse to and enter code GQWC-FWFK
INFO[0002] start polling

At this point, the device app starts polling the token endpoint at 5-second intervals until the request is allowed, denied, or times out (currently 5 minutes).


When you browse to the given URL and the device code is entered, the authentication flow for a user is started. If you are already logged in, it skips right ahead to the final screen where you can choose to allow or deny the request. If you are not logged in, you will have to enter your credentials for login.

Device Authorization Flow in ZITADEL Device Authorization Flow in ZITADEL Device Authorization Flow in ZITADEL Device Authorization Flow in ZITADEL Device Authorization Flow in ZITADEL

When “allow” is clicked, the device (the CLI in this case) will receive a token on the next poll. A log line will be shown as given below:

INFO[0165] successfully obtained token: &{Um2W5Od0yBU0KHfhP0AD0726rXrpxlepOR7yyftMvocgMWr25pVCuca1oiSSLiQjcXQqCEA Bearer  43199  }

At this point, the program terminates as it doesn’t have any other useful purpose. Regular device apps would of course use the token to consume the actual service.

Code URL

During the start of the authorization flow ,there is a log line printed with the complete response object from ZITADEL that looks like this:

resp&{dOcbPeysDhT26ZatRh9n7Q KPVZ-DJGG 300 5}

From this object, we used the verification_uri and user_code fields to print the information to the user to go to an address and enter the code. We also return a verification_uri_complete field, which already includes the code and allows skipping manual entry of the code.

In real-life applications, this could be used to create a QR code on the device screen, and users can use their mobile phones to scan the code to go to the required URL for authentication. In the context of this example, you can restart the device example program and copy/paste the complete link instead of manually entering it.

Security considerations

The user uses a low entropy code to link a device to their account, which is easy to brute-force. Also, the code or QR might be displayed in environments where others could observe and use the code to authenticate the device (hijack the session) to their account.

The device authorization grant specification was written with the philosophy that hijacking such sessions is not beneficial for the attacker. For example, with an on-demand streaming service, the attacker would be paying for the services the user is benefiting from. Hence, economically, the attack would not make sense.

See here for more information.

Client library

For Go clients, the ZITADEL OIDC repository already includes device authorization in the rp package.

Use rp.DeviceAuthorization to start the flow and receive the URL and user code. rp.DeviceAccessToken polls the token endpoint and returns the access token once it succeeds.

The client implementation is rather simple and can easily be recreated in other languages. Go can be used as an example, or simply follow the RFC as a guide.