Skip to content
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

Changes to support WebAuthn Get and Create #93

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
306 changes: 297 additions & 9 deletions draft-parecki-oauth-first-party-apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ normative:
name: "National Institute of Standards and Technology"
date: August 2015
target: http://dx.doi.org/10.6028/NIST.FIPS.180-4
WEBAUTHN-3:
target: https://www.w3.org/TR/webauthn-3/
title: Web Authentication Level 3
date: 2023-09-27
author:

informative:
RFC6750:
Expand Down Expand Up @@ -206,7 +211,7 @@ Figure: First-Party Client Authorization Code Request
- (A) The first-party client starts the flow, by presenting the user with a "sign in" button, or collecting information from the user, such as their email address or username.
- (B) The client initiates the authorization request by making a POST request to the Authorization Challenge Endpoint, optionally with information collected from the user (e.g. email or username)
- (C) The authorization server determines whether the information provided to the Authorization Challenge Endpoint is sufficient to grant authorization, and either responds with an authorization code or responds with an error. In this example, it determines that additional information is needed and responds with an error. The error may contain additional information to guide the Client on what information to collect next. This pattern of collecting information, submitting it to the Authorization Challenge Endpoint and then receiving an error or authorization code may repeat several times.
- (D) The client gathers additional information (e.g. signed passkey challenge, or one-time code from email) and makes a POST request to the Authorization Challenge Endpoint.
- (D) The client gathers additional information (e.g. WebAuthn response, or one-time code from email) and makes a POST request to the Authorization Challenge Endpoint.
- (E) The Authorization Challenge Endpoint returns an authorization code.
- (F) The client sends the authorization code received in step (E) to obtain a token from the Token Endpoint.
- (G) The Authorization Server returns an Access Token from the Token Endpoint.
Expand Down Expand Up @@ -239,9 +244,9 @@ important to note that some extension parameters have meaning in a web context b
mechanism (e.g. `response_mode=query`). It is out of scope as to what the AS does in the case that an extension
defines a parameter that has no meaning in this use case.

The client initiates the authorization flow with or without information collected from the user (e.g. a signed passkey challenge or MFA code).
The client initiates the authorization flow with or without information collected from the user (e.g. a WebAuthn response or MFA code).

The authorization challenge endpoint response is either an authorization code or an error code, and may also contain an `auth_session` which the client uses on subsequent requests to the authorization challenge endpoint.
The authorization challenge endpoint response is either an authorization code, a set of WebAuthn parameters, or an error code, and may also contain an `auth_session` which the client uses on subsequent requests to the authorization challenge endpoint.


## Token endpoint
Expand Down Expand Up @@ -284,6 +289,15 @@ format with a character encoding of UTF-8 in the HTTP request body:
: OPTIONAL. The code challenge method as defined by {{RFC7636}}.
See {{redirect-to-web}} for details.

"authn_params_type":
: OPTIONAL. The string `public-key` to request a set of parameters for a WebAuthn request.

"authn_params_op:
: OPTIONAL. The string `get` to request a set of parameters for a WebAuthn assertion request or the string `create` for a WebAuthn credential creation request.

"authn_response":
: OPTIONAL. A JSON string containing the Base64URL encoded JSON object containing the properties defined in {{webauthn-response}}

Specific implementations as well as extensions to this specification MAY define additional parameters to be used at this endpoint.

For example, the client makes the following request to initiate a flow
Expand All @@ -296,6 +310,130 @@ given the user's phone number, line breaks shown for illustration purposes only:
login_hint=%2B1-310-123-4567&scope=profile
&client_id=bb16c14c73415

In another example, the client sends the response of successful WebAuthn authentication ceremony:

POST /authorize HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

