Sake.Auth.DeviceVerification (Sake v0.4.3)

Copy Markdown View Source

The device verification page (RFC 8628 §3.3), at {oauth_path}/device: where a person enters the user code a CLI or a device shows them, then approves or denies its request on the consent page. Mount it, like Sake.Auth.Authorize, inside the pipeline that requires a signed-in person; Sake reads the person through Sake.Auth.Subject. It answers 404 without device: in the auth config.

GET shows the code entry form (Sake.Auth.Consent.render_user_code/1), prefilled from verification_uri_complete's user_code; nothing is looked up until the person submits it. A posted code shows the consent page, with the code on it to compare with the device's. A code that is unknown, expired or already decided is refused with the same message, and each signed-in person may enter five codes a minute, which is what keeps the eight characters of a user code out of reach of guessing. The consent page shows even when the person approved the client before: whoever started the request may have sent the code to someone else to approve.

Both forms carry a signed blob bound to the signed-in person, which expires after ten minutes, and the host's CSRF token when its pipeline runs Plug.CSRFProtection, as Sake.Auth.Authorize's form does. The pages refuse to be framed.

A device request may say how the person must have signed in (RFC 9470: acr_values, max_age). Once the person submits its code, a sign-in that does not meet it (by the subject module's authentication/1) is sent to reauthenticate/2, with the conn's query string set to the code (user_code=...), so that coming back to request_path?query_string shows the form with the code filled in; the grant stays pending meanwhile. The approval records the acr and auth_time of the person's sign-in, which the tokens carry.