-
Notifications
You must be signed in to change notification settings - Fork 431
docs: add device flow documentation #2026
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks so much, this already looks great!
left a couple of comments to bring the doc in line with our docs style guide.
content wise this looks very good - I did not test it out in practice though
as for the place of the doc and also place in the sidebar we can check what the best place is once its ready to merge. @christiannwamba is currently working on a restructure of the docs, so depending on when its ready to merge we might have a different place for it. |
Thanks for the review @vinckr. I think I applied all of the requested changes, please have another look when you can. |
da5525d
to
7acc1cb
Compare
We should probably add to the oauth2 quickstart this command chain as well, to try it out quickly:
Of course not with go run . but with the ory cli prefix. We'll need to release that then first and can then merge the docs, which also kinda makes sense as we need to release this stuff in any case before merging it as it would be confusing to users/customers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there were some merge conflicts incorrectly addressed, can you please revert all non-relevant changes for this PR?
This patch introduces the OAuth 2.0 Device Authorization Grant to Ory Hydra. The OAuth 2.0 device authorization grant is designed for Internet-connected devices that either lack a browser to perform a user-agent-based authorization or are input constrained to the extent that requiring the user to input text in order to authenticate during the authorization flow is impractical. It enables OAuth clients on such devices (like smart TVs, media consoles, digital picture frames, and printers) to obtain user authorization to access protected resources by using a user agent on a separate device. The OAuth 2.0 Device Authorization Grant may also become relevant for AI Agent authentication flows and is generally an amazing step and innovation for this project. A very special thanks goes to @nsklikas from [Canonical](https://canonical.com), @supercairos from [shadow.tech](https://shadow.tech) and @BuzzBumbleBee. For more details, please check out the documentation (ory/docs#2026) To implement this feature, you will need to implement two additional screens in your login and consent application. A reference implementation can be found [here](https://github.com/ory/hydra-login-consent-node/blob/99ca6ad544f64110706c289dda74c7c622ec3110/src/routes/device.ts). Closes #3851 Closes #3252 Closes #3230 Closes #2416
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is looking great from my POV.
some "nits" that might improve readability, feel free to include or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm 🚀
thanks so much 🫶
can you take another quick look please @aeneasr ? It looks fine to me now, but I want to make sure before we merge. |
Yes, I think this generally is good, however this feature isn't released anywhere yet - neither in network nor oel nor open source, so I think we should merge it once that's done, which is why this is blocked |
gotcha - i will apply the |
Clarified the description of user code entropy options and their implications for user entry.
Updated the description and steps for the Device Authorization Grant to clarify the process and correct terminology.
Added an image to illustrate the device authorization flow.
Added a sequence diagram to illustrate the device authorization flow using Mermaid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can also merge as is and refine this later, but the current state is still pretty basic. I added some ideas for improvements.
Later we should specifically add these sections or sub-pages:
- how to get a refresh token
- concrete use-cases and recommended configuration
capabilities. This flow is designed for smart TVs, streaming devices, IoT hardware, printers, AI agents, and other connected devices | ||
where typing credentials isn't practical. Here's how it works: the device to be authenticated displays a URL and a short code, prompting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
capabilities. This flow is designed for smart TVs, streaming devices, IoT hardware, printers, AI agents, and other connected devices | |
where typing credentials isn't practical. Here's how it works: the device to be authenticated displays a URL and a short code, prompting | |
capabilities. This flow is designed for smart TVs, streaming devices, IoT hardware, printers, remote terminal sessions, AI agents, and other connected devices | |
where typing credentials or opening a browser isn't practical or possible. Here's how it works: the device to be authenticated displays a URL and a short code, prompting |
The OAuth 2.0 Device Authorization Grant (RFC 8628) brings OAuth to devices with internet connectivity but limited input | ||
capabilities. This flow is designed for smart TVs, streaming devices, IoT hardware, printers, AI agents, and other connected devices | ||
where typing credentials isn't practical. Here's how it works: the device to be authenticated displays a URL and a short code, prompting | ||
you to open that URL on your phone or computer to authorize access. The two devices don't need to communicate directly—the authorization |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you to open that URL on your phone or computer to authorize access. The two devices don't need to communicate directly—the authorization | |
you to open that URL on your phone or computer to authorize access. After successful authorization, the device will get an access and (optionally) a refresh token. The two devices don't need to communicate directly—the authorization |
|
||
### Step 2: Display user code and verification URI | ||
|
||
The device shows the user the `user_code` and `verification_uri` it received from the authorization server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The device shows the user the `user_code` and `verification_uri` it received from the authorization server. | |
The device shows the user the `user_code` and `verification_uri` it received from the authorization server. Depending on the device, this can be in form of a URL, QR-code, acoustically, or any other form that the device can communicate with the user. |
- `device_code`: The device code returned from the authorization request | ||
- `grant_type`: This must always be `urn:ietf:params:oauth:grant-type:device_code` | ||
|
||
After the user grants permission, the authenicaton server sends an access token to the device, which is used to access the protected resource. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After the user grants permission, the authenicaton server sends an access token to the device, which is used to access the protected resource. | |
After the user grants their consent, the authentication server sends an access token to the device, which is used to access the protected resource. |
``` | ||
urls: | ||
device: | ||
verification: http://path/to/device/verification/ui | ||
success: http://path/to/device/success |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
``` | |
urls: | |
device: | |
verification: http://path/to/device/verification/ui | |
success: http://path/to/device/success | |
```yaml | |
urls: | |
device: | |
# The verification UI is where the user inputs the user-code | |
verification: http://path/to/device/verification/ui | |
# The success UI is where the user is send to after successful authorization | |
success: http://path/to/device/success |
- `high`: `user_code` is 8 characters long and consists of alphanumeric characters, excluding some ambiguous symbols | ||
- `medium`: `user_code` is 8 characters long and consists of only upper case alphabetic characters | ||
- `low`: `user_code` is 9 characters long and consists of only numberic characters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just considering whether we should make this fully configurable (length and character set). It is pretty important for the security and UX to get this right. It is suggested to only use characters that can be unambiguously displayed by the device, which can be quite limited e.g. on a 7-segment display. Potentially this even has to be configurable on a per-client level. Maybe we keep this approach as a "fallback" option and implement the fully configurable variant per-client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now added this, as it was quite trivial. The key now changed from oauth2.device_authorization.user_code_entropy
to oauth2.device_authorization.user_code.entropy_preset
. Additionally, I added oauth2.device_authorization.user_code.length
and oauth2.device_authorization.user_code.character_set
.
- `medium`: `user_code` is 8 characters long and consists of only upper case alphabetic characters | ||
- `low`: `user_code` is 9 characters long and consists of only numberic characters | ||
|
||
As users will need to manually enter the user code, the higher the entropy, the more difficult it will be for the user to enter the user code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As users will need to manually enter the user code, the higher the entropy, the more difficult it will be for the user to enter the user code. | |
It is important to strike the right balance between security and user-experience here. Higher entropy enhances security and protects against an attacker randomly guessing valid user-codes. | |
This is especially important the more concurrent device flows are being performed. | |
As users will need to manually enter the user code, the higher the entropy, the more difficult it will be for the user to enter the user code. | |
This is not of any concern when the user doesn't need to input the user-code manually, e.g. by scanning a QR-code. On the other side, ambiguous characters should be avoided (e.g. `O` and `0` on any display, or `1` and `7` on a 7-segment display). |
### Configuring user code entropy | ||
|
||
Depending on your security needs and your traffic load, you should choose the appropriate `user_code` entropy. The | ||
`oauth2.device_authorization.user_code_entropy` configuration supports 3 values: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`oauth2.device_authorization.user_code_entropy` configuration supports 3 values: | |
`oauth2.device_authorization.user_code.entropy_preset` configuration supports 3 values: |
- `high`: `user_code` is 8 characters long and consists of alphanumeric characters, excluding some ambiguous symbols | ||
- `medium`: `user_code` is 8 characters long and consists of only upper case alphabetic characters | ||
- `low`: `user_code` is 9 characters long and consists of only numberic characters | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is also possible to configure the length and character set directly: | |
```yaml | |
oauth2: | |
device_authorization: | |
user_code: | |
length: 8 | |
character_set: abcdefghijklmnopqrstuvwxyz0123456789 |
Related Issue or Design Document
Adds docs for the device flow as implemented in ory/hydra#3912.
Checklist
If this pull request addresses a security vulnerability,
I confirm that I got approval (please contact [email protected]) from the maintainers to push the changes.
Further comments
I am not sure if this is the right place to place the doc, The rest of the docs in that folder do not reference hydra configurations, but the docs in the hydra folder do not seem to document oauth2/oidc flows. Please let me know if there is a better place for it.