authn_response=eyJ0eXBlIjoicHVibGljLWtleSIsImlkIjoiSlZfYkYzdzhaSndkM200R2FxcHhabmVlN2p1T0g4X1NRcGdUTWF4R3VEMCIsInJhd0lkIjoiSlZfYkYzdzhaSndkM200R2FxcHhabmVlN2p1T0g4X1NRcGdUTWF4R3VEMCIsImF1dGhlbnRpY2F0b3JBdHRhY2htZW50IjoicGxhdGZvcm0iLCJyZXNwb25zZSI6eyJjbGllbnREYXRhSlNPTiI6ImV5SjBlWEJsSWpvaWQyVmlZWFYwYUc0dVoyVjBJaXdpWTJoaGJHeGxibWRsSWpvaU1VNXRZa2g0U0djeVRIZHBNWE5vV1RWS1YySlZXSEpIV0VkTWJsOXdhbVEzVEd4R1pEVlZRMDFuV1NJc0ltOXlhV2RwYmlJNklDSm9kSFJ3Y3pvdkwyeHZaMmx1TG1WNFlXMXdiR1V1WTI5dElpd2lZM0p2YzNOUGNtbG5hVzRpT2lCbVlXeHpaWDAiLCJhdXRoZW50aWNhdG9yRGF0YSI6Ikl0ZUVLOUIta1pGSkUtdG1lUUUwZlRiOU5Ub0V0LV9QZVhxU3EwdGxWTmNGQUFBQUFBIiwic2lnbmF0dXJlIjoiTUVVQ0lCYWVSVk9FYllzQ2xyQmljZHU4Y2ltSnI5OXl3NVVseURyRUFJSnotQkxZQWlFQThyVkt1MlNQQ2FNbTJoMEdBS2U1QzFZS1ZQWUtISk5xY1VKOERoWG16eTAiLCJ1c2VySGFuZGxlIjoiWjRLaGhQWnZUVy1Wdl8zcFJFNEo2dyJ9LCJjbGllbnRFeHRlbnNpb25SZXN1bHRzIjp7fX0

### WebAuthn Response {#webauthn-response}

#### WebAuthn Authentication Response

The response for a WebAuthn authentication request (`authn_params_op` === `get`):

"id":
: REQUIRED. A JSON string representing the credential identifier as defined in {{WEBAUTHN-3}}.

"rawId":
: REQUIRED. A JSON string representing the credential identifier as defined in {{WEBAUTHN-3}}.

"type":
: REQUIRED. A JSON string with value `public-key`.

"response":
: REQUIRED. A JSON object with the properties defined below:

"clientDataJSON":
: REQUIRED. A JSON string as defined in `AuthenticatorAssertionResponseJSON` in {{WEBAUTHN-3}}.

"authenticatorData":
: REQUIRED. A JSON string as defined in `AuthenticatorAssertionResponseJSON` in {{WEBAUTHN-3}}.

"signature":
: REQUIRED. A JSON string as defined in `AuthenticatorAssertionResponseJSON` in {{WEBAUTHN-3}}.

"userHandle":
: OPTIONAL. A JSON string as defined in `AuthenticatorAssertionResponseJSON` in {{WEBAUTHN-3}}.

"authenticatorAttachment":
: OPTIONAL. A JSON string representing the authenticator attachment modality as defined in {{WEBAUTHN-3}}.

"clientExtensionResults":
: OPTIONAL. A JSON object containing extension outputs from the client as defined in {{WEBAUTHN-3}}.

~~~ json
{
"id": "o89r9ablrfK5tqkYWJLWLn4rghP71MPFAqHT1fX9Z4M",
"rawId": "o89r9ablrfK5tqkYWJLWLn4rghP71MPFAqHT1fX9Z4M",
"response": {
"authenticatorData": "dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvAFAAAAAA",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiTGU5N1hRMkt0dnlWb1JGaHktdVlsSVVXSlZrYU52LWlMc0I1N2FIXzN2Sm5NLUYyS3VCVndiNEhJMVJhNlgxS2ZjMFl6dTRGX0lFZHFjY0trUG1KLWciLCJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLmlvIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ",
"signature": "MEQCIELsUAUCOzh6cyispFGrN4pwTXEasQyVJ0UAW7opF0OUAiADR7qg-QIQpZerXEez9JTBY53ssNmkUYhlDyC6eHI1uA",
"userHandle": "LX8WlTwNobR7h16Jse6eOzzAXroGbEyVtt7MtKL6LKM"
},
"type": "public-key",
"clientExtensionResults": {},
"authenticatorAttachment": "platform"
}
~~~

