Three-legged authorization (User-Client-Server)
In order for the end user (PSU) to authorize the TPP's requested PSD2 action (i.e. consent, payment or confirmation of funds) we use OpenID Connect Authorization Code Flow (see pseudo code example below).
Authorization Code Grant Flow
Whether the TPP needs to set up a PSD2 payment/CoF or a PSD2 consent, the initial flow is fairly similar.
Provided that a valid 2-legged access token with the relevant scope has already been obtained, the TPP will start the flow by calling the initiation endpoint on either the payment/CoF or account/consent product API (using mutual TLS and the 2-legged access token as authorization).
Furthermore, on all calls to any of the product APIs, the secret API key that was issued during TPP registration must be added in an 'x-api-key' header (as well as 'X-Request-ID' and any other requirements listed in the Berlin Group Specification).
After calling the initiation endpoint, the TPP will receive a JSON reply with a consentId (or a paymentId/CoF id) and a number of links including the API endpoint for initiating an actual authorization, stored in the JSON reply in "_link" - "startAuthorisation" (the relevant consent/payment/CoF id will be an integral part of this path).
The TPP can now initiate an authorization (that will involve Strong Customer Authentication by the PSU) by calling the supplied 'startAuthorization' endpoint path on the consent (or payment) product API. The response from the authorization initiation call will include the full URI to the OAuth configuration (stored in the JSON reply in "_links" - "scaOAuth") where a .well-known JSON discovery document can be fetched with a simple GET (see two-legged authentication above for details) and the authorization URI can be extracted (as Wellknown["authorization_endpoint"]).
(It should be noted that the first two calls in the flow might seem overly complex, but this design allows for multiple authorizations to be created based on the same consent/payment - which could be relevant in certain cases, for example when an authorization from several people is needed to perform a payment from a shared company account).
The TPP is now ready to start the Strong Customer Authentication by redirecting the PSU's user agent (browser) to the extracted authorization endpoint, including various parameters such as a state and codeChallenge (details in pseudo code below). The redirect must also include the 2-legged access token, a scope specified as "ais:<consentId>" (or "pis:<paymentId>" for a payment, "piis:<CoFId>" for a confirmation of funds) and the TPP's (pre-registered) redirect URI that will be called when the authorization completes.
Please note that the Berlin Group sets up some requirements for some of the optional choices in the OAuth flow. In version 1.3 of the implementation guide(navigate to 'archive' and publication date 2018-10-19), chapter 13 describes these requirements (for example, we require "S256" rather than "plain" for the PKCE code challenge, as outlined in the code example below). Here you will also find information on the structure of code_challenge & code_verifier.
Assuming that a consentId has already been fetched, an authorization has then been initiated, and wellknown_json has been fetched from the URI returned in "_link.scaOAuth" in the reply (all as described above), then the OAuth flow seen from a TPP's perspective can be expressed (in pseudo code) as follows:
What happens next is basically a black box to the TPP. The PSU's user agent will enter a flow directly with the authorization endpoint, where the end-user, in any number of steps, will be authenticated and authorize the operation requested by the TPP. Only after the end user has accepted or rejected the request, you will receive a call to the redirect URI you provided.
If the request was accepted, the request handler can find the authorization code and state in the query parameters.
Ultimately, the TPP will then use the authorization code to complete the OAuth authorization code flow and obtain a 3-legged access token. Note that the verifier used to create the code_challenge in the original redirect call is now sent to the token endpoint (under mutualTLS):
The response from the token endpoint will include the 3-legged access token that can be used to carry out the PSD2 operation that the PSU authorized - e.g. perform a number of recurring account information requests.
Optionally, the response may also include a refresh token that can be used to obtain a new 3-legged access token if the old one is (or is about to be) expired.