#### WebAuthn Registration Response

The response for a WebAuthn credential creation request (`authn_params_op` === `create`):

"id":
: REQUIRED. A JSON string representing the credential identifier as defined in {{WEBAUTHN-3}}.

"rawId":
: REQUIRED. A JSON string representing the credential identifier as defined in {{WEBAUTHN-3}}.

"type":
: REQUIRED. A JSON string with value `public-key`.

"response":
: REQUIRED. A JSON object with the properties defined below:

"clientDataJSON":
: REQUIRED. A JSON string as defined in `AuthenticatorAttestationResponseJSON` in {{WEBAUTHN-3}}.

"authenticatorData":
: REQUIRED. A JSON string as defined in `AuthenticatorAttestationResponseJSON` in {{WEBAUTHN-3}}.

"transports":
: REQUIRED. A JSON array as defined in `AuthenticatorAttestationResponseJSON` in {{WEBAUTHN-3}}.

"publicKey":
: OPTIONAL. A JSON string as defined in `AuthenticatorAttestationResponseJSON` in {{WEBAUTHN-3}}.

"publicKeyAlgorithm":
: REQUIRED. A JSON number as defined in `AuthenticatorAttestationResponseJSON` in {{WEBAUTHN-3}}.

"attestationObject":
: REQUIRED. A JSON string as defined in `AuthenticatorAttestationResponseJSON` in {{WEBAUTHN-3}}.

"authenticatorAttachment":
: OPTIONAL. A JSON string representing the authenticator attachment modality as defined in {{WEBAUTHN-3}}.

"clientExtensionResults":
: OPTIONAL. A JSON object containing extension outputs from the client as defined in {{WEBAUTHN-3}}.

~~~ json
{
"id": "o89r9ablrfK5tqkYWJLWLn4rghP71MPFAqHT1fX9Z4M",
"rawId": "o89r9ablrfK5tqkYWJLWLn4rghP71MPFAqHT1fX9Z4M",
"response": {
"attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVikdKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBFAAAAAK3OAAI1vMYKZIsLJfHwVQMAIKPPa_Wm5a3yubapGFiS1i5-K4IT-9TDxQKh09X1_WeDpQECAyYgASFYILwr3RftOeZOgl2LfFcEe35EVCkTXPZFznwbM9Nl48eqIlggnrHqnnq_hidd3iZMbyYfiKRcWCVW0u2pqjQ0MOrTTik",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoieFBHNnNzS2VZZld1VGQ5ZTNzZkVaa0xIdlRzaWRkUS1MdjhNZzROTURuajV2aFNoeVdNRjk2ZWxqal9ET21sY1ZCX0gxdG9CZ2xMR3hIcXdISW1RY3ciLCJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLmlvIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ",
"transports": [
"internal"
],
"publicKeyAlgorithm": -7,
"publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvCvdF-055k6CXYt8VwR7fkRUKRNc9kXOfBsz02Xjx6qeseqeer-GJ13eJkxvJh-IpFxYJVbS7amqNDQw6tNOKQ",
"authenticatorData": "dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvBFAAAAAK3OAAI1vMYKZIsLJfHwVQMAIKPPa_Wm5a3yubapGFiS1i5-K4IT-9TDxQKh09X1_WeDpQECAyYgASFYILwr3RftOeZOgl2LfFcEe35EVCkTXPZFznwbM9Nl48eqIlggnrHqnnq_hidd3iZMbyYfiKRcWCVW0u2pqjQ0MOrTTik"
},
"type": "public-key",
"clientExtensionResults": {
"credProps": {
"rk": true
}
},
"authenticatorAttachment": "platform"
}
~~~

## Authorization Challenge Response {#challenge-response}

The authorization server determines whether the information provided up to this point is sufficient to issue an authorization code, and if so responds with an authorization code. If the information is not sufficient for issuing an authorization code, then the authorization server MUST respond with an error response.
Expand All @@ -320,6 +458,142 @@ For example,
"authorization_code": "uY29tL2F1dGhlbnRpY"
}

### WebAuthn Parameters Responses

#### WebAuthn Authentication Parameters Response

The authorization server generates and returns the public key credential request options for a WebAuthn authentication ceremony by creating an HTTP response content using the `application/json` media type as defined by {{RFC8259}} with the following properties and an HTTP 200 (OK) status code:

< TODO: add note that some are optional in the response but required in the WebAuthn API as some may be derived client side, represent PublicKeyCredentialRequestOptions>

"authn_params_public_key_get":
: REQUIRED. A JSON object with one or more properties defined below.

"challenge":
: REQUIRED. A JSON string <>

"timeout":
: OPTIONAL. A JSON number represnting the timeout value as defined in {{WEBAUTHN-3}}.

"rpId":
: OPTIONAL. A JSON string representing the WebAuthn Relying Party Identifier as defined in {{WEBAUTHN-3}}.

"allowCredentials":
: OPTIONAL. A JSON array of allowed WebAuthn credential IDs for the request as defined in {{WEBAUTHN-3}}.

"userVerification":
: OPTIONAL. A JSON string representing the desired user verification mode as defined in {{WEBAUTHN-3}}.

"extensions":
: OPTIONAL, A JSON object with one or more extensions as defined in {{WEBAUTHN-3}}.


~~~ http
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
"authn_params_public_key": {
"challenge": "e7kFIsthAIve4isZgTpAclt9dWVYKkl3fNm5xABJQhM",
"timeout": 60000,
"rpId": "login.example.com",
"allowCredentials": [
{
"id": "3qrxsBJngNp1__J-Y8Lw-y8JanKzsxpr170jreoLcc4",
"type": "public-key",
"transports": [
"internal"
]
}
],
"userVerification": "preferred"
}
}
~~~

#### WebAuthn Registration Parameters Response

The authorization server generates and returns the public key credential request options for a WebAuthn registration ceremony by creating an HTTP response content using the `application/json` media type as defined by {{RFC8259}} with the following properties and an HTTP 200 (OK) status code:

< TODO: add note that some are optional in the response but required in the WebAuthn API as some may be derived client side, represent PublicKeyCredentialCreationOptions>

"authn_params_public_key_create":
: REQUIRED. A JSON object with one or more properties defined below.

"challenge":
: REQUIRED. A JSON string <>

"timeout":
: OPTIONAL. A JSON number representing the timeout value as defined in {{WEBAUTHN-3}}.

"rp":
: OPTIONAL, A JSON object representing the Relying Party attributes as defined in `PublicKeyCredentialRpEntity` in {{WEBAUTHN-3}}.

"user":
: OPTIONAL, A JSON object representing the user account that the credential is associated with as defined in `PublicKeyCredentialEntity` in {{WEBAUTHN-3}}.

"pubKeyCredParams":
: OPTIONAL, a JSON array representing the public key parameters as defined in `PublicKeyCredentialParameters` in {{WEBAUTHN-3}}.

"excludeCredentials":
: OPTIONAL, a JSON array representing the excluded credentials list as defined in {{WEBAUTHN-3}}.

"authenticatorSelection":
: OPTIONAL, a JSON object representing the authenticator selection options as defined in `AuthenticatorSelectionCriteria` in {{WEBAUTHN-3}}.

"attestation":
: OPTIONAL. A JSON string representing the attestation conveyance as defined in `AttestationConveyancePreference` in {{WEBAUTHN-3}}.

"hints":
: OPTIONAL. A JSON array representing client hints for interacting with the user as defined in `PublicKeyCredentialHints` in {{WEBAUTHN-3}}.

"extensions":
: OPTIONAL, A JSON object with one or more extensions as defined in {{WEBAUTHN-3}}.

~~~ http
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store

{
"authn_params_public_key_create": {
"rp": {
"name": "WebAuthn.io Demo",
"id": "webauthn.io"
},
"user": {
"id": "LX8WlTwNobR7h16Jse6eOzzAXroGbEyVtt7MtKL6LKM",
"name": "ietf-example",
"displayName": "ietf-example"
},
"challenge": "xPG6ssKeYfWuTd9e3sfEZkLHvTsiddQ-Lv8Mg4NMDnj5vhShyWMF96eljj_DOmlcVB_H1toBglLGxHqwHImQcw",
"pubKeyCredParams": [
{
"type": "public-key",
"alg": -7
},
{
"type": "public-key",
"alg": -257
}
],
"timeout": 60000,
"excludeCredentials": [],
"authenticatorSelection": {
"residentKey": "required",
"requireResidentKey": true,
"userVerification": "preferred"
},
"attestation": "none",
"hints": [],
"extensions": {
"credProps": true
}
}
}
~~~

### Error Response {#challenge-error-response}

If the request contains invalid parameters or incorrect data,
Expand Down Expand Up @@ -687,16 +961,30 @@ IANA has (TBD) registered the following values in the IANA "OAuth Authorization

This section provides non-normative examples of how this specification may be used to support specific use cases.

## Passkey
## Passkeys (autofill)

A user may log in with a passkey (without a username or password).

* The Client sends an Authorization Challenge Request ({{challenge-request}}) to the Authorization Challenge Endpoint ({{authorization-challenge-endpoint}}) including the `authn_params_type=public-key` paramaeter
* The Authorization Server generates the appropriate WebAuthn parameters for an authentication ceremony and returns them in the response.
* The Client calls the platform's native WebAuthn APIs.
* The platform interacts with the authenticator, optionally requests user verification, and signs the WebAuthn challenge.
* The Client base64url encodes the JSON object containing the WebAuthn response and sends it to the Authorization Challenge Endpoint ({{authorization-challenge-endpoint}}) using the `authn_response` parameter.
* The Authorization Server validates the WebAuthn response and returns an Authorization Code.
* The Client requests an Access Token and Refresh Token by issuing a Token Request ({{token-request}}) to the Token Endpoint.
* The Authorization Server verifies the Authorization Code and issues the requested tokens.

## Passkeys (username first)

A user may log in with a passkey (without a password).

* The Client collects the username from the user.
* The Client sends an Authorization Challenge Request ({{challenge-request}}) to the Authorization Challenge Endpoint ({{authorization-challenge-endpoint}}) including the username.
* The Authorization Server verifies the username and returns a challenge
* The Client signs the challenge using the platform authenticator, which results in the user being prompted for verification with biometrics or a PIN.
* The Client sends the signed challenge, username, and credential ID to the Authorization Challenge Endpoint ({{authorization-challenge-endpoint}}).
* The Authorization Server verifies the signed challenge and returns an Authorization Code.
* The Client sends an Authorization Challenge Request ({{challenge-request}}) to the Authorization Challenge Endpoint ({{authorization-challenge-endpoint}}) including the username and the `authn_params_type=public-key` paramaeter.
* The Authorization Server looks up the username, generates the appropriate WebAuthn parameters for an authentication ceremony, and returns them in the response.
* The Client calls the platform's native WebAuthn APIs.
* The platform interacts with the authenticator, optionally requests user verification, and signs the WebAuthn challenge.
* The Client base64url encodes the JSON object containing the WebAuthn response and sends it to the Authorization Challenge Endpoint ({{authorization-challenge-endpoint}}) using the `authn_response` parameter.
* The Authorization Server validates the WebAuthn response and returns an Authorization Code.
* The Client requests an Access Token and Refresh Token by issuing a Token Request ({{token-request}}) to the Token Endpoint.
* The Authorization Server verifies the Authorization Code and issues the requested tokens.

Expand Down
Loading