/
v3.0.1 Security Profile

v3.0.1 Security Profile

 

Version Control

Version

Date

Author

Comments

 

Version

Date

Author

Comments

 

3.0.0-draft1

May 3, 2022

Payments NZ API Working Group

Baseline

 

3.0.0-draft2

Nov 21, 2022

@Nigel Somerfield

Added refresh token introspection

 

3.0.0-draft2

Dec 15, 2022

@Nigel Somerfield

  • Updated Normative References

  • Updated Read and Write API Security Provisions

  • Added section 5.2 Authorization Code Flow - Non-Normative examples

  • Added section 6.2 Authorization Code Flow - Implementation Guide

 

3.0.0-draft2

Jan 5, 2023

@Nigel Somerfield

Updated Decoupled Flow examples

 

3.0.0-draft2

Jan 9, 2023

@Nigel Somerfield

Updated Decoupled Flow implementation guide

 

3.0.0-draft2

Jan 10, 2023

@Nigel Somerfield

Updated Hybrid Flow implementation guide

 

3.0.0-draft2

Feb 15, 2023

@Nigel Somerfield

Added supported authorisation grant types

 

3.0.0-draft2

Feb 21, 2023

@Nigel Somerfield

Updated:

  • Request Object references to include FAPI 1.0

  • Updated Request Object nbf and exp claim definitions for clarity

  • Moved the example JARM HTTP response earlier to improve readability

  • Minor wording change to reflect the CIBA ping is request to third party, not a response

Added:

  • Hybrid flow example HTTP authorisation response

 

3.0.0-draft2

Mar 1, 2023

@Nigel Somerfield

Added:

Updated:

 

3.0.0-draft2

Mar 13, 2023

@Nigel Somerfield

Removed ConsentId from JARM response token data model and examples.

 

3.0.0-draft2

Apr 4, 2023

@Nigel Somerfield

Added missing login_hint_token object (subject) definition

 

3.0.0-draft2

Apr 24, 2023

@Nigel Somerfield

Updated:

  • login_hint_token to include reference to RFC7519 registered JWT claims.

Added:

  • BCP-225 / RFC8725 as normative reference for JWT Best Current Practices

 

3.0.0-rc1

May 5, 2023

@Nigel Somerfield

Migrated:

  • Security Profile to new space as BWG guidance to separate Security Profile into its own standard

  • Security content from NZ Banking Data API to Security Profile

Updated:

 

3.0.0-rc1

Jun 16, 2023

@Nigel Somerfield

Updated:

  • ID Token description relating consent to customer. Now reads:
    ”In the NZ Open Data API context, the ID Token always identifies the consent (using ConsentId claim) that was authorised and Customer who authorised it (using the sub claim).”

  • Authorization code flow PAR request FAPI 1.0 applicability statement updated to clarify PAR is only required for authorization code flow.

 

3.0.0-rc1

Jul 21, 2023

@Nigel Somerfield

Corrected:

  • CIBA callback example HTTP request Authorization header did not use the correct client_notification_token value

 

3.0.0-rc2

Sep 12, 2023

@Nigel Somerfield

Baselined for release candidate 2

 

3.0.1

Sep 3, 2024

@Nigel Somerfield

Updated sections 7.1.2, 8.1 and 8.3. Clarify signing algorithms, certificate section and updated example keys to use x5c claim.

Jira issue addressed:
https://paymentsnz.atlassian.net/browse/ACSD-729

Patch release documentation:
https://paymentsnz.atlassian.net/wiki/spaces/PaymentsDirectionAPIStandardsDevelopment/pages/1858633729

#005 v2.1.3, V2.2.3, v2.3.3, V3.0.1

Proposed update page that has been merged:

https://paymentsnz.atlassian.net/wiki/spaces/PaymentsDirectionAPIStandardsDevelopment/pages/1822457858

 

Introduction

This document is based on the OpenID Foundation's Financial-grade API Read+Write specification FAPI-RW, which in turn is based on the Read only specification document FAPI. In addition, the Financial-grade API: Client Initiated Backchannel Authentication Profile FAPI-CB has been incorporated, to support a decoupled authentication flow. The Security Profile will further shape these profiles in some cases tightening restrictions and in others loosening requirements using keywords. Please see the introduction to FAPI-RW for a general introduction to the aims of this document.

The Security Profile outlines the differences between the FAPI-RW and FAPI-CB with clauses and provisions necessary to reduce delivery risk for API Providers.

Security Architecture

OAuth 2.0

OAuth 2.0 will be the foundational framework for API Security for the in-scope API standards. OAuth 2.0 itself is a framework which can be deployed in many ways, some of them completely incompatible with financial models. In order to securely use the OAuth 2.0 framework, a profile must exist by which both Third Parties and API Providers are certified to have correctly configured their clients and servers.

OIDC Core

The OpenID Connect Request object uses exactly the same claims object for specifying claim names, priorities, and values as OAuth 2.0. However if the Request object is used, the Claims object becomes a member in an assertion that can be signed and encrypted, allowing the API Provider to authenticate the request from the Third Party and ensure it hasn't been tampered with. The OpenID Connect Request object can either be passed as a query string parameter, or can be referenced at an endpoint that could theoretically be protected by MATLS. The use of JWT Request objects by reference is not supported due a number of delivery risks and remaining security concerns.

In addition to specifying a ticket, the Third Party can optionally require a minimum strength of authentication context or request to know how long ago the user was actually authenticated. Multiple tickets could be passed if necessary. Everything is fully specified. Vendors who implement this feature are not creating a one-off proprietary feature, they are simply supporting the OpenID Connect standard.

Full accountability is available as required by all participants. Not only can the API Provider prove that they received the original request from the Third Party, but the Third Party can prove that the access token that comes back was the token that was intended to be affiliated to this specific ConsentId.

OIDC Client Initiated Backchannel Authentication

The OIDC Client Initiated Backchannel Authentication (CIBA) profile enables a Client (Third Party) to initiate the authentication of the end-user (Customer) with the OpenID Provider (API Provider) in an out of band mechanism. This direct out of band mechanism between the Third Party and API Provider means that the Customer is not redirected to authenticate through the Customer's browser (or consumption device).

FAPI

The Financial API working group in the OpenID Foundation has created a draft standard for configuration of Financial-grade API security regimes. If any FAPI-compliant vendor can participate in the Open Data API ecosystem, it means that vendors can work to the standard and reach many customers, rather than having to create different solutions for different banking platforms. The FAPI profiles apply to both OIDC Core and OIDC CIBA profiles.

Scope

This part of the document specifies the method of

  • Applications to obtain the OAuth tokens in an appropriately secure manner for financial data access;

  • Applications to use OpenID flows to identify the Customer; and

  • Using tokens to interact with the REST endpoints that provides financial data;

This document is applicable to higher risk use cases which includes commercial and investment banking.

Normative References

The following referenced documents are strongly recommended to be used in conjunction with this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.

Terms and Definitions

For the purpose of this document, the terms defined in [FAPI ReadOnly profile] FAPI, [FAPI Read+Write profile] FAPI-RW, [OpenID Connect Core] OIDC, [OpenID Connect Client Initiated Backchannel Authentication Flow] CIBA, and [FAPI: Client Initiated Backchannel Authentication Profile] FAPI-CB apply.

Symbols and Abbreviated Terms

  • API Provider - provides APIs in a manner that complies with the API Standards (e.g. Account Information and Payment Initiation APIs), and connects those APIs with a Third Party.

  • Third Party - the entity that consumes an API in a manner that complies with the API Standards.

  • Customer - a natural or legal person that operates banking accounts.

Authorisation Scopes

To access each of the APIs, the API must be called with an access token in the HTTP Authorization header.

The scopes required with these access tokens and the grant type used to get the access token are specified in the specific API documentation.

Consent Authorisation

OAuth 2.0 scopes are coarse grained and the set of available scopes are defined at the point of client registration. There is no standard method for specifying and enforcing fine grained scopes (e.g. a scope to specify that account information should only be provided for certain time periods or to enforce payments of a specified amount on a specified date).

A consent (identified with a ConsentId) is used to define the fine-grained permissions that are granted by the Customer to the Third Party. The API specifications define a variety of consents resources such as account-access-consents and domestic-payment-consents. The act of a Customer providing authorisation of a consent with an API Provider is called consent authorisation.

Two generic consent types are used in the API specification:

  • Short lived consents - these are used for one-off access to a protected resource

  • Long lived consents - these are used for enduring access to a protected resource

Steps for consent authorisation are:

  • The Third Party requests an API Provider to create a consent (with the fine-grained permissions) using a client credentials grant.

  • The API Provider creates the consent and responds with a ConsentId.

  • The Third Party then initiates an authorisation flow (passing in the ConsentId as a parameter) where the Customer authorises the consent with the API Provider. The supported grant types for the authorisation flow are described below.

  • The API Provider issues an access token to the Third Party tied to the authorised consent and the Customer.

Token Expiry

An API Provider may issue an access token and refresh token for a long-lived consent. These tokens may expire before the consent expires. In such a situation, the state of the consent does not change and the API Provider must not modify the state of the consent.

Token Expiry Time

The expiry time for issued access tokens and refresh tokens must be deterministic for the Third Party.

In order to achieve this:

  • The API Provider must indicate the lifetime in seconds of the access token in the expires_in field of the JSON object returned by the token endpoint (see https://tools.ietf.org/html/rfc6749#section-4.2.2 ).

  • If the API Provider issues a refresh token, the API Provider must support refresh token introspection, as per the Security Profile

  • The location of the introspection endpoint is indicated in authorisation server metadata introspection_endpoint.

  • If the API Provider issues a refresh token that does not expire, the API Provider must populate refresh token introspection response claim exp with a value representing the number of seconds to 03:14:07 UTC on 19 January 2038 (end of 32-bit UNIX epoch), or a value further in the future.

Supported Grant Types

OAuth2.0 and OIDC provide support for a variety of methods for the Authorization Server to issue an access token to the Client. These methods are called Grants.

Some of these Grant Types only identify the client, but not the resource owner. It is sufficient to provide the client's identity.

On the other hand, other grant types identify the client and resource owner. The resource owner must be authenticated to issue access tokens through such a grant type.

The Security Profile supports a sub-set of these grants as well as the FAPI Profile CIBA grant.

Grant Type

Mandatory?

Grant Type

Mandatory?

Client Credentials

Mandatory

Authorization Code Flow (using PAR with PKCE and JARM)

Mandatory

Hybrid Flow

Optional

Decoupled Flow (CIBA)

Mandatory

Client Credentials Grant

Some of the APIs can be accessed using an access token issued through a Client Credentials Grant. These APIs are not restricted resources owned by the Customer and do not require Customer consent authorisation. It is sufficient to identify and authenticate the Third Party in order to call these APIs.

The Client Credentials Grant is documented in Section 4.4 of the OAuth 2.0 RFC.

Authorization Code Flow

The Authorization Code Flow (see https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth ), used with PAR, PKCE and JARM is both more secure and offers a better consumer experience than the Hybrid Flow.

The Authorization Code Flow uses Pushed Authorization Requests, aka PAR (with PKCE) to submit an authorization request for validation, before redirecting the customer. Third Parties can then redirect when an authorization request has passed technical validation with the API provider.

The JARM response removes the need for ID token to be exposed via the redirect, and as such prevents leakage of identity information. Because the JARM response is a signed-JWT, there is no requirement for detached signature, code hash or state hash.

ID Token

When an access token is generated through a Authorization Code Flow, an OIDC Authorization Server will also issue an ID Token along with the access token.

The ID Token is a signed JWT that consists of a number of claims that identify the resource owner. In the NZ Open Data API context, the ID Token always identifies the consent (using ConsentId claim) that was authorised and Customer who authorised it (using the sub claim).

As the ID Token is signed by the API Provider and bound to a specific Third Party (through the aud claim), the ID Token could be leveraged to identify the Customer in subsequent authorisation requests. OIDC caters for this by allowing the ID Token to be passed into an authorization code grant request as the id_token_hint query parameter (as documented here).

Error Condition

If the Customer does not complete a successful consent authorisation (e.g. if the Customer is not authenticated successfully), the authorization flow ends with a redirection to the Third Party with an error response as described in section 4.1.1 herehttps://openid.net/specs/openid-financial-api-jarm.html#the-jwt-response-document . The Customer is redirected to the Third Party with an error parameter indicating the error that occurred.

Hybrid Flow

The Hybrid Flow enables access to APIs that require the Customer as well as Third Party to be identified and authenticated.

The Hybrid Flow (see Section 3.3. of the OIDC Specification) provides a redirect based mechanism to redirect a Customer to the API Provider's authorisation pages in order to authenticate the Customer and generate an authorization code. The Third Party can then exchange this authorization code for an access token (and optionally refresh token) by calling the API Provider's token endpoint and authenticating itself.

The Security Profile and FAPI Read & Write API Security Profile specify a more stringent set of requirements that API Providers and Third Parties must adhere to.

ID Token

When an access token is generated through a Hybrid Flow, an OIDC Authorization Server will also issue an ID Token along with the access token.

The ID Token is a signed JWT that consists of a number of claims that identify the resource owner. In the Security Profile API context, the ID Token always identifies the consent (using ConsentId claim) that was authorised and Customer who authorised it (using the sub claim).

As the ID Token is signed by the API Provider and bound to a specific Third Party (through the aud claim), the ID Token could be leveraged to identify the Customer in subsequent authorisation requests. OIDC caters for this by allowing the ID Token to be passed into an authorization code grant request as the id_token_hint query parameter (as documented here).

Error Condition

If the Customer does not complete a successful consent authorisation (e.g. if the Customer is not authenticated successfully), the hybrid flow ends with a redirection to the Third Party with an error response as described in RFC 6749 Section 4.1.2.1. The Customer is redirected to the Third Party with an error parameter indicating the error that occurred.

Decoupled Flow (CIBA)

The CIBA flow is a decoupled authentication flow that enables access to APIs that require the Customer as well as Third Party to be identified and authenticated.

The Client Initiated Back-channel Authentication flow is part of the OpenID specifications. A FAPI Profile of the CIBA specification is available and API Providers that implement the CIBA Flow must adhere to this FAPI profile.

An API Provider must implement the CIBA Flow to allow Customers to authenticate themselves using a decoupled authentication device that may be distinct from the consumption device on which they consume the Third Party application.

The NZ Security Profile specifies a more stringent set of requirements that API Providers and Third Parties must adhere to.

An API Provider:

  • must support the id_token_hint as a method of identifying the Customer to be authenticated.

  • may support login_hint_token as a method of identifying the Customer to be authenticated.

  • must document on their developer portal, the methods of identifying a Customer that the API Provider supports.

A Third Party:

  • must pass a method of identifying the Customer in the authorisation request object using either the login_hint_token or id_token_hint (i.e., not both).

  • must create a consent with the API Provider prior to creating the CIBA authorisation request.

  • must pass the generated ConsentId as a custom claim in the authorisation request object (this allows the access token that is eventually generated to be bound to a specific consent).

If an API Provider does not support a specific method of identifying a Customer, the API Provider must return an error with the error field set to invalid_request as per https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13 .

ID Token Hint

To identify a Customer through a previously issued ID Token - the Third Party must issue an authorisation request object with an id_token_hint which contains an ID Token from a previously successful authentication event for the Customer. As this is a previously used ID Token, it is valid for a Third Party to use an expired ID Token.

Third Parties must provide either a login_hint_token or id_token_hint (i.e., not both).

Login Hint Token

The login_hint_token is a token in the CIBA authorisation request object that contains a subject_type and corresponding claim that identifies the Customer for whom authentication is being requested.

Third Parties must provide either a login_hint_token or an id_token_hint (i.e., not both).

The Security Profile and related APIs support these login_hint_token identification claims:

  • phone

  • email

  • username

  • api_provider_token

  • third_party_token

UML Diagram
Data Model

Name

Occurrence

XPath

EnhancedDefinition

Class

Codes

Name

Occurrence

XPath

EnhancedDefinition

Class

Codes

NZLoginHintToken1

 

NZLoginHintToken1

 

NZLoginHintToken1

 

subject

0..1

NZLoginHintToken1/subject

 

NZLoginHintType1

 

subject_type

1..1

NZLoginHintToken1/subject/subject_type

The type of subject identification used in the login_hint_token. The subject_type must be accompanied by the corresponding claim field. E.g., a subject_type of "phone" must be accompanied by the corresponding phone claim.

NZCIBASubject1Code

api_provider_token
email
phone
third_party_token
username

phone

0..1

NZLoginHintToken1/subject/phone

A phone number that identifies the Customer with the API Provider.

PhoneNumber

^\+[0-9]{1,3}\s?[0-9]{1,14}(\s[0-9]{1,13})?$

email

0..1

NZLoginHintToken1/subject/email

An email address that identifies the Customer with the API Provider.

Max256Text

 

username

0..1

NZLoginHintToken1/subject/username

The username that identifies the Customer with the API Provider.

Max70Text

 

api_provider_token

0..1

NZLoginHintToken1/subject/api_provider_token

A token generated by a Customer's authentication device that identifies the Customer with the API Provider. This token is passed to the Third Party.

xs:string

 

third_party_token

0..1

NZLoginHintToken1/subject/third_party_token

A token generated by a Third Party and registered with a Customer's authentication device by the Customer.

xs:string

 

Example

This is an example of a login_hint_token using the phone number as the subject_type:

{ "alg": "PS256", "kid": "GxlIiwianVqsDuushgjE0OTUxOTk" } . { "subject": { "subject_type": "phone", "phone": "+64-220466878" } } . <<signature>>

Changes to Consent Status

A Customer may revoke their consent either through the Third Party or directly through the API Provider. This only applies to long-lived consents.

  • When the Customer revokes their consent with the API Provider, the API Provider must update the consent Status as Revoked.

  • When the Customer revokes their consent with the Third Party, the Third Party must make a request to DELETE the consent using the ConsentId.

In each of the above cases, the consent states are terminal i.e., the API Provider must not allow any further state changes. The API Provider must not permit any authorisation code grants to be initiated with such a consent.

Consent Re-authorisation

Consent re-authorisation is the scenario where the API Provider requests a long-lived consent to be re-authorised (e.g., because of fraud risk). In this scenario, the Third Party reuses the existing ConsentId, and the API Provider may tailor the re-authorisation flow to be more efficient than the full consent authorisation flow.

A Third Party may request a Customer to re-authorise an existing long-lived consent that is in the Authorised state (using the existing ConsentId) at any point of time. This includes before and after the tokens bound to the consent have expired.

An API Provider must accept a request from a Third Party to re-authorise a long-lived consent (that is in the Authorised state) at any point of time. This includes before and after the tokens bound to the consent have expired.

Once a consent is re-authorised, the Third Party must not use access tokens and refresh tokens that were previously issued for the same consent.

If an API Provider issues a new access token and refresh token as a result of consent re-authorisation, it may invalidate the previously issued access tokens and refresh tokens for the same consent.

Use of Refresh Token

An API Provider may issue a refresh token along with an access token as a result of consent re-authorisation.

When an access token expires, the Third Party may attempt to get a new access and refresh token as defined in Section 6 of the OAuth 2.0 specification.

If the Third Party fails to get an access token using a refresh token, the Third Party must initiate a consent re-authorisation flow.

NZ Read and Write API Security Profile

The NZ Read and Write API Security Profile extends from [FAPI Read+Write profile] FAPI-RW.

This section identifies variations from FAPI-RW and the numbered section references where there is a variation in FAPI-RW.

Read and Write API Security Profile Variations

5.2 Read and Write API Security Provisions

5.2.1 Introduction

The Security Profile does not distinguish between the security requirements from a technical level between "read" and "write" resources. The security requirements for accessing Customer resources held at API Providers require more protection level than a basic OAuth 2.0 (RFC6749) supports.

As a profile of the OAuth 2.0 Authorization Framework, this document mandates the following to the specified APIs.

5.2.2 Authorization Server

The Authorization Server

  1. shall only support confidential clients;

  2. shall secure its token endpoint using mutually authenticated TLS;

  3. shall only support the response_type values code and code id_token;

  4. shall require the ConsentId to be passed in the authorisation request as an essential claim;

  5. shall issue an ID Token in the token response as in Section 3.1.3.3 of OIDC with its "sub" value corresponding to a Pairwise Pseudonymous Identifier (PPID) for the Customer - that uniquely identifies the Customer to the Third Party. This PPID must not be reused for another Third Party.

  6. may support refresh tokens;

  7. shall require the request object to contain an nbf claim that is no longer than 60 minutes in the past;

  8. shall require the request object to contain an exp claim that has a lifetime of no longer than 60 minutes after the nbf claim

  9. shall provide a discovery endpoint that does not require a client certificate to authenticate using a TLS certificate that should be trusted by the user agent; and

  10. shall only support private_key_jwt for client authentication

5.2.4 Confidential Client

A Confidential Client

  1. may use separate and distinct Redirect URI for each Authorization Server that it talks to; and

  2. shall accept and verify signed ID Tokens (JWS);

6. Accessing Protected Resources

6.1 Introduction

The FAPI endpoints are OAuth 2.0 protected resource endpoints that return various financial information for the resource owner associated with the submitted access token.

6.2 Access Provisions

6.2.1 Protected resources provisions

The resource server with the FAPI endpoints

  1. shall mandate mutually authenticated TLS; and

  2. shall verify that the client identifier bound to the underlying mutually authenticated TLS transport session matches the client that the access token was issued to.

6.2.2 Client Provisions

The confidential client supporting this document

  1. shall use mutually authenticated TLS;

  2. shall supply the last time the customer logged into the client as defined by FAPI clause 6.2.2.3;

  3. shall supply the customer's IP address if this data is available as defined by FAPI clause 6.2.2.4;

  4. shall supply the merchant's IP address if this data is available in the x-merchant-ip-address header, e.g., x-fapi-merchant-ip-address: 198.51.100.119; and

  5. shall supply the customer's user agent if this data is available in the x-customer-user-agent header.

7. Request Object Endpoint

7.1 Introduction

OPs:

  1. shall only support request_uri when used with PAR, and not OIDC Request Object by Reference;

  2. shall only support Request Objects passed by value as in clause 6.3 of OIDC and as per PAR.

8. Security Considerations

  1. The Message containment failure considerations in FAPI section 7.4 shall be followed.

8.5 TLS Considerations

  1. The TLS considerations in FAPI section 7.1 shall be followed; and

  2. The TLS considerations in FAPI-RW section 8.5 shall be followed.

8.6 JWS Algorithm Considerations

  1. The JWS algorithm considerations in FAPI-RW section 8.6 shall be followed.

NZ Client Initiated Backchannel Authentication Profile

The NZ Client Initiated Backchannel Authentication Profile extends from [FAPI: Client Initiated Backchannel Authentication Profile] FAPI-CB.

This section identifies variations from FAPI-CB and the numbered section references where there is a variation in FAPI-CB.

The Client Initiated Backchannel Authentication Flow [CIBA] specifies an alternate method of users granting access to their resources whereby the flow is started from a consumption device, but authorized on an authentication device.

Client Initiated Backchannel Authentication Variations

5.2 Read and Write API Security Provisions

5.2.2 Authorization Server

The Authorization Server

  1. shall require a previously staged ConsentId to be passed in the authentication request;

  2. shall not require clients to provide a request_context claim - as these fraud and threat parameters will be passed in the consent object;

  3. shall only support login_hint_token and id_token_hint; and 

  4. shall not support the user_code parameter in the authentication request.

6. Accessing Protected Resources

6.1 Introduction

The FAPI endpoints are OAuth 2.0 protected resource endpoints that return various financial information for the resource owner associated with the submitted access token.

6.2 Access Provisions

6.2.1 Protected resources provisions

The resource server with the FAPI endpoints

  1. shall mandate mutually authenticated TLS; and 

  2. shall verify that the client identifier bound to the underlying mutually authenticated TLS transport session matches the client that the access token was issued to.

6.2.2 Client Provisions

The confidential client supporting this document

  1. shall use mutually authenticated TLS;

  2. shall supply the last time the customer logged into the client as defined by FAPI clause 6.2.2.3;

  3. shall supply the customer's IP address if this data is available as defined by FAPI clause 6.2.2.4;

  4. shall supply the merchant's IP address if this data is available in the x-merchant-ip-address header, e.g., x-fapi-merchant-ip-address: 198.51.100.119; and 

  5. shall supply the customer's user agent if this data is available in the x-customer-user-agent header.

7. Security Considerations

7.9 TLS Considerations

  1. The TLS considerations in FAPI-CB section 7.9 shall be followed.

7.10 Algorithm Considerations

  1. The JWS algorithm considerations in FAPI-CB section 7.10 shall be followed.

Non-Normative Examples

Hybrid Flow

This section describes parameters that should be used with a hybrid grant flow request so that a ConsentId can be passed from the Third Party to an API Provider for minimum conformance for the NZ Read and Write API Security Profile (extending FAPI-RW). The hybrid flow is used as an optional redirect authorisation flow for the NZ Banking Data and other specified APIs.

Prior to this step, 

  1. The Third Party would have already registered a consent with an API Provider. This is achieved by creating a resource with an account information or payment consent APIs.

  2. The API Provider would have responded with a ConsentId (this is the unique identifier for the consent resource).

Authorization Request

This section describes the bare minimum set of Authorization Request parameters that an API Provider must support. The definitive reference is specified in OIDC Section 3.3.2.1 (Authentication Request) and OIDC Section 3.1.2.1 (Authentication Request)

All API Providers must support the issuance of OIDC ID Tokens, a Third Party must request that an ID Token is issued. 

This is a non-normative example of the Authorization Request:

GET /authorize? response_type=code%20id_token &client_id=Z5O3upPC88QrAjx00dis &state=zSYkfyTKWQuZOBikzsmc& &scope=openid%20payments &nonce=w8q2mp1-z0o5w3mVHf-Mlt &redirect_uri=https://thirdparty.co.nz/redirect &request=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5xTzZlOEFK WEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaS5wcm92aWRlci5jb y5ueiIsImNsYWltcyI6eyJpZF90b2tlbiI6eyJDb25zZW50SWQiOnsiZXNzZW50aWFsIjp0cnVlLCJ2Y Wx1ZSI6InVybi1hbHBoYWJhbmstaW50ZW50LTU4OTIzIn19fSwiY2xpZW50X2lkIjoiWjVPM3VwUEM4O FFyQWp4MDBkaXMiLCJleHAiOjE2NzE3NTg2NDIsImlhdCI6MTY3MTc1ODA0MiwiaXNzIjoiWjVPM3VwU EM4OFFyQWp4MDBkaXMiLCJqdGkiOiJlZTBlYTE4Yy1lMGEyLTQwODYtYTQ0Yy0xOTJjMGIzNzRmN2QiL CJuYmYiOjE2NzE3NTgwMzIsIm5vbmNlIjoidzhxMm1wMS16MG81dzNtVkhmLU1sdCIsInJlZGlyZWN0X 3VyaSI6Imh0dHBzOi8vdGhpcmRwYXJ0eS5jby5uei9yZWRpcmVjdCIsInJlc3BvbnNlX3R5cGUiOiJjb 2RlIGlkX3Rva2VuIiwic2NvcGUiOiJvcGVuaWQgcGF5bWVudHMiLCJzdGF0ZSI6InpTWWtmeVRLV1F1W k9CaWt6c21jIn0.A7iPTBmVa2Ngf2ZWMSDVUo_g0eZdE1jGv_LYksUjLANBGjbCMCptMSIj4XuW-26o1 lwtfsFIpOZ2H4gi10jVwmS9igWRKvauR2cjFooTxj4sidlH_JbSMQOZ-q2jQd7hwbiCnSGakFe5uqTiK Q8ZAzAM485YvQcGPQXxGW3OSEgIE34QeE0AOfm7t_k16jAsF0Xzr7CscYeL3jZ0QKhuFYweM1xf3v7gC 8mQZJ1MfGUrSbU4Hwq0VDNqjnF-jX1KUa_LzZ39psHUEB8xm612ikNpqVz9gFBEQ6NhH9LU_wdLAIB0_ OMCutZDkosoCTBN2IDtBuNDua65BEMwQk-4apIg2slQeEriEELbLQNM_c02gS7gh8NwWICWgyfszw72d UigoIGJCDN2rDiY21wDRUodU_N6X1w1ilNKDYKDt_PyE3a1MlaI732iQpqw1rqmc8nZM1MCBYmtKy2ZJ PbqqYdzM4CD1Tne6saavffN5mu_bopmvqoSQmK-jm8Vc1wZuf8-v4TnP6yDu_w8v_7p_DI2viv8pnZ7n nhUeDRVW1HfQCrg4ldxE06xBTwUMIYsEpg_0IUf7BR3BtJSH1cMsZ9Pq0tWIDCUylqapMR7bCAG8von8 OeqBibTmRI6H9ihPRizY5k06GJDIobSC9knqUSsoGRmfQRXWC-6kOAGuyg

Parameters

Parameter

NZ Security Profile

Notes

Parameter

NZ Security Profile

Notes

scope

Required

Third Parties must specify the scopes that are being requested.

The scope parameter must contain openid

The scopes must be a sub-set of the scopes that were registered during Client Registration with the API Provider.

response_type

Required

OAuth 2.0 requires that this parameter is provided.

Third Parties must specify "code id_token"

The values for these parameters must match those in the Request Object, if present.

client_id

Required

Third Parties must provide this value and set it to the Client Id issued to them by the API Provider to which the authorization code grant request is being made.

redirect_uri

Required

Third Parties must provide the URI to which they want the resource owner's user agent to be redirected to after authorization.

This must be a valid, absolute URL that was registered during Client Registration with the API Provider.

state

Required

Third Parties must provide a state parameter.

The parameter may be of any format and is opaque to the API Provider.

The API Provider must play back the value in the redirect to the Third Party.

The API Provider must include the s_hash in the ID Token.

nonce

Required

Third Parties must provide a nonce parameter.

Used to help mitigate against replay attacks.

The API Provider must replay the supplied nonce parameter in any ID Token response.

request

Required

The Third Party must provide a value for this parameter.

The Request Object parameter must contain a JWS that is signed by the Third Party.

The JWS payload must consist of a JSON object containing a Request Object as per OIDC Section 6.1.

Request Object

This section describes the Request Object which is used in the request Authorization Request parameter. The definitive reference is specified in OIDC Section 6.1 (Request Object). All standards and guidance MUST be followed as per the OIDC specification. Note that FAPI 1.0 Baseline and FAPI 1.0 Advanced place additional constraints on the Request Object.

As per OIDC - when the Request Object is used, the OpenID Connect Request Object values (in the JWT) supersede those which are passed using the OAuth 2.0 request query parameter syntax. 

The Request Object:

  • must contain a "claims" request parameter with the ConsentId in the "id_token" object as an essential claim

  • may contain additional "claims" to be requested if the API Provider's Authorization Server support them - these claims must be listed on the OIDC Well Known configuration endpoint.

In OIDC - the "claims" request parameter in the Request Object is used to request that specific Claims be returned in either the ID Token or at the userinfo endpoint. Hence the top level members of the "claims" request parameter are:

  • id_token

  • userinfo

The userinfo and id_token members of the claims request parameter are JSON objects with the names of the individual Claims being requested as the member names. Within an individual Claims field, the "essential" field is required to indicate whether the Claim being requested is an Essential Claim. If the value is true, this indicates that the claim is an Essential Claim.

For instance, the claim request:

"claims": { "id_token": { "ConsentId": { "essential": true, "value": "urn-alphabank-intent-58923" } } }

can be used to specify that it is essential to return the ConsentId as a claim in the ID Token.

This is a non-normative example of the Request Object JWS - without Base64 encoding:

{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "aud": "https://as.api.provider.co.nz", "claims": { "id_token": { "ConsentId": { "essential": true, "value": "urn-alphabank-intent-58923" } } }, "client_id": "Z5O3upPC88QrAjx00dis", "exp": 1671758642, "iat": 1671758042, "iss": "Z5O3upPC88QrAjx00dis", "jti": "ee0ea18c-e0a2-4086-a44c-192c0b374f7d", "nbf": 1671758032, "nonce": "w8q2mp1-z0o5w3mVHf-Mlt", "redirect_uri": "https://thirdparty.co.nz/redirect", "response_type": "code id_token", "scope": "openid payments", "state": "zSYkfyTKWQuZOBikzsmc" } . <<signature>>

Claims

Where appropriate follow the JWT Best Current Practices Guides [BCP-225] https://www.rfc-editor.org/rfc/rfc8725  

Field

NZ Security Profile

Notes

Field

NZ Security Profile

Notes

iss

Required

The iss value should be the Client Id of the Third Party, unless it was signed by a different party than the Third Party.

aud

Required

The aud value should be or include the API Provider's Issuer Identifier URL.

scope

Required

Third Parties must specify the scopes that are being requested.

The scope parameter must contain openid

The scopes must be a sub-set of the scopes that were registered during Client Registration with the API Provider.

response_type

Required

Third Parties must provide this field and set its value to 'code id_token'.

The values must match those in the request parameter.

client_id

Required

Third Parties must provide this value and set it to the Client Id issued to them by the API Provider to which the authorization code grant request is being made.

redirect_uri

Required

Third Parties must provide the URI to which they want the resource owner's user agent to be redirected to after authorization.

This must be a valid, absolute URL that was registered during Client Registration with the API Provider.

state

Required

Third Parties must provide a state parameter.

The parameter may be of any format and is opaque to the API Provider.

The API Provider must play back the value in the redirect to the Third Party.

The API Provider must include the s_hash in the ID Token.

nonce

Required

Third Parties must provide a nonce parameter.

Used to help mitigate against replay attacks. 

The API Provider must replay the supplied nonce parameter in any ID Token response.

max_age

Optional

Third Parties may provide a maximum authentication age parameter.

This specifies the allowable elapsed time in seconds since the last time the End-User was actively authenticated by the API Provider. If the elapsed time is greater than this value, the API Provider must attempt to actively re-authenticate the Customer. (The max_age request parameter corresponds to the OpenID 2.0 PAPE [OpenID.PAPE] max_auth_age request parameter.)

If the parameter is provided, the API Provider must include an auth_time Claim value in the ID Token.

claims.id_token.ConsentId

Required

Third Parties must provide a ConsentId.

The ConsentId must be the identifier for a consent resource returned by the API Provider to Third Party that is initiating the authorisation request.

exp

Required

Third Parties must provide an exp claim
The time after which the JWT must not be accepted for processing. The processing of the "expclaim requires that the current date/time MUST be before or equal to the expiry date/time listed in the exp claim.

The exp claim must be no more than 60 minutes after the nbf (not-before) claim

nbf

Required

Third Parties must provide an nbf claim
The time before which the JWT must not be accepted for processing. The processing of the "nbfclaim requires that the current date/time MUST be after or equal to the not-before date/time listed in the nbf claim.

The nbf claim must be no longer than 60 minutes in the past

iat

Optional

Third Parties may provide a time at which the Request Object was issued.

jti

Optional

Third Parties may provide a unique identifier for the token as per RFC7519.

Authorisation Response

The following is a non-normative HTTP authorization response, showing code, state and id_token parameters, as required by OIDC Core 1.0, section 3.3.2.5:

HTTP/1.1 302 Found Location: https://thirdparty.co.nz/redirect# code=g_0JnK9emAbw-LCPPAooR_Vgw0TmpmgmYz9a6qpoT0Q& state=zSYkfyTKWQuZOBikzsmc& id_token=eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BB UU53MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiI1ODkyMyIsImF1ZCI6Ilo1T zN1cFBDODhRckFqeDAwZGlzIiwiYXV0aF90aW1lIjoxNjczMjE5OTgwLCJjX2hhc2giOiJleTNCNVNfS mdDXzRVY1JDY2l6YWdBIiwiZXhwIjoxNjczMjIwNTkwLCJpYXQiOjE2NzMyMTk5OTAsImlzcyI6Imh0d HBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubnoiLCJqdGkiOiI1YTMwMTU2My04NWZhLTRjNmItOTcwMy0wZ WE1ZmVkYTAzZmQiLCJub25jZSI6Inc4cTJtcDEtejBvNXczbVZIZi1NbHQiLCJzX2hhc2giOiJRR2VsV W45S1B0VnVQakZHV1hXZm9BIiwic3ViIjoiMjNsMzRqZHNsZjkyIn0.kjIKpi9eTXz4LaSC8Ui4Nou_f C8ssTob6yqUAffRQACS1WRv1vGKdYWJNODtPg1G6h5t9T8eMnEvvzH5NhVovN-oFVaS8ZExRFycUHUY_ D-54QySGdRdvcR_6M4qKO-KKwaAxrIEwj9uj0jfW7Dg0OerladFigJ5xyuA7N27JupxRdFsgB-VlGTa0 6-KNS2_DZ5dsHnEfFuHwfmPCYlpasZUD07nvgyq74PMPyzrDCbPBS6SOxYz9Uff3Nl9Kit5QDLe7dlbp 0cSCtXPfzBe5BPTi64Wkr2OOD1t-bE2HsEKSkvWFWxPYMP9DE5_gz5jJXC4-3S6tLWbV7DjkvJD8iUip _DHEL3sGX95ELyHOCiY9BBNnPiNCPDgnsXGx2Dz2m2SpShoyq2etCZCxsDJWwjkBGwfWU_MfTLIu4r36 Ft5VXnXxA-Bz1DF6m78ImHK2EjrrHw1ZaGNqYAV42x9om0vhkn6xuUedPIYDbqOv5vysFNzWmKvQPjB_ u82w0WHNLIzP5rK4ybg7CjzDlxWgO2WEt-haMQp5EHKe-7BXlEboZwSx-EOQkGomgwoOHhorD4sMO3TV WLL4gXSY5RRuawpjGY9zqyQgYG6iDUQKBhGheRqasKuj2nwRlTfelKRyH4EKoGWa266vvDTWiO6H36mc EgSuYAdPFvs1ZRiMdQ

ID Token

This is a non-normative example of an ID Token returned - with the sub being populated with a PPID uniquely identifying the Customer to the Third Party.

"id_token":"eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BB UU53MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiI1ODkyMyIsImF1ZCI6Ilo1T zN1cFBDODhRckFqeDAwZGlzIiwiYXV0aF90aW1lIjoxNjczMjE5OTgwLCJjX2hhc2giOiJleTNCNVNfS mdDXzRVY1JDY2l6YWdBIiwiZXhwIjoxNjczMjIwNTkwLCJpYXQiOjE2NzMyMTk5OTAsImlzcyI6Imh0d HBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubnoiLCJqdGkiOiI1YTMwMTU2My04NWZhLTRjNmItOTcwMy0wZ WE1ZmVkYTAzZmQiLCJub25jZSI6Inc4cTJtcDEtejBvNXczbVZIZi1NbHQiLCJzX2hhc2giOiJRR2VsV W45S1B0VnVQakZHV1hXZm9BIiwic3ViIjoiMjNsMzRqZHNsZjkyIn0.kjIKpi9eTXz4LaSC8Ui4Nou_f C8ssTob6yqUAffRQACS1WRv1vGKdYWJNODtPg1G6h5t9T8eMnEvvzH5NhVovN-oFVaS8ZExRFycUHUY_ D-54QySGdRdvcR_6M4qKO-KKwaAxrIEwj9uj0jfW7Dg0OerladFigJ5xyuA7N27JupxRdFsgB-VlGTa0 6-KNS2_DZ5dsHnEfFuHwfmPCYlpasZUD07nvgyq74PMPyzrDCbPBS6SOxYz9Uff3Nl9Kit5QDLe7dlbp 0cSCtXPfzBe5BPTi64Wkr2OOD1t-bE2HsEKSkvWFWxPYMP9DE5_gz5jJXC4-3S6tLWbV7DjkvJD8iUip _DHEL3sGX95ELyHOCiY9BBNnPiNCPDgnsXGx2Dz2m2SpShoyq2etCZCxsDJWwjkBGwfWU_MfTLIu4r36 Ft5VXnXxA-Bz1DF6m78ImHK2EjrrHw1ZaGNqYAV42x9om0vhkn6xuUedPIYDbqOv5vysFNzWmKvQPjB_ u82w0WHNLIzP5rK4ybg7CjzDlxWgO2WEt-haMQp5EHKe-7BXlEboZwSx-EOQkGomgwoOHhorD4sMO3TV WLL4gXSY5RRuawpjGY9zqyQgYG6iDUQKBhGheRqasKuj2nwRlTfelKRyH4EKoGWa266vvDTWiO6H36mc EgSuYAdPFvs1ZRiMdQ"

Decoded ID Token JWT

{ "alg": "PS256", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY", "typ": "JWT" } . { "ConsentId": "58923", "aud": "Z5O3upPC88QrAjx00dis", "auth_time": 1673219980, "c_hash": "ey3B5S_JgC_4UcRCcizagA", "exp": 1673220590, "iat": 1673219990, "iss": "https://as.apiprovider.co.nz", "jti": "5a301563-85fa-4c6b-9703-0ea5feda03fd", "nonce": "w8q2mp1-z0o5w3mVHf-Mlt", "s_hash": "QGelUn9KPtVuPjFGWXWfoA", "sub": "23l34jdslf92" } . <<signature>>

Claims

Where appropriate please follow the JWT Best Current Practices Guides [BCP-225] https://www.rfc-editor.org/rfc/rfc8725  

Field

NZ Security Profile

Notes

Field

NZ Security Profile

Notes

aud

Required

As per FAPI-RW and OIDC.

Audience that the ID Token is intended for.

OpenID Connect protocol mandates this must include the ClientID of the Third Party's OAuth Client.

iss

Required

A JSON string that represents the issuer identifier of the authorization server as defined in RFC7519. When a pure OAuth 2.0 is used, the value is the redirection URI. When OpenID Connect is used, the value is the issuer value of the authorization server.

Issuer of the token.

Token issuer will be specific to the business.

sub

Required

 

Token subject identifier.

A Pairwise Pseudonymous Identifier (PPID) for the Customer - that uniquely identifies the Customer to the Third Party. This PPID must not be reused for another Third Party.

The sub must be the same for an ID Token created by the Authorisation and Token endpoints during the Hybrid flow. 

ConsentId

Required

The ConsentId of the originating request.

exp

Required

The validity length will be at the discretion of the API Providers as long as it does not impact the functionality of the APIs. E.g., an expiry time of 1 second is insufficient for all resource requests

Token expiration date/time.

Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519.

iat

Required

Token issuance date/time.

Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519.

auth_time

Case-Specific

The date/time the Customer was authorised.

This field must be provided when max_age is in the Authorization Request is made or max_age is included as an essential claim. In order to be compliant with the protocol we therefore need to support it.

Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519.

nonce

Required

As per FAPI-RW (Hybrid Flow), and OIDC (Hybrid Flow).

Used to help mitigate against replay attacks.

The API Provider must be replay the supplied nonce parameter (in the Authorization Request) in any ID Token response.

c_hash

Required

Code hash value.

Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the code value, where the hash algorithm used is the hash algorithm used in the alg Header Parameter of the ID Token's JOSE Header.

s_hash

Required

State hash value.

must include state hash, s_hash, in the ID Token to protect the state value - if the state value is provided in the Authorization Request.

Its value is the base64url encoding of the left-most half of the hash of the octets of the ASCII representation of the state value, where the hash algorithm used is the hash algorithm used in the alg Header Parameter of the ID Token's JOSE Header. For instance, if the alg is HS512, hash the code value with SHA-512, then take the left-most 256 bits and base64url encode them. The s_hash value is a case sensitive string.

jti

Optional

JWT Token Identifier

An API Provider may include a unique identifier in the ID token as defined in RFC7519

 

Authorization Code Flow

This section describes parameters that should be used with a authorization code flow request so that a ConsentId can be passed from the Third Party to an API Provider for minimum conformance for the NZ Read and Write API Security Profile (extending FAPI-RW). The authorization code flow is used as the redirect authorisation flow for the NZ Banking Data and other specified APIs.

Authorization Code Flow is mandatory in this version of the NZ Security Profile.

Prior to this step;

  1. The Third Party would have already registered a consent with an API Provider. This is achieved by creating a resource with an account information or payment consent APIs.

  2. The API Provider would have responded with a ConsentId (this is the unique identifier for the consent resource).

Pushed Authorization Requests (PAR) with JWT-Secured Authorization Requests & Proof-Key Code Exchange

Pushed Authorisation Requests (PAR, RFC9126) allow an OAuth 2.0 authorization request to be lodged directly with the authorization server, without the need to redirect the client. This results in better security (the OIDC authentication request object is not exposed to user-agent) and customer experience, since the client is only redirect if the authentication request is considered appropriate to proceed.

FAPI 1.0 requires PAR requests to use JAR (RFC9101) method to submit a request object JWT, which must include PKCE claims.

FAPI 1.0 supports PAR requests with hybrid flow ("response_type": "code id_token"), however this specification requires PAR only for authorization code flow ("response_type": "code").

Proof Key Code Exchange

As per FAPI 1.0, PKCE (RFC 7636) is required for PAR requests and subsequent token requests. Only S256 for code_challenge_method is supported.

Note: Section 7.1 of PKCE specifies the code_verifier should be a minimum of 256 bits, or 32 ASCII characters encoded using URL-safe base64 (total 43 characters).

PKCE code_challenge and code_challenge_method are required in the PAR request object, while the token request includes code_verifier to facilitate verification before issuing tokens.

Authentication

The PAR endpoint requires private_key_jwt for client authentication. The endpoint must use MTLS for secure transport.

PAR Request using JAR

The authentication request object is required to be specified in the request parameter, and request_uri is not supported in PAR request. Only signed JWT tokens (JWS) are supported.

The following is a non-normative PAR request:

POST /as/par HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcwMzczNzcwLCJpYXQiOjE2NzAzNzMxNzAsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiMDIwMjEzMjYtMWUxYi00ZDQzLTlhOTQtY2UyMDUwOTEwZGExIiwi bmJmIjoxNjcwMzczMTcwLCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.DJG6z0AcEWedXGnoklX x0oh8l_T2Tb7uq_GljnjLMiZkYdY4GeSSWbR1u6-xg9HZCaO8zUK1ZWD6zcjD0ndkxFH_ukReHUwaLGq vo4PzsU6nNBfWooWpoRmNqAuH-IwhYsslo0AmSIWkJbfc-CmecI4d_FXVfZ6Ib95iHm0_5YD0PLvgyAg vNMw2hxvsEZdkyc7XGdE86RlpVsZhNywDJhavbGstadFtuc5Djc4TuS-5aue1YNp56oLq722_woCOmjx KUSv_DdZHnMOlgfa5Q2LZHNgK6zOQ-v6yOjVq8bP0D_sRfyHBtG7bhI-FOO20ugMhjJFcmZOzvQMv0fu LnQ9h-djScNID1J4CuwZbVcy0b7beuh7zuc4cHj5zLlX3Vt3m89PhDlmeUMy5hYkpaV-EeeGplDJ_AA_ 8psvh6ohC0SuFfWXYmDHbXqPgIYCUwGwWE-eyjQoGeckGzJYXhZsk9noJ9iWw065s1gc5C03LGFTATlz k8UgzQ8z2LkSwGHg3Vorrj49qVq-Udhn3frOx7wbKIZ1bTlxzjarOokTluBqV6E4TtSSkIt3-zfcOX_A PFZuizsrZ8L81eckGyduzNCAKuJmTbU-Sg1cqiDQ-nuBcReKySMidJH28048PHyYMDk7-Rgj5806G_Jy YyPVFfXYMinjtzzVtHPNxDeo& client_id=Z5O3upPC88QrAjx00dis& request=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5xTzZlOEFK WEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3ZpZGVyLmNvL m56IiwiY2xhaW1zIjp7ImlkX3Rva2VuIjp7IkNvbnNlbnRJZCI6eyJlc3NlbnRpYWwiOnRydWUsInZhb HVlIjoiY29uc2VudC0xMjM0In19fSwiY2xpZW50X2lkIjoiWjVPM3VwUEM4OFFyQWp4MDBkaXMiLCJjb 2RlX2NoYWxsZW5nZSI6InJvWHN2UkMxSy01V0FZV0xXc3FRSnBYVFI4TnpuRmd5c2pqcUtocWhTTzQiL CJjb2RlX2NoYWxsZW5nZV9tZXRob2QiOiJTMjU2IiwiZXhwIjoxNjcwMzczNzc3LCJpYXQiOjE2NzAzN zMxNzcsImlzcyI6Ilo1TzN1cFBDODhRckFqeDAwZGlzIiwianRpIjoiMTIyZTFjOTUtNTJjOS00MzY5L WIxNDQtZjE3OTM0YmEzNDhmIiwibmJmIjoxNjcwMzczMTY3LCJub25jZSI6IjIzNG5hc2QtMzI0YmRzY S0zMjQiLCJyZWRpcmVjdF91cmkiOiJodHRwczovL3RoaXJkcGFydHkuY28ubnovcmVkaXJlY3QiLCJyZ XNwb25zZV9tb2RlIjoiand0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJzY29wZSI6Im9wZW5pZCBhY 2NvdW50cyBwYXltZW50cyIsInN0YXRlIjoic2FkcmV3dmRIQVNEVEFXIn0.UP-JyMa_F_5tltkPwBeig hrTVnlMFlkhKtPe-f63NgILY3SxKbj-oBDGYHZYWKfItzIrSQmNnztB82zFzkmB-v6Sn78fD9FoPG5BG CunceshfWdDjstHh_JGCpFBGlffe77nKmnTB3oQu7HUA6toYKWs0zSP5MTfe58EIFa8HmS72Q1a6dcXf K8f6reXI6_0J6GBx3EqefypNdEJku0YQer2kAlOx-6kicd66AclGI1bOR487OKfZoEDe_Ix-5PJNtHzv Ur64WGRE7qivZmvh7RjLWnpY6uYBoz4IKvc3kfYdBMRRJV892dLnEkTedJTUxIZOBFtkTsyxgmk7BnUZ r_x59IxuQCeKqANTiQxZ_60C-VQxK6lVdQ--NFggVjOdDrWxuppl4w77BkcZPjuwT4aehhZLNtnEhFsN sdlEPuJRjG3dAqo-FAozQE6PkpEOLCBhtYu6ZcGjaMf6G9oaA0Z3KhooYf1xIJ8Xa6SwR22e0z9w-4ur fWRqAnWQfTNttTowLBw4iMsrLHNnNEPrQezz3iRvcO4vSDqjVAFHPiRLhEAdkUvsSDZHBvvUkBCNWRl- MPAbt-81lzGTtGF5zuO_A867n4RPvf_KjNOO7HHkgM3gdaf4HGzQxlQC0k3meJT2a1nNByrqAF7W440v qEzkLRJycW0rcOySnuBdqo

Decoded PAR request object JWT body:

{ "aud": "https://as.apiprovider.co.nz", "claims": { "id_token": { "ConsentId": { "essential": true, "value": "consent-1234" } } }, "client_id": "Z5O3upPC88QrAjx00dis", "code_challenge": "roXsvRC1K-5WAYWLWsqQJpXTR8NznFgysjjqKhqhSO4", "code_challenge_method": "S256", "exp": 1670373777, "iat": 1670373177, "iss": "Z5O3upPC88QrAjx00dis", "jti": "122e1c95-52c9-4369-b144-f17934ba348f", "nbf": 1670373167, "nonce": "234nasd-324bdsa-324", "redirect_uri": "https://thirdparty.co.nz/redirect", "response_mode": "jwt", "response_type": "code", "scope": "openid accounts payments", "state": "sadrewvdHASDTAW" }

PAR Response

The following shows a non-normative example success response. PAR requires HTTP 201 Created for success. Both request_uri and expires_in are required.

The expires_in value is the time-to-live in seconds for the request_uri expected to be short, normally between 5 and 600 seconds and it is the API provider responsibility to set and publish values for this.

The request_uri format is at the discretion of the API provider, but must contain at least some part that is randomly generated in a cryptographically strong manner, consistent with section 10.10 of OAuth 2.0. The authorization server may choose to use the PAR-specified format of urn:ietf:params:oauth:request_uri:<reference-value>. where <reference-value> is the randomly generated part.

HTTP/1.1 201 Created Content-Type: application/json Cache-Control: no-cache, no-store { "request_uri": "urn:ietf:params:oauth:request_uri:8qi1b0XAGrV9Ypv1cMyLAS_2AIchvqXx", "expires_in": 60 }

Error Response

PAR error responses use the same format as OAuth 2.0 and related extensions.

The following is an non-normative example of and error response:

HTTP/1.1 400 Bad Request Content-Type: application/json Cache-Control: no-cache, no-store { "error": "invalid_request", "error_description": "The redirect_uri is not valid for the given client" }

PAR also defines the following additional error responses in section 2.3 of PAR:

HTTP Response Code

Description

HTTP Response Code

Description

405

If the request did not use the "POST" method, the authorization server responds with an HTTP 405 (Method Not Allowed) status code

413

If the request size was beyond the upper bound that the authorization server allows, the authorization server responds with an HTTP 413 (Payload Too Large) status code.

429

If the number of requests from a client during a particular time period exceeds the number the authorization server allows, the authorization server responds with an HTTP 429 (Too Many Requests) status code.

Authorize request with PAR

The following shows a non-normative example of an authorization request, using a request_uri previously issued through a PAR request:

GET /authorize?client_id=Z5O3upPC88QrAjx00dis&request_uri=urn%3Aietf%3Aparams %3Aoauth%3Arequest_uri%3A8qi1b0XAGrV9Ypv1cMyLAS_2AIchvqXx HTTP/1.1 Host: as.apiprovider.co.nz

Note that PAR section 4 requires authorization servers should treat request_uri as a single-use value, but may allow for duplicates to allow for user-agent reloading of the URI. An expired request_uri must be rejected as invalid.

OIDC metadata

API provider authorization servers must publish the appropriate metadata for PAR, as required by RFC9126 section 9.1.

JWT-Secured Authorization Response Mode (JARM)

FAPI 1.0

FAPI 1.0 Final specifies in section 5.2.2 the use of JARM ("response_mode":"jwt") in conjunction with "response_type": "code". The use of JARM removes the need for ID token as detached signature in the authorization response.

Signing and encryption

JARM supports both signing and encryption, however this specification requires that only signing is used (similar to ID Token as detached signature). The approved JARM signing algorithms are as per FAPI 1.0.

Example JARM response

The following is a non-normative JARM HTTP success response JWT using the previous PAR request object and subsequent authorization request:

Response Mode "jwt"

FAPI 1.0 requires "response_mode": "jwt" is used with "response_type": "code". JARM specifies response mode "jwt" in this case to be shorthand for "query.jwt", so the response to the authorisation request is in the redirect URI query parameter.

The following shows a non-normative example of the HTTP redirect using the JARM JWT above (line breaks for display only):

HTTP/1.1 302 Found Location: https://thirdparty.co.nz/redirect? response=eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BBUU5 3MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJaNU8zdXBQQzg4UXJBangwMGRpcyIsImNv ZGUiOiJnXzBKbks5ZW1BYnctTENQUEFvb1JfVmd3MFRtcG1nbVl6OWE2cXBvVDBRIiwiZXhwIjoxNjcw Mzc2Nzg5LCJpc3MiOiJodHRwczovL2FzLmFwaXByb3ZpZGVyLmNvLm56Iiwic3RhdGUiOiJzYWRyZXd2 ZEhBU0RUQVcifQ.Eb45YpgdgmRvRG3SlmiT1RHlRjGRp1c78HlCYwM4f1SSWuUPIN3ET8-8vZ0u1Wfnn g2EwKsyFSwIRYr1u3kC6iJbUYxdaunAaNhX6PfGWXoiSiaX2xpL2DZXEg01n0QN4G9nIDC3Sp4r7lACe qzTsj8uYjGc_cdUuiyIGda9xi90k-DErWR1dwui-pXNWmLiOWK4bJbf1k9hAB6ZSsOEGoOIbY3fOmJro lGbHyLDnISwrgKSqpvYlVsmYu2iwGpM5jNPe9DwtHZtk5RUAY8h91eqIa1OlBhd_JphiCY4XV-FTrQbk lFJp7LRTLbWWtw_iLt3dWWU4BMAPBpLdG0eW4Qg9Ul_vGtn49divX9Ld-cd1eJY95qVqs5yqbkJPh-Ai 6XM6Vca1LDTIdbYkD2JUhIzDSARc2tLxeMJwfumF8_tsczFwJ3hxUIeXGi8XOnieZ8aZnr6zDBLJsSuO MGpO5qU2rMrF5TPqy0Nys0U9viMAsdRM4V3wnn-kIw5tVL44fFTHiyu-H1nP7wurBjB5OMTUraQkJBAC ydXdY1yawUiWY02lG7TtgNNlF0JOJE1eqsWJVYn-FDGiXab_uQwA2r-K4gkOfW_dUlDpX6GjpJdF6fHg nUs7SdsLYa92vVdGSPD8mJ95vq7t6uHp2SASiOwmVuYA2W9xrboCc56yYw

The JARM JWT from the response parameter:

eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BBUU53MGo1aEI2 cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJaNU8zdXBQQzg4UXJBangwMGRpcyIsImNvZGUiOiJnX zBKbks5ZW1BYnctTENQUEFvb1JfVmd3MFRtcG1nbVl6OWE2cXBvVDBRIiwiZXhwIjoxNjcwMzc2Nzg5L CJpc3MiOiJodHRwczovL2FzLmFwaXByb3ZpZGVyLmNvLm56Iiwic3RhdGUiOiJzYWRyZXd2ZEhBU0RUQ VcifQ.Eb45YpgdgmRvRG3SlmiT1RHlRjGRp1c78HlCYwM4f1SSWuUPIN3ET8-8vZ0u1Wfnng2EwKsyFS wIRYr1u3kC6iJbUYxdaunAaNhX6PfGWXoiSiaX2xpL2DZXEg01n0QN4G9nIDC3Sp4r7lACeqzTsj8uYj Gc_cdUuiyIGda9xi90k-DErWR1dwui-pXNWmLiOWK4bJbf1k9hAB6ZSsOEGoOIbY3fOmJrolGbHyLDnI SwrgKSqpvYlVsmYu2iwGpM5jNPe9DwtHZtk5RUAY8h91eqIa1OlBhd_JphiCY4XV-FTrQbklFJp7LRTL bWWtw_iLt3dWWU4BMAPBpLdG0eW4Qg9Ul_vGtn49divX9Ld-cd1eJY95qVqs5yqbkJPh-Ai6XM6Vca1L DTIdbYkD2JUhIzDSARc2tLxeMJwfumF8_tsczFwJ3hxUIeXGi8XOnieZ8aZnr6zDBLJsSuOMGpO5qU2r MrF5TPqy0Nys0U9viMAsdRM4V3wnn-kIw5tVL44fFTHiyu-H1nP7wurBjB5OMTUraQkJBACydXdY1yaw UiWY02lG7TtgNNlF0JOJE1eqsWJVYn-FDGiXab_uQwA2r-K4gkOfW_dUlDpX6GjpJdF6fHgnUs7SdsLY a92vVdGSPD8mJ95vq7t6uHp2SASiOwmVuYA2W9xrboCc56yYw

Decoded JARM response JWT body:

{ "aud": "Z5O3upPC88QrAjx00dis", "code": "g_0JnK9emAbw-LCPPAooR_Vgw0TmpmgmYz9a6qpoT0Q", "exp": 1670376789, "iss": "https://as.apiprovider.co.nz", "state": "sadrewvdHASDTAW" }
JARM response claims

The JARM response is to be processed according to JARM section 4.4.

For the NZ Security Profile, the following enhanced definitions of the JARM response claims from [section 4.1.1 of JARM}(https://openid.net/specs/openid-financial-api-jarm.html#response-type-code ) are used:

Claim

NZ Security Profile

Notes

Claim

NZ Security Profile

Notes

aud

Required

Must be set to the client_id of the Third Party

code

Required

The authorization code issued by the API Provider authorization server.
The format is determined by the API Provider and is opaque to the Third Party

exp

Required

The expiration time of the JARM JWT

iss

Required

The issuer URL of the API Provider authorization server that created the response

state

Required

The state value as sent by the client in the authorization request

Error response

JARM error response is a JWT containing the error response claims defined in Oauth 2.0 RFC6749 section 4.1.2.1:

{ "error": "unauthorized_client", "state": "sadrewvdHASDTAW" }

For the NZ Security Profile, the following enhanced definitions of the JARM response claims from section 4.1.1 of JARM are used:

Claim

NZ Security Profile

Notes

Claim

NZ Security Profile

Notes

error

Required

A OAuth 2.0 error response code

error_description

Optional

A human readable description of the error

error_uri

Optional

A URI identifying a human-readable web page with information about the error

state

Required

The state value as sent by the client in the authorization request

Token request

The following non-normative example shows the token request:

POST /as/token.oauth HTTP/1.1 Host: as.apiprovider.co.nz grant_type=authorization_code& code=g_0JnK9emAbw-LCPPAooR_Vgw0TmpmgmYz9a6qpoT0Q& redirect_uri=https://thirdparty.co.nz/redirect& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcwMzc0MDk5LCJpYXQiOjE2NzAzNzM0OTksImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiYWUyM2Y4M2EtMDkyYS00OTliLWFiNDctNmZkYjcyMmQ0Y2FhIiwi bmJmIjoxNjcwMzczNDk5LCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.H9-f5ySi_RFGDArgk2d 8oXAkQ8Fhuj_Om5DBMyXiRNa-t2EF4r--tRHIx3QMiz0apgjoeyq-czL64OY4u1kKQalbVhaiUOlDZ7r lkaedsN3r1XFs54dqTF9FQdKRxGtsxbp4YMgpuynFjJfzku1AgZoSv5zYaAniWeOw6t9_cCglAZgfUbB t9KwvlQx-mYJLnE0lw1RsQwJGar25qqWZvIxjZ6c3KNBbJlZR99qVqzyc8bg1ufR_HwQwufsl3Cte-mo Sl3WTbkEznqNUcXeiEjXWWNlKFxYWU4OIAiaNECY-m27vibCU9Dc-G8s9Mkt9VqPDXDi1GYOSR1C7A47 IiBQekTfcr6ATv8ClxyUDDPnIqMqyMazRrQMxCgjgIQ3ZEddT8dfsoHfkSG9tcNGNwnYgF-Zl6FzUYrJ bqT1GfLAKgyF0y-8_jIvNM75X0lhjPy_zuKF3AFApkUoMgJ5iELtVCZWcFtMaK7YL7ZjAdxnDHUdXm_- 3hHLZba1RYeswRkGrLM4CUHj7XFjF3pjnBf1DK3TDaX5ky81poYZmMrLzq14y00ASz6_6j2TrsfqPhHJ 7_MRe62XrTHy56N4O9J53w1s7p-dZ-oqn6G0zEJDsMp7RpToCqHydbwN71pbwdeBhFbtBkyWVpJsfROO WWMVA9jGddypjpaDjUwkaQPo& client_id=Z5O3upPC88QrAjx00dis& code_verifier=z_JVTAK_E8RseRP1OjrDLq0Ch6Qq-YLoG9AGtTdL11O

Note that the code_verifier is included so the authorization server can verify the code_challenge PKCE claim supplied in the PAR request.

Decoded client assertion JWT body:

{ "aud": "https://as.apiprovider.co.nz", "exp": 1670374099, "iat": 1670373499, "iss": "Z5O3upPC88QrAjx00dis", "jti": "ae23f83a-092a-499b-ab47-6fdb722d4caa", "nbf": 1670373499, "sub": "Z5O3upPC88QrAjx00dis" }

Token response

HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "access_token": "Hqh7hobWMFq0w5aPl8nMUo5PnG2DdQTejpadkQ-4zLM", "token_type": "Bearer", "refresh_token": "nub0HLu_PM-oJxbH5UkVyQVbU-c-OZ4_gp3kiISuoCH5sCN1jXkvLoxWrvY7i239", "expires_in": 600, "id_token":"eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BB UU53MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiJjb25zZW50LTEyMzQiLCJhd WQiOiJaNU8zdXBQQzg4UXJBangwMGRpcyIsImF1dGhfdGltZSI6MTY3MTA1NTEzMSwiY19oYXNoIjoiZ XkzQjVTX0pnQ180VWNSQ2NpemFnQSIsImV4cCI6MTY3MTA1NTc0MSwiaWF0IjoxNjcxMDU1MTQxLCJpc 3MiOiJodHRwczovL2FzLmFwaXByb3ZpZGVyLmNvLm56IiwianRpIjoiYzRhMjRmZTgtYTg1MC00NmZhL TliMDAtNTQ0N2Q2NWRiMmFiIiwibm9uY2UiOiIyMzRuYXNkLTMyNGJkc2EtMzI0Iiwic19oYXNoIjoiT WRBb2lGdTdIRTNSSEVSaHUyTXNlZyIsInN1YiI6IjIzbDM0amRzbGY5MiJ9.LQMQCMvkAOVF6_nH44UI hzih2p1idWUjd2PCgD356oiNIxydDGECDYC5taSoxafz5IR6057RyyhsjSBiDdjzOoNXJZq32xGEqL4N wd5ErgZVLP9Oj2xiPRsFUzAvIhmqGAVtl6sp3mZ8ZnHon_BZp1juNF5WYC25DYqucT5gAsb3-o1RBmkc tMA-wRXkH-kOO3r4NtfJk6ex-qGc-IPRme19NBqzNghqSt_z7UAdDpTsi9gqtkyevkeneoDD8TpJUwj8 awWBQWT_zqJ4aLxpco6CVGRpSoybWWPk4zA81VCElc41UQ4ZWZ7b-XEZfT_XPS19xuLliZj2h-wjs2td 2jvz5zk1VpUjVQrcuMevdAz0M_9Wa0N1ZBuX94DRuqSF_Kch7joVe0jXvpn98gF3dnM5P-x-_YFra1_F YEYIRPfGlSXZDA9gCtoCn4sI4VDTg_4eHSnG17YQXPzZK0qD09_e4D52zFvcbCOhYZ082cKEjjeXcJJb LMeG5t0Ss7cLwwcJiR3bFh06yUDZqJkBfVtfLdKyKzm3KL-YsUU1h7E0KA4uiEI_SwLz1gyNa1lkfY_C QtOEWTBb7WJenKafSOP7TuNub74uYsaLtVS8NzVjgLz0Qf-0jG4DGBIwybxvWBaH24JjeHl9xFL44mE8 ATv01zuD404mYTuk2Pmn7V0" }

The client must validate the ID token according to OIDC Core 3.1.3.7

Decoded ID token JWT body:

{ "ConsentId": "consent-1234", "aud": "Z5O3upPC88QrAjx00dis", "auth_time": 1671055131, "c_hash": "ey3B5S_JgC_4UcRCcizagA", "exp": 1671055741, "iat": 1671055141, "iss": "https://as.apiprovider.co.nz", "jti": "c4a24fe8-a850-46fa-9b00-5447d65db2ab", "nonce": "234nasd-324bdsa-324", "s_hash": "MdAoiFu7HE3RHERhu2Mseg", "sub": "23l34jdslf92" }
OIDC metadata

API provider authorization servers must publish the appropriate metadata for supported JARM signing algorithms, as required by JARM Authorisation Server Metadata.

Decoupled Request

This section describes parameters that should be used with a decoupled flow so that a ConsentId can be passed from the Third Party to an API Provider for minimum conformance for the NZ Client Initiated Backchannel Authentication Profile (extending FAPI-CB).

Prior to this step, 

  1. The Third Party would have already registered a consent with an API Provider. This is achieved by creating a resource with an account information or payment consent APIs.

  2. The API Provider would have responded with a ConsentId (this is the unique identifier for the consent resource).

Authorization Request

This section describes the bare minimum set of Authorization Request parameters that an API Provider must support. The definitive reference is specified in CIBA Section 7.1 (Authentication Request).

As per FAPI-CB 5.2.2.6 the Authorization Requests shall be signed as per CIBA Section 7.1.1

This is a non-normative example of the Authorization Request:

POST /bc-authorize HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded request=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5xTzZlOEFK WEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiJ1cm4tYWxwaGFiYW5rLWludGVud C01ODkyMyIsImF1ZCI6Imh0dHBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubnoiLCJjbGllbnRfbm90aWZpY 2F0aW9uX3Rva2VuIjoiYWE5NmQwNmMtYzQ4OC00MTM1LWI2Y2QtOTcyYjRlNDY5NzkxIiwiZXhwIjoxN jcyODY1NDA0LCJpYXQiOjE2NzI4NjQ4MDQsImlzcyI6Ilo1TzN1cFBDODhRckFqeDAwZGlzIiwianRpI joiNDQzZDQ3YzYtY2I2Ny00NmUzLTlmMDgtZmFjMzk4MzQ3MGIwIiwibG9naW5faGludF90b2tlbiI6I mV5SmhiR2NpT2lKUVV6STFOaUlzSW10cFpDSTZJbFp6T0ZGRU16bEthRkpQY0haUFR6aGtTbEZJTFc0M 1RVNXhUelpsT0VGS1dFaDJNVEEwWkd0dU5VMGlmUS5leUp6ZFdKcVpXTjBJanA3SW5Cb2IyNWxJam9pS 3pZMExUSXlNRFkyT0RjNElpd2ljM1ZpYW1WamRGOTBlWEJsSWpvaWNHaHZibVVpZlgwLnF4dmZNajlTR 2lYVWJmRTVGM1NUTXJXcl9ITm9ZMUJNSVVtWDZkOWJ2a05mLUpyLVY5c0JDak9yTjhxc3hvVnVCblRvW nNEb1RSRExIR3p5a2hqdHFZUDZsYS1SS0J1OFliblM0VWQzU1hvQ3pJUUVMdnRJbXJtYy0tQlFsdy1tR Wkydmt4NGhZQjRmVXlXMWkyZ2d0aFE1blhrY2tSa0xtWU5Ua09vUENjSkRiMmtmR1Y3ODNtV09GZ3g4N mRKMDU0T3ZxV2FOaWRuVU9YWTlPQ0tQR3ZLdC1VWUE0VUJtbFd5cHZJSzRLeVhOX0VQdVlzcVZaZ3NES Ep3dmRwZW90Y3Z6U1hrLUkzWDZWdi1nc2Qzbk8zcC1FcWx5Vnl1RlBZcVNiaDNRWnRsMVM0RmNudGhjT VBjakl4aGkxNUxlYzBXVjVRLTRSMHozRVRseFhLbDF2M3V3ZzhWS09neWdXeEh0dENqaGxjSzJCOHpwN lY2cUxwSDgyWjgzR293cWpXa1dJd1Y1alpQQlZLUHlFWnl3S1NCUjBfRDBHaGQ5cG9JQXFnVEZSSFVGb npJbmlGNEQxSDJaN09DRUtBRUlSRjdkMThOVURxTzV1a1lGcU4ySkxoYVNjUUdteTF6bGgwWjdPVkkwR k1vYWZ2cW56b3ZZdG8tcEotcENXUTR4bnBDSHFhcTVXQl80Q2o4TG91S3ByRW1FYW53S081cTNUemZfd mNNSGEydW9Bd0xyNC1kOFprRk9NY2ZDb0ZzLUtkT2pCZWNqOWtjMHNoS2dyZlpFUTh6VVFlWGlqUW50V 044RDVfV3VlLVg2UWhRcVZ5SHVicEhGWTNidjlWUWd5aUx2V2pRMUZlcjVqc2dGTENMU3RrRDc4YWhac HhvSTRza0JieXBIaHZFIiwibmJmIjoxNjcyODY0Nzk0LCJzY29wZSI6Im9wZW5pZCBwYXltZW50cyJ9. pgpQqAWI1XoGrhgDVuH71F9wY12YUEtGatkSPa4YiZ5ugenr8I2GZZKVTUKx1S7wh_UGmNQR371PBuFS Q4wk9Di0JOmucvTr6UcRLR_M4_C20X_IxzKXXKSsn9bAQ14mPe206uzCjun6vtI4BQlSKz0lhXhWc_0W RKy-osQ77r5oHpRKDQ3Hp1-0C0wSbi7SCYvgKqiiugWXJu9rw5uVIyLPBiXWwDPqkRFMHcQsv7GdyX59 c255FUKuYVuTvkW5kMzmp8pMnBzjRxaj0X2qnJgw1svAMm46clubLiz7cDVSIfTQ9R0hqwMn6sXeDyVN q1LsTEKjEMC2gWhhHuURDgme8d0QpBVugcKGt8NxE4N3HFBo6OOP0S82QyGRe4UUfKBEwjuvEbsjRHBd cFYY0PfbImyKrR6z_uAjwUFyG-NW6VA8GJJFy7GcxKyEIM0NML5MfMEiojTvjeOB-6j2kdsy4Dz1ueb0 h5rrmx30NtiOups1X_USCiB9kQQFWr8dtPaAAQKu_K3tHVqTqjbvj6EVRsIOESCWU38GGMkwkGg3LMl6 37duoE126m3uQUycW7IYHp6pWq9b53-jmvMxJkGXMBFUxKBgtv4ssKUIrMn7TXpOtlAk2nTwPRoEmc4H Op6pGt-thEEK9vKyj4RNP0mbKVJqPup3wKFOOA4vo-M& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3A client-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcyODY1NDA2LCJpYXQiOjE2NzI4NjQ4MDYsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiNTQzOGNmOTktNWNmZC00MmU5LTlmZTMtZmUwYTI0NTk1OWZlIiwi bmJmIjoxNjcyODY0ODA2LCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.jCIbyogiGxGFws6X1k6 b_ED_MVmo2xxlpEcEjeslOpsn_SBOyDQSXwCz79B5-61RjUnFgAWb3_bqz93Xy2o0RxbDdPO7nKtz_kk GMM7crm5WS9C3WanKHp-VPqU87rwpPNvx98pn0cHa9e-o_AAeInNrH2gLse8ZMV9NFCdGl0QWOTDFVzK bxZ7B8OlkbWx3XQ3wUEX2d9TCJifUled7uJbCTejWa3fGexlrxhQnVbIwkZ9ni9bIj6D1vEs9_RPQ2ZE Qrwhs3QozLLRH54-96HfizAcpDjnI_5AeQWSvBMuu5BsaHFYazLlXY0isRs0TqQ6eB-ZJX6jkAi3Hs93 LbyQ8qGozwThKutmG9xzdVgEcIT6FX9m1yK9_aNqe7Am9bnbz6fNm-M08vV0ASWMH_-y_eDoiFTEiss1 6Bk0psobALEt_ydkV1A5cqIyYkaX0ibwJm7vulYXiyv24yu7ydYGFQ3PJVIKQcP0SF2GGtvtBZbBDK6W _KhuMDcGHAemKQP0ZNtCYnoU9iIATNysCfLqJI8k_yrYnbD33hZpqBBYvFE4f6eITQKqIsavnmnzSlwH 52YLhpAhORbBQToSKt_8QM60IrDI88rddlGZu7PIe4xXP6UsyzCRQTQ0NinurZ-nDydP3rD2MlY4UZMr zm0xybnlIGAaOa6-pDhR0LtU

This is the example Request Object - without Base64 encoding:

{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "ConsentId": "urn-alphabank-intent-58923", "aud": "https://as.apiprovider.co.nz", "client_notification_token": "aa96d06c-c488-4135-b6cd-972b4e469791", "exp": 1672865404, "iat": 1672864804, "iss": "Z5O3upPC88QrAjx00dis", "jti": "443d47c6-cb67-46e3-9f08-fac3983470b0", "login_hint_token": "eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSl FILW43TU5xTzZlOEFKWEh2MTA0ZGtuNU0ifQ.eyJzdWJqZWN0Ijp7InBob25lIjoiKzY0LT IyMDY2ODc4Iiwic3ViamVjdF90eXBlIjoicGhvbmUifX0.qxvfMj9SGiXUbfE5F3STMrWr_ HNoY1BMIUmX6d9bvkNf-Jr-V9sBCjOrN8qsxoVuBnToZsDoTRDLHGzykhjtqYP6la-RKBu8 YbnS4Ud3SXoCzIQELvtImrmc--BQlw-mEi2vkx4hYB4fUyW1i2ggthQ5nXkckRkLmYNTkOo PCcJDb2kfGV783mWOFgx86dJ054OvqWaNidnUOXY9OCKPGvKt-UYA4UBmlWypvIK4KyXN_E PuYsqVZgsDHJwvdpeotcvzSXk-I3X6Vv-gsd3nO3p-EqlyVyuFPYqSbh3QZtl1S4FcnthcM PcjIxhi15Lec0WV5Q-4R0z3ETlxXKl1v3uwg8VKOgygWxHttCjhlcK2B8zp6V6qLpH82Z83 GowqjWkWIwV5jZPBVKPyEZywKSBR0_D0Ghd9poIAqgTFRHUFnzIniF4D1H2Z7OCEKAEIRF7 d18NUDqO5ukYFqN2JLhaScQGmy1zlh0Z7OVI0FMoafvqnzovYto-pJ-pCWQ4xnpCHqaq5WB _4Cj8LouKprEmEanwKO5q3Tzf_vcMHa2uoAwLr4-d8ZkFOMcfCoFs-KdOjBecj9kc0shKgr fZEQ8zUQeXijQntWN8D5_Wue-X6QhQqVyHubpHFY3bv9VQgyiLvWjQ1Fer5jsgFLCLStkD7 8ahZpxoI4skBbypHhvE", "nbf": 1672864794, "scope": "openid payments" } . <<signature>>

Claims

Field

NZ Security Profile

Notes

Field

NZ Security Profile

Notes

iss

Required

The iss value should be the Client Id of the Third Party, unless it was signed by a different party than the Third Party.

aud

Required

The aud value should be or include the API Provider's Issuer Identifier URL.

nbf

Required

The time before which the JWT must not be accepted for processing. The processing of the "nbfclaim requires that the current date/time MUST be after or equal to the not-before date/time listed in the nbf claim.

Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519.

exp

Required

Token expiration date/time.

Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519.

iat

Required

Token issuance date/time.

Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519.

jti

Required

The jti (JWT ID) claim provides a unique identifier for the JWT.

scope

Required

Third Parties must specify the scopes that are being requested.

The scope parameter must contain openid

The scopes must be a sub-set of the scopes that were registered during Client Registration with the API Provider.

ConsentId

Required

Third Parties must provide a ConsentId for which this authorisation is requested.

client_notification_token

Optional

Third Parties must provide this field if registered to use Ping mode. 

It is a bearer token provided by the Third Party that will be used by the API Provider to authenticate the callback request to the Third Party. 

login_hint_token

Optional

A token containing information identifying the Customer for whom authentication is being requested.

The particular details for the login_hint_token are documented in the NZ Security Profile standard.

Third Parties must provide either a login_hint_token or an id_token_hint

id_token_hint

Optional

An ID Token previously issued to the Third Party by the API Provider being passed back as a hint to identify the Customer for whom authentication is being requested.

Third Parties must provide either a login_hint_token or an id_token_hint

requested_expiry

Optional

A positive integer allowing the client to request the expires_in value for the auth_req_id the server will return.

The API Provider may use this value to influence the lifetime of the authentication request and is encouraged to do so where it will improve the user experience, for example by terminating the authentication when as it knows the client is no longer interested in the result.

Login Hint Token

This is a non-normative example of a Login Hint Token - which is used to identify the Customer.

{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M" } . { "subject": { "phone": "+64-22066878", "subject_type": "phone" } } . <<signature>>

Claims

The following claims are supported in the login_hint_token. The RFC7519 registered claims may also be included, and are to be treated in according with that specification.

Field

NZ Security Profile

Notes

Field

NZ Security Profile

Notes

subject

Required

JSON object containing identification hint information, in the form of:

  • subject_type - the indicator of the type of the hint

  • Value of one of the supported hints, whose type is indicated in subject_type

subject_type

Required

Third Parties must specify the type of identification provided in the login_hint_token.

This is limited to:

  • phone

  • email

  • username

  • api_provider_token

  • third_party_token

username

Optional

The username that identifies the Customer with the API Provider.

phone

Optional

A phone number that identifies the Customer with the API Provider.

email

Optional

An email address that identifies the Customer with the API Provider.

api_provider_token

Optional

A token generated by a Customer's authentication device that identifies the Customer with the API Provider.

third_party_token

Optional

A token generated by a Third Party and registered with a Customer's authentication device by the Customer.

ID Token Hint

This ID Token must be from a previously successful authentication event for the Customer. As this is a previously used ID Token, it is valid for a Third Party to use an expired ID Token.

This is the example Request Object - without Base64 encoding - using the ID Token Hint:

{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "ConsentId": "urn-alphabank-intent-58923", "aud": "https://as.apiprovider.co.nz", "client_id": "Z5O3upPC88QrAjx00dis", "client_notification_token": "aa96d06c-c488-4135-b6cd-972b4e469791", "exp": 1672865404, "iat": 1672864804, "id_token_hint": "eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwY TZ5SWxxb1BBUU53MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJaNU8zdXBQQ zg4UXJBangwMGRpcyIsImF1dGhfdGltZSI6MTY3MTA1NTEzMSwiZXhwIjoxNjcxMDU4NzQx LCJpYXQiOjE2NzEwNTUxNDEsImlzcyI6Imh0dHBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubno iLCJqdGkiOiI0MThmODMzNC1lNDhiLTQ5ODYtOWI2Yi1lNjNjMjhlYmRiODAiLCJzdWIiOi IyM2wzNGpkc2xmOTIifQ.BhVmkTg6Kn7pwir8j4nFkJ_G8qpL6nuJTcIxRk1VKKR0MdcO2J __JKS3bzGnLPtS0kyTQsHTTeEHuN2u4kvmikF5SXwQ3edX8J9OrPz3Zvu61-41703DOsfXz 8jJ2XH3QDNptcDXgiMJ2a7vYO4zn7O4jyelZGJnZr3ZvIVu9nRjRgF8BwFElq_gOxvVPCks SgmHSkE0hOT4ynBff-tXjETjMbYy4jP3ZLZznbucaSGQPmG5AWjnHGnyHN14NQFk4v9b8KE MZhAVTTdE_V1fudIu8uW2-bprAtcrRpAvoFHoznjnaNsPRbSSFrrxK9WXYwWKHMkMzd2mdD 8cakV1ITD9hSkDoIryhc9jwZgZI_uu5k6LD-OssRd5j_L_qXghcYyLI8_ByrSnDWkIvc8i1 jpWqOmZcwi3IBiJGe5gWP7ncWiR40QfsG-l8UVEANvUzIWUUe4Oz8DFJyCab33cpFAPl6IL 02edDi7CMr3LBtGKr_BBW--0GNCbI6ku9uc0EHd3ucsLDzlhcpjj_2ByAKVq47r61_6_KRR ykLrLFQNEzT81hVBaYnxH50TUjJbVCBB9igOQFcn29IicoHgX3SpBwN95qMqryNNJLxkGYA P3Hs4W-QEGKPHIF6vsZV3B4_LZ474csN3KjjQiDWA3pZP7oCQ0OolXArEC7pKgXrs", "iss": "Z5O3upPC88QrAjx00dis", "jti": "c12162ca-2535-49bc-8687-dedc3df2a2ce", "nbf": 1672864794, "scope": "openid payments" } . <<signature>>

This is the (non-normative) ID Token Hint, after base64 decoding:

{ "alg": "PS256", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY", "typ": "JWT" } . { "aud": "Z5O3upPC88QrAjx00dis", "auth_time": 1671055131, "exp": 1671058741, "iat": 1671055141, "iss": "https://as.apiprovider.co.nz", "jti": "418f8334-e48b-4986-9b6b-e63c28ebdb80", "sub": "23l34jdslf92" } . <<signature>>

Authorization Request Response

The following is a non-normative example of an authentication response:

HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1", "expires_in": 3600, "interval": 2 }

Claims

Field

NZ Security Profile

Notes

Field

NZ Security Profile

Notes

auth_req_id

Required

This is a unique identifier to identify the authentication request made by the Client. It MUST contain sufficient entropy (a minimum of 128 bits while 160 bits is recommended) to make brute force guessing or forgery of a valid auth_req_id computationally infeasible - the means of achieving this are implementation specific, with possible approaches including secure pseudorandom number generation or cryptographically secured self-contained tokens.

expires_in

Required

A JSON number with a positive integer value indicating the expiration time of the "auth_req_id" in seconds since the authentication request was received. A Client calling the token endpoint with an expired auth_req_id will receive an error.

interval

Optional

A JSON number with a positive integer value indicating the minimum amount of time in seconds that the Client MUST wait between polling requests to the token endpoint. This parameter will only be present if the Client is registered to use the Poll or Ping modes.

Token Request

The following is a non-normative example of a token request using the auth_req_id in the authorisation request response.

POST /token HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded grant_type=urn%3Aopenid%3Aparams%3Agrant-type%3Aciba& auth_req_id=1c266114-a1be-4252-8ad1-04986c5b9ac1 client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3A client-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcyODY1NDA5LCJpYXQiOjE2NzI4NjQ4MDksImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiNDg3MjE5YWItZjNjOC00ZWM3LTlkNGQtYWJhMDk4MDhhYTVhIiwi bmJmIjoxNjcyODY0ODA5LCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.kPYlf7832XTFQecOt3L hjpYecKecFlIVnKTw8IizwumwH4q1DWowVy7GE5vnLJ2iyB8yaRiEkNGaoYjR1n4b8oBXeE4Futpahma D4PHX2_LjmhfkaEHDcE1U49NNopRovIH8C7UvDmZCnMde7WM-N_1jc4fUZFM2vb_NO5Lo40iPS5wAjrh hOEd2f6gL0k80h4ilyj4LWWxVLzcyrpLBtL9zSlUwOkz46X3_ivfkRS6OTtvw2G10S_t5waTa1W4Cr1O uYqhQttB5MwwJgubFwjVkT0Wx4gbb_FJyRhi9Vf0WxjskeRdq5t_BsljnHcGejGcnh0SHAScdH2vrIxA Qg6kJ4erui_K1uuIJXjfpzoXF1rRZqVsm_6JQ6SNSADFeZ8RC3Dg_8Ytvy7UBbcLQaVJM5naFq6oTrs7 KqeXL2pBXpHOG_XVZdwZ8WKE7ByaGPDpVNE7FZxX-QUHKSx1pBGeS_DxVWpzN63yiEpCK83HpkCyLT32 SXmw9u9Io5Wqp9Mzkdkj6faDkLgjXr-VZPArqoCL_zg1BuFcXAsNxM5rImyCz5xfZ_gObtlb18pJRhGa bRIFbIKGwBj1Wh7PTcbUKtqLqbeyj9hr05LM75UrWqVJajDeojbvxPJFQA4r-RRblxqDvQreozCfVRyd xg3KtGjQblnXA1zn345pVhLw

Token Request Response

The following is a non-normative example of a successful token response.

HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "access_token": "G5kXH2wHvUra0sHlDy1iTkDJgsgUO1bN", "token_type": "Bearer", "refresh_token": "4bwc0ESC_IAhflf-ACC_vjD_ltc11ne-8gFPfA2Kx16", "expires_in": 3600, "id_token":"eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BB UU53MGo1aEI2cldNWlkifQ.eyJDb25zZW50SWQiOiJ1cm4tYWxwaGFiYW5rLWludGVudC01ODkyMyIsI mF1ZCI6Ilo1TzN1cFBDODhRckFqeDAwZGlzIiwiZXhwIjoxNjcyODY1NDE0LCJpYXQiOjE2NzI4NjQ4M TQsImlzcyI6Imh0dHBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubnoiLCJqdGkiOiJlNWYyODA4Mi01MjU5L TRkYWUtYWUxOC0yOTJhOWM2OWQwODEiLCJzdWIiOiIyM2wzNGpkc2xmOTIifQ.i4-mjlZqa0a81-tGy0 PWMNz7cmwnvCBT7XUNfDJ3EN2Gner_VZZylQ0oAbkeStXLIVjPT2hEOoxi7wCf65i-Qb1fAqTbiwovB3 XSaQAOl12adg7xl_LtMp1FQ6sTyjjyklWEbKuRef3ONgrBfneqFXxxM4rWRPjTeNJ2_DsDl73OBHr9Y6 fZ1UkfDBWh4qCnzCaFbNhghKvKkoq8Gn2AAfLx9g-b4L8zbIV1Yw7lxl2uq3i8ygnDnaFxmCS2rRNy79 m_U8MY4XC1A5WlcG8N2YPeEkRNQfVoBp9t5b1To7MUf0yMGQSEcBiryz2utuGyCAk_os_RsG8KJ7Shlz i7_9N5josduX_85jNZhxygfmmmJXPMtpeRr_ivqbQccFpMxjCLrSj88rg6GGCLDdNmh80V4KOdXLcXLw npE2QcYUU6tOs_349tCuo2T1nTDp-V_u-UdXktg_1-c0mIfHHgcF75ZIUVqkFTIsmk3sc3VwIEzUv1lG K9yNcxojj0-3rK6ZRsK_6aimNjgDHhCzrJaDNvRhLVqtQh5_X8__LItygHkfcS0UoB2yoGC2J3FG0yxJ VPlPRHViHS22MjwhuGPvZPExnokefkTdgHg087o-Tix_Ip3u3i-Ef0hT0bypaYuP46uyzhSpsVDg3AjC -EjrxzNdMX-XLtnRVgmd_I2WA" }

Ping Callback

The following is a non-normative example of a Ping callback request. The API Provider calls POST at the Third Party's registered callback endpoint with the client_notification_token in the original Authorisation Request, and the auth_req_id in the body of the request.

POST /cb HTTP/1.1 Host: api.thirdparty.co.nz Authorization: Bearer e330a2f1-5e1b-41be-9a54-e112c19ac05f Content-Type: application/json { "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1" }

ID Token

This is a non-normative example of an ID Token returned - with the sub being populated with a PPID uniquely identifying the Customer to the Third Party.

{ "alg": "PS256", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY" } . { "ConsentId": "urn-alphabank-intent-58923", "aud": "Z5O3upPC88QrAjx00dis", "exp": 1672865414, "iat": 1672864814, "iss": "https://as.apiprovider.co.nz", "jti": "e5f28082-5259-4dae-ae18-292a9c69d081", "sub": "23l34jdslf92" } . <<signature>>

Claims

Where appropriate please follow the JWT Best Current Practices Guides [BCP-225] https://www.rfc-editor.org/rfc/rfc8725  

Field

NZ Security Profile

Notes

Field

NZ Security Profile

Notes

aud

Required

As per FAPI-RW and OIDC.

Audience that the ID Token is intended for.

OpenID Connect protocol mandates this must include the ClientID of the Third Party's OAuth Client.

iss

Required

A JSON string that represents the issuer identifier of the authorization server as defined in RFC7519. When a pure OAuth 2.0 is used, the value is the redirection URI. When OpenID Connect is used, the value is the issuer value of the authorization server.

Issuer of the token.

Token issuer will be specific to the business.

sub

Required

 

Token subject identifier.

A Pairwise Pseudonymous Identifier (PPID) for the Customer - that uniquely identifies the Customer to the Third Party. This PPID must not be reused for another Third Party.

The sub must be the same for an ID Token created by the Authorisation and Token endpoints during the Hybrid flow and Authorisation Code Flow. 

ConsentId

Required

The ConsentId of the originating request.

exp

Required

The validity length will be at the discretion of the Banks provided that it does not impact the functionality of the APIs. For example, an expiry time of 1 second is insufficient for all Resource Requests.
 

Token expiration date/time.

Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519.

iat

Required

Token issuance date/time.

Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519.

jti

Optional

Unique identifier for the ID token

Implementation Guide

This provides an implementation perspective of the NZ Security Profile aligned to the accepted NZ Banking Data and other specified APIs for:

  • The Hybrid Flow (illustrated with the Payment Initiation APIs)

  • The Authorization Code Flow

  • The Decoupled Flow (illustrated with the Account Information APIs)

Both the Payment Initiation APIs and the Account Information APIs rely on the same underlying consent flow - so either authorisation flow may be used for both Payment Initiation and Account Information.

JSON schemas for messages associated with the security profile can be found here:

https://github.com/PaymentsNZ/API-Security-Profile

Hybrid Flow

The implementation is based on the following known configurations:

Client Types

Grant Types

Client Credentials Grant Type

This is with scope payments

  • The Client Credentials Grant Type is used when the Third Party requires an Access Token (on behalf of itself) in order to access a consent resource

  • Only valid API scopes will be accepted when generating an Access Token (i.e., payments)

  • Access tokens generated by a Client Credentials grant may not return any refresh tokens (as per the OAuth 2.0 specification)

Hybrid Flow

This is with response_type "code id_token"

  • The Payment Initiation APIs illustrate the use of request_type=code id_token for the OIDC Hybrid Flow implementation

  • The API Provider may optionally choose to return Refresh Tokens for the Hybrid Flow when issuing an Access Token

Access Tokens

  • For the Payments and Accounts APIs, the Access Token must be obtained within a Secure, Server Side Context between the Third Party and the API Provider

  • Access Tokens must be validated by the Third Party as outlined within OIDC

Refresh Tokens

  • API Providers may optionally return a Refresh Token when an Authorization Request is successfully processed at the Token endpoint. The Hybrid flow supports the provisioning of Refresh Tokens.

  • Refresh Tokens must be validated as outlined in OIDC

ID Tokens

  • ID Tokens must be validated by the Third Party as outlined within OIDC

  • Third Parties must use the ConsentId claim to populate and retrieve the ConsentId for any required validation

  • The full set of claims that can be represented within an ID Token are documented in the Request Object and ID Token sections of the Security Profile

Authorization Codes

  • Authorization Codes must be validated by the Third Party as outlined within OIDC

Unspecified Behaviour

The implementation guide does not illustrate the following configurations in this section.

Client Types

  • Public clients - as only confidential clients are allowed in the NZ Security Profile

Grant Types

  • OIDC Hybrid Flow (response_type=code id_token token)

    • Forces an Access Token to be returned from the API Provider Authorization endpoint (instead of a token endpoint). This is not illustrated in the Payments and Accounts API Specifications

  • Client Credentials Grant Type (scope=openid email profile)

Validity Lengths

These are to be managed in the competitive space - so different validity lengths are not illustrated. Each API Provider's Authorization / Resource Server will be configured independently to comply with internal API Provider Security Policies and Guidelines. The Accounts and Payments API Specifications do not mandate validity lengths. 

Authorization Code
  •  OAuth 2.0 Specification suggests an Authorization Code should be short lived to a maximum of 10 minutes. Any codes exceeding this limit to be rejected

ID Token
  • ID Token claims (exp and iat) determine its validity

  • Returned with the Authorization Code when the Hybrid flow (code id_token) is initiated

Access Token
  • The expires_in attribute returned by the Authorization Server when an Access Token is generated determines its validity

  • Access Tokens are generally short lived, and where they expire, are then exchanged for another using a longer lived Refresh Token

  • Refer to Section 16.18 of OIDC - Lifetimes of Access Tokens and Refresh Tokens.

Refresh Token
  • Refresh Tokens are generally longer lived in comparison to Access Tokens

  • Refer to Section 16.18 of OIDC - Lifetimes of Access Tokens and Refresh Tokens

Success Flows

The sequence diagram below highlights the OAuth 2.0 Client Credentials Grant and OIDC Hybrid flow that are used by the Payments API. 

 

Payment Initiation with Client Credentials Grant Type and OIDC Hybrid Flows
participant Customer participant Third Party participant API Provider Authorisation Server participant API Provider Resource Server autonumber 1 Customer -> Third Party: Establish TLS 1.2 note over Customer, API Provider Resource Server Step 1: Agree payment consent end note Customer -> Third Party: Agree payment consent note over Customer, API Provider Resource Server Step 2: Create payment consent end note Third Party <-> API Provider Authorisation Server: Establish TLS 1.2 MA note left of Third Party Client Credentials Grant end note Third Party -> API Provider Authorisation Server: POST /token (client authentication credentials, scope:payments) API Provider Authorisation Server -> API Provider Authorisation Server: Validate client authentication credentials, scope API Provider Authorisation Server -> API Provider Authorisation Server: Validate ClientId matches client SSL cert API Provider Authorisation Server -> Third Party: HTTP 200 (OK) access-token (scope:payments) Third Party <-> API Provider Resource Server: Establish TLS 1.2 MA Third Party -> API Provider Resource Server: POST /domestic-payment-consents (access-token - scope:payments) API Provider Resource Server -> API Provider Resource Server: Validate access token API Provider Resource Server -> API Provider Resource Server: Validate scope:payments API Provider Resource Server -> API Provider Resource Server: Validate ClientId matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Create new domestic-payment-consent resource API Provider Resource Server -> API Provider Resource Server: Bind ConsentId with ClientId API Provider Resource Server -> Third Party: HTTP 201 (Created), ConsentId note right of Third Party Begin OIDC Hybrid Flow. See OpenID Core 6.1. Passing a Request Object by Value See OpenID Core 5.5. Requesting Claims using the "claims" Request Parameter The claims parameter must at least request: "id_token": { "ConsentId": {"value": ConsentId, "essential": true} } The request object must be signed using the Third Party's private key. end note Third Party -> Third Party: Persist ConsentId note right of Third Party The Third Party should store the ConsentId in a manner that it can be retrieved again later in the flow in Step 4. This could be stored in the user session (and retrieved using 'state' as a key) or the Customer could use some other unique identifier. This will be re-retrieved in [43]. end note note over Customer, API Provider Resource Server Step 3: Authorize consent end note Third Party -> Third Party: Create signed request object with requested Claims (ConsentId) Third Party -> Customer: HTTP 302 (Found); Location: /authorize,\nredirect-uri, ClientId, state, nonce, scope=openid payments,\nresponse-type=code id_token,\nrequest=signed JWT request object - ConsentId) Customer -> API Provider Authorisation Server: HTTP GET /authorize redirect-uri, ClientId, state, nonce, scope=openid payments, response-type=code id_token,\nrequest=signed JWT request object - ConsentId API Provider Authorisation Server -> API Provider Authorisation Server: Validate Clientid, scope API Provider Authorisation Server -> API Provider Authorisation Server: Validate redirect-uri for ClientId API Provider Authorisation Server -> API Provider Authorisation Server: Validate JWT request claim - ConsentId note right of API Provider Authorisation Server Validate the request object by using the Third Party's public key. Third Party certificate will be identified using the kid claim in the JOSE header of the request object. Check that the ConsentId belongs to the ClientId that initiated the request. end note API Provider Authorisation Server <-> Customer: Authenticate (login and agree consent) Customer <-> API Provider Authorisation Server: Select debtor account if necessary API Provider Authorisation Server -> API Provider Resource Server: Update Consent Status to Authorised API Provider Resource Server -> API Provider Authorisation Server: OK note right of API Provider Authorisation Server Implementation of how the resource is updated is API Provider specific. (There is no standardised API for this) end note API Provider Authorisation Server -> API Provider Authorisation Server: Generate authorization-code, id_token note right of API Provider Authorisation Server id_token claims:{ c_hash: 123, s_hash: 456 } id_token must be signed using the API Provider's private key. The generation of c_hash is documented in OIDC: 3.3.2.11. ID Token The generation of s_hash is in FAPI R/W spec: Section 5.1 http://openid.net/specs/openid-financial-api-part-2-wd-02.html#introduction end note API Provider Authorisation Server -> Customer: HTTP 302 (Found); Location: redirect-uri (authorization-code, id_token, state) Customer -> Third Party: HTTP GET redirect-uri (authorization-code, id_token, state) Third Party -> Third Party: Validate signature on id_token note right of Third Party Validate the id_token by using the API Provider's public key. API Provider certificate will be identified using the kid claim in the JOSE header of the id_token end note Third Party -> Third Party: Validate authorization-code using id_token (c_hash) Third Party -> Third Party: Validate state using id_token (s_hash) Third Party -> Third Party: Validate nonce using id_token note right of Third Party Exchange authorization-code for access token. end note Third Party <-> API Provider Authorisation Server: Establish TLS 1.2 MA Third Party -> API Provider Authorisation Server: HTTP POST /token (client authentication credentials,\n authorization-code, grant_type, redirect_uri) API Provider Authorisation Server -> API Provider Authorisation Server: Validate ClientId matches client SSL cert API Provider Authorisation Server -> API Provider Authorisation Server: Validate client authentication credentials,\n authorization-code API Provider Authorisation Server -> API Provider Authorisation Server: Generate access-token API Provider Authorisation Server -> API Provider Authorisation Server: Bind access-token to ConsentId API Provider Authorisation Server -> Third Party: HTTP 200 (OK) access-token (scope:payments) note over Customer, API Provider Resource Server Step 4: Create domestic payment end note Third Party <-> API Provider Resource Server: Establish TLS 1.2 MA Third Party -> Third Party: Retrieve ConsentId note left of Third Party Retrieve the ConsentId that was issued in Step 2. The method for doing this will depend on how the Third Party persisted the payment id in [16] end note Third Party -> Third Party: Decode / verify ID Token Third Party -> Third Party: Read ConsentId from id_token claim Third Party -> Third Party: Compare with ConsentId retrieved in [43] Third Party -> API Provider Resource Server: POST /domestic-payments (access-token - scope:payments) using ConsentId API Provider Resource Server -> API Provider Resource Server: Validate access-token API Provider Resource Server -> API Provider Resource Server: Validate access-token matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Validate scope:payments note right of API Provider Resource Server Check binding created in [38] end note API Provider Resource Server -> API Provider Resource Server: Ensure access-token is bound to ConsentId API Provider Resource Server -> API Provider Resource Server: Update domestic-payment Status to AcceptedSettlementInProcess API Provider Resource Server -> Third Party: HTTP 201 (Created), DomesticPaymentId note over Customer, API Provider Resource Server Step 5: Get domestic payment status end note opt Third Party <-> API Provider Resource Server: Establish TLS 1.2 MA alt Use active access token to retrieve domestic-payment status Third Party -> API Provider Resource Server: GET /domestic-payments/{DomesticPaymentId} (access-token - scope:payments) API Provider Resource Server -> API Provider Resource Server: Validate access-token API Provider Resource Server -> API Provider Resource Server: Validate access-token matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Validate scope:payments API Provider Resource Server -> Third Party: HTTP 200 (OK), domestic-payments resource end alt end opt

Client Credentials Grant Type (OAuth 2.0)

This grant type is used by the Third Party in Step 2 to setup a single payment with the API Provider.

  1. The Third Party initiates an Authorization request using valid Client Credentials Grant type and scope(s)

  2. The API Provider Authorization Server validates the Client Authentication request from the Third Party and generates an Access Token response where the request is valid

  3. The Third Party uses the Access Token to create a new Payment resource against the API Provider Resource Server

  4. The API Provider Resource server responds with the ConsentId for the resource it has created

  5. The Client Credentials Grant may optionally be used by the Third Party in Step 5 to retrieve the status of a consent resource

OIDC Hybrid Flow

  • The Hybrid flow is an optional redirect flow for the NZ Security Profile. The Hybrid flow prevents IDP mixup attacks as documented by Nat Sakimura - Cut and Paste OAuth 2.0 Attack

  • This is initiated at the end of Step 2 by the Third Party after the ConsentId is generated by the API Provider and returned to the Third Party

  • This is used in a redirect across the Customer and API Provider in Step 3 in order for the Customer to authorize consent with the API Provider

  • This is used across the Third Party and API Provider in Step 4 by exchanging the Authorization Code for an Access Token in order to create the domestic-payment resource

Non-Normative HTTP Request and Response Examples

Step 1 - Agree Payment Consent

There are no Requests and Responses against the Payments API in this Step for the Customer, Third Party and API Provider.

Step 2 - Setup Payment-Order Consent

  1. Third Party obtains an Access Token using a Client Credentials Grant Type. The scope

payments must be used. When an Access Token expires, the Third Party will need to re-request for another Access Token using the same request below. 

Request : Client Credentials using private_key_jwt
POST /as/token.oauth2 HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=client_credentials &scope=payments &client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer &client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjczMjE5OTUxLCJpYXQiOjE2NzMyMTkzNTEsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiNTY3MTVkZjItYWI2ZC00YmE1LTlmZjUtMGFiMzNlY2Q0OTg2Iiwi bmJmIjoxNjczMjE5MzUxLCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.cXVI0Rgr1X7wuFwTcTY kDBLVK7oHMT_ldBZa5dOqXxt81eyBaCH1MMdnCsirt6g_ExL7Q_gh7rMUCP6toZULOSy6He32_hqsZk_ AXNlnuehDdRvn6aZxeuBJliM9gUWPqR73UKgMzDA-Zx-XFT9tmH92_nhGWgU9DWd0q-0MyldF3z3ri2j x4oeO8JLLyW6azz46ePxbla2qcPVWfKWIHo60cTJsq8I2uDIcBxsVAmAJRttszTTV1OS3xhWuRlIc45Q R7-MEA2omQCahBCbW1JhQ9gNXFjOu3pflxs-uThPLD8aJ1fWnNYFHe_nLVOSZKMY5nlkW6TT6jTX1RDp f__wbx3USIadzev4wDfTgCpRc23RgPW7J2Why2_87ZcmvpzsLQe0-h8WVwQhDQF5GajmUkI07j2zbaTR wRtCUiepHjDZez4t6WheGmzXAtjOvNJHSykaw6Rj3JfJzWsZgNy6ueh-gq9c2WPHehZn3389XHDmQova 3FQWYaNdSlyp65N4lUGgnAC5feifSVWriwS78OfEb5o_25o15q-_XmrM8zOhEOlob-ulxFfXdYX4ZvV1 3HJywZtHQ1B0L0u3Itk7YbPGDBD8lwvGcKX-WM2WNapT9z2cLOlx_6wJJRb41Xa1cyq4B6v5TlWNh5Ud fTEkzBM4eAp8ffnqB4ZKkGKo
Non-Base64 JWT client_assertion
{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "aud": "https://as.apiprovider.co.nz", "exp": 1673219951, "iat": 1673219351, "iss": "Z5O3upPC88QrAjx00dis", "jti": "56715df2-ab6d-4ba5-9ff5-0ab33ecd4986", "nbf": 1673219351, "sub": "Z5O3upPC88QrAjx00dis" } . <<signature>>
Response : Client Credentials
HTTP/1.1 200 OK Content-Length: 1103 Content-Type: application/json Date: Mon, 09 Jan 2023 12:19:13 GMT+1300 { "access_token": "2YotnFZFEjr1zCsicMWpAA", "expires_in": 3600, "token_type": "bearer", "scope": "payments" }

 

  1. Third Party uses the Access Token (with 

payments scope) from the API Provider to invoke the payment-order consent API. 

Request : domestic-payment-consents
POST /domestic-payment-consents HTTP/1.1 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA x-idempotency-key: THIRDPARTY.21302.GFX.20 x-fapi-customer-auth-date: 2023-01-09T11:36:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: b77f86a5-ad32-4627-a9ab-2440e9e74a79 Content-Type: application/json Accept: application/json { "Data": { "Consent": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "THIRDPARTY.21302.GFX.20", "InstructedAmount": { "Amount": "165.88", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "08080021325698", "Name": "ACME Inc", "SecondaryIdentification": "0002" }, "RemittanceInformation": { "Reference": { "CreditorName": "The Creditor", "CreditorReference": { "Particulars": "CreditorPart", "Code": "CreditorCode", "Reference": "CreditorRef" } } } } }, "Risk": { "PaymentContextCode": "EcommerceGoods", "MerchantCategoryCode": "5967", "MerchantCustomerIdentification": "053598653254", "DeliveryAddress": { "AddressLine": [ "Flat 7", "Acacia Lodge" ], "StreetName": "Acacia Avenue", "BuildingNumber": "27", "PostCode": "1010", "TownName": "Auckland", "CountySubDivision": [ "Auckland Central" ], "Country": "NZ" } } }
Response : domestic-payment-consents
HTTP/1.1 201 Created x-fapi-interaction-id: b77f86a5-ad32-4627-a9ab-2440e9e74a79 Content-Type: application/json { "Consent": { "ConsentId": "58923", "Status": "AwaitingAuthorisation", "CreationDateTime": "2023-01-09T12:19:20+13:00", "StatusUpdateDateTime": "2023-01-09T12:19:25+13:00", "Consent": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "THIRDPARTY.21302.GFX.20", "InstructedAmount": { "Amount": "165.88", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "08080021325698", "Name": "ACME Inc", "SecondaryIdentification": "0002" }, "RemittanceInformation": { "Reference": { "CreditorName": "The Creditor", "CreditorReference": { "Particulars": "CreditorPart", "Code": "CreditorCode", "Reference": "CreditorRef" } } } } }, "Risk": { "PaymentContextCode": "EcommerceGoods", "MerchantCategoryCode": "5967", "MerchantCustomerIdentification": "053598653254", "DeliveryAddress": { "AddressLine": [ "Flat 7", "Acacia Lodge" ], "StreetName": "Acacia Avenue", "BuildingNumber": "27", "PostCode": "1010", "TownName": "Auckland", "CountySubDivision": [ "Auckland Central" ], "Country": "NZ" } }, "Links": { "Self": "https://apiprovider.co.nz/open-banking/v3.0/domestic-payment-consents/58923" }, "Meta": {} }

Step 3 - Authorize Consent

  1. Third Party receives a ConsentId from the API Provider. The Third Party then creates an Authorization request (using a signed JWT Request containing the ConsentId as a claim) for the Customer to consent to the Payment directly with their API Provider. The request is an OIDC Hybrid flow (requesting for code and id_token)

Request : OIDC Hybrid Flow

Sourced from the NZ Security Profile Request Object section

Base64 and URL Encoded Example
GET /authorize? response_type=code+id_token& client_id=Z5O3upPC88QrAjx00dis& state=zSYkfyTKWQuZOBikzsmc& scope=openid+payments& nonce=w8q2mp1-z0o5w3mVHf-Mlt& redirect_uri=https%3A%2F%2Fthirdparty.co.nz%2Fredirect& request=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5xTzZlOEFK WEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3ZpZGVyLmNvL m56IiwiY2xhaW1zIjp7ImlkX3Rva2VuIjp7IkNvbnNlbnRJZCI6eyJlc3NlbnRpYWwiOnRydWUsInZhb HVlIjoiNTg5MjMifX19LCJjbGllbnRfaWQiOiJaNU8zdXBQQzg4UXJBangwMGRpcyIsImV4cCI6MTY3M zIyMDU3MCwiaWF0IjoxNjczMjE5OTcwLCJpc3MiOiJaNU8zdXBQQzg4UXJBangwMGRpcyIsImp0aSI6I jk4NWQwMmZkLWU1YTktNGJiOC05MjljLTI3MTA3YTcwNjVkOCIsIm1heF9hZ2UiOjg2NDAwLCJuYmYiO jE2NzMyMTk5NjAsIm5vbmNlIjoidzhxMm1wMS16MG81dzNtVkhmLU1sdCIsInJlZGlyZWN0X3VyaSI6I mh0dHBzOi8vdGhpcmRwYXJ0eS5jby5uei9yZWRpcmVjdCIsInJlc3BvbnNlX3R5cGUiOiJjb2RlIGlkX 3Rva2VuIiwic2NvcGUiOiJvcGVuaWQgcGF5bWVudHMiLCJzdGF0ZSI6InpTWWtmeVRLV1F1Wk9CaWt6c 21jIn0.EkrwixVI7YQ-wTd3cbCI1l2F0_29BMVijrnErMfiBBnXrI30cdAluRB-foCpnuUBjSNP13fmq 5ms6DCLvYCcbQOjY6-VieVG-vlA7Bue8Zp-RS1ZHjvTbhC698kVjrUqLyRS92s1wNsSt0ZKv6Re6FBqw 8hsoi3cdLF38ckpimQAwPYHQUvRDH-vU1yyNktRoVw2wlSClp8nyx4aLAO6kZgLGthtELLatErQQIsHV McP7fmgvnVygYtldQEo6PSdTAa2JWvJJxl3-wXYCGxZoyH3GMeGA_H6qHxbvSaMrwhzIAr9NIQigEbco dqLhQAUpvRxxVXaQYMl2FS79agHlEx7RdHbvtQPTRtnp4VglNbZcdrLd-YhsgOOA1bSBCUqCwXIEcbQh 7tLE3Y2eFC5JlCyOW0VBqCZVoXZuzsuJ1WG8uo6ML-CoRn_4b94oJUMwklUy5AM-TsOAvLO8-uw3XY5O K3R3m5A-zKbaVeOzp0PFylHalbPRU1N69s_QCM-PHFoJlaJ0ZMSnA22tMu6kdVmNAWkKQtsUhza8HpaS BxOvsXMWBuELqYRY_mnnfNiMB8oIGLpRfcEuzPdQkeeUu9OTwdOvOknstLljCXi6ecuftyGCJ1bZipFd snP1h3Hsb3vd_17DI9kyWYqYYLgnW_ENzjAEUDqA5xw3cEeoj8
Non-Base64 encoded example of the request parameter object
{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "aud": "https://as.apiprovider.co.nz", "claims": { "id_token": { "ConsentId": { "essential": true, "value": "58923" } } }, "client_id": "Z5O3upPC88QrAjx00dis", "exp": 1673220570, "iat": 1673219970, "iss": "Z5O3upPC88QrAjx00dis", "jti": "985d02fd-e5a9-4bb8-929c-27107a7065d8", "max_age": 86400, "nbf": 1673219960, "nonce": "w8q2mp1-z0o5w3mVHf-Mlt", "redirect_uri": "https://thirdparty.co.nz/redirect", "response_type": "code id_token", "scope": "openid payments", "state": "zSYkfyTKWQuZOBikzsmc" } . <<signature>>
Response : OIDC Hybrid Flow

After the Customer has consented directly with the API Provider via their web application (and confirmed the Debtor account) the API Provider validates the Authorization request and generates an Auth Code and ID Token

HTTP/1.1 302 Found Location: https://thirdparty.co.nz/redirect# code=g_0JnK9emAbw-LCPPAooR_Vgw0TmpmgmYz9a6qpoT0Q& state=zSYkfyTKWQuZOBikzsmc& id_token=eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BB UU53MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiI1ODkyMyIsImF1ZCI6Ilo1T zN1cFBDODhRckFqeDAwZGlzIiwiYXV0aF90aW1lIjoxNjczMjE5OTgwLCJjX2hhc2giOiJleTNCNVNfS mdDXzRVY1JDY2l6YWdBIiwiZXhwIjoxNjczMjIwNTkwLCJpYXQiOjE2NzMyMTk5OTAsImlzcyI6Imh0d HBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubnoiLCJqdGkiOiI1YTMwMTU2My04NWZhLTRjNmItOTcwMy0wZ WE1ZmVkYTAzZmQiLCJub25jZSI6Inc4cTJtcDEtejBvNXczbVZIZi1NbHQiLCJzX2hhc2giOiJRR2VsV W45S1B0VnVQakZHV1hXZm9BIiwic3ViIjoiMjNsMzRqZHNsZjkyIn0.kjIKpi9eTXz4LaSC8Ui4Nou_f C8ssTob6yqUAffRQACS1WRv1vGKdYWJNODtPg1G6h5t9T8eMnEvvzH5NhVovN-oFVaS8ZExRFycUHUY_ D-54QySGdRdvcR_6M4qKO-KKwaAxrIEwj9uj0jfW7Dg0OerladFigJ5xyuA7N27JupxRdFsgB-VlGTa0 6-KNS2_DZ5dsHnEfFuHwfmPCYlpasZUD07nvgyq74PMPyzrDCbPBS6SOxYz9Uff3Nl9Kit5QDLe7dlbp 0cSCtXPfzBe5BPTi64Wkr2OOD1t-bE2HsEKSkvWFWxPYMP9DE5_gz5jJXC4-3S6tLWbV7DjkvJD8iUip _DHEL3sGX95ELyHOCiY9BBNnPiNCPDgnsXGx2Dz2m2SpShoyq2etCZCxsDJWwjkBGwfWU_MfTLIu4r36 Ft5VXnXxA-Bz1DF6m78ImHK2EjrrHw1ZaGNqYAV42x9om0vhkn6xuUedPIYDbqOv5vysFNzWmKvQPjB_ u82w0WHNLIzP5rK4ybg7CjzDlxWgO2WEt-haMQp5EHKe-7BXlEboZwSx-EOQkGomgwoOHhorD4sMO3TV WLL4gXSY5RRuawpjGY9zqyQgYG6iDUQKBhGheRqasKuj2nwRlTfelKRyH4EKoGWa266vvDTWiO6H36mc EgSuYAdPFvs1ZRiMdQ
Non-Base64 encoded ID token
{ "alg": "PS256", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY", "typ": "JWT" } . { "ConsentId": "58923", "aud": "Z5O3upPC88QrAjx00dis", "auth_time": 1673219980, "c_hash": "ey3B5S_JgC_4UcRCcizagA", "exp": 1673220590, "iat": 1673219990, "iss": "https://as.apiprovider.co.nz", "jti": "5a301563-85fa-4c6b-9703-0ea5feda03fd", "nonce": "w8q2mp1-z0o5w3mVHf-Mlt", "s_hash": "QGelUn9KPtVuPjFGWXWfoA", "sub": "23l34jdslf92" } . <<signature>>

Note: The default response mode for Hybrid Flow (shown above) is fragment encoding. Third Parties may complete authorisation response processing through one of the following methods:

  • User Agent parses the response parameters and sends to the Client (Third Party) for processing. See OIDC core 1.0, section 3.3.2.7, and OIDC core 1.0, section 15.5.3

  • Client may specify response_mode as query, causing the authorisation response parameters to be encoded in query parameters, making them directly visible to the client (Third Party). If the query response mode is supported by the API Provider it will be indicated in authorisation server metadata response_modes_supported

  1. The Customer is then redirected to the Third Party. The Third Party will now possess the Authorization Code and ID Token from the API Provider. Note at this point, there is no Access Token. The Third Party will now introspect the ID Token and use it as a detached signature to check:

  • The hash of the Authorization Code to prove it hasn't been tampered with during redirect (comparing the hash value against the c_hash attribute in ID Token)

  • The hash of the State to prove it hasn't been tampered with during redirect (comparing the state hash value against the s_hash attribute in the ID Token)

Example: ID Token

Sourced from the NZ Security Profile Request Object section

{ "alg": "PS256", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY", "typ": "JWT" } . { "ConsentId": "58923", "aud": "Z5O3upPC88QrAjx00dis", "auth_time": 1673219980, "c_hash": "ey3B5S_JgC_4UcRCcizagA", "exp": 1673220590, "iat": 1673219990, "iss": "https://as.apiprovider.co.nz", "jti": "5a301563-85fa-4c6b-9703-0ea5feda03fd", "nonce": "w8q2mp1-z0o5w3mVHf-Mlt", "s_hash": "QGelUn9KPtVuPjFGWXWfoA", "sub": "23l34jdslf92" } . <<signature>>
  1. Once the state and code validations have been confirmed as successful by use of the ID Token, the Third Party will proceed to obtain an Access Token from the API Provider using the Authorization Code they now possess. The Third Party will present its Authorization Code together with the private_key_jwt. The Access Token is required by the Third Party in order to submit the Payment on behalf of the Customer. The 

payments scope should already be associated with the Authorization Code generated in the previous step.

Request : Access Token Request using Authorization Code and private_key_jwt
POST /as/token.oauth2 HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=authorization_code& code=g_0JnK9emAbw-LCPPAooR_Vgw0TmpmgmYz9a6qpoT0Q& redirect_uri=https://thirdparty.co.nz/redirect& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjczMjIwNTkyLCJpYXQiOjE2NzMyMTk5OTIsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiMmFhMjU0MWYtNGJlOC00MjYyLWJlMmEtN2VmMTAyNjRhZjQ1Iiwi bmJmIjoxNjczMjE5OTkyLCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.R0IgOEYhoNWWPildkhs wOAZeY3wnZAsiOQI7X83qEGR4MyaY9YsN-BKjwfd70z6wlLAjKV64M13x_uxEQJcQs3h76JeffGp1m9I REHvXYuM-8nCzc6n6SNhTI8vW09gf2prd81u4UF93zWfq_T3-c-yWA3OuxVWbF0cjmB-VX3ZMjUmvB5i hTAAwKL70t5XWj_4ph6r00TYl0QjOR_-gmmatjYfRKZvUsE6AHP3Q3P9saUoF0IO6PjohQ9yPZtlaiF- 73x6tiDvpgOc4bCohDnxq4WOxtc4u96Xp3gN3p3RLsq166-mK2AxBdi_sSXLrPitoi7aCJyJNUoRzVVx MrqdtJMbh2ThyJkCeXljOHOp0_BBME8igUaM5Y0vLON_Zig6noLMk_McdB-ZRlYm34fssSLxihgS4bWC _YrS6Ep6DfVWYIqXmZOLg2ZEbBEV8QSCrTL0IIXXCP8O3kGUOFShUymvZQj0rdZtACTUoJQ_i10QCp_K igxFQSIRBHyBZetBW7D28V-0rJen_Rk2INiiRvS6dLmd-XHK-sBb2xVpHKJ_Ro5x1Tah563PN0sk60Wa A1cztDm64pxV6cc7OfpKYHOmhsT2oXDe5yg0wE1Lp-Ae_tG2d3qD7jqCUA0eYXH6BRm_0WTMEmeR2Izc CesGrhs1YJUFxIn5UKJGHr3k
Non-Base64 JWT client_assertion
{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } { "aud": "https://as.apiprovider.co.nz", "exp": 1673220592, "iat": 1673219992, "iss": "Z5O3upPC88QrAjx00dis", "jti": "2aa2541f-4be8-4262-be2a-7ef10264af45", "nbf": 1673219992, "sub": "Z5O3upPC88QrAjx00dis" } . <<signature>>
Response : Access Token
HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "access_token": "iGNPnFetrevIpltXhGZKPTrhHVfGmLWW", "token_type": "Bearer", "expires_in": 3600, "id_token":"eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BB UU53MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiI1ODkyMyIsImF1ZCI6Ilo1T zN1cFBDODhRckFqeDAwZGlzIiwiYXV0aF90aW1lIjoxNjczMjE5OTgwLCJjX2hhc2giOiJleTNCNVNfS mdDXzRVY1JDY2l6YWdBIiwiZXhwIjoxNjczMjIwNTk0LCJpYXQiOjE2NzMyMTk5OTQsImlzcyI6Imh0d HBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubnoiLCJqdGkiOiJhNzQ2ZjQyYS0yYmE3LTQ2YjgtYmI3OC1jY mYyNWE3Mjg4OGIiLCJub25jZSI6Inc4cTJtcDEtejBvNXczbVZIZi1NbHQiLCJzX2hhc2giOiJRR2VsV W45S1B0VnVQakZHV1hXZm9BIiwic3ViIjoiMjNsMzRqZHNsZjkyIn0.FQVQa4pU3RTEC9w17iO13zpe4 0N2Uyv9EX0OXRGEKumPwDF64tdVapQjPjTphEQpHdS7kXSP-5ExKTcfuozTY5XWICcV73xZe6zAdqbrc vQHWADNKFDGaGI6isWHhOknieX6stxSYbvg0dMmViDGjlfEnicUDcTkmVRJVQwEX_COiRmuPIKqJHH5F ilHptDKd6IMIuf15x0tafQGacvHe2T7Jrou_g7dla-jG1Ar7ZONdEr7t4l4-nmnTh-R58IQyNdrSW1k0 -2K1Ethq1fsbJ9_cbUq-JugUNKUMiXM27a3ZN03FXAvYPNuZ22Hw7a-jqvP-IWKF9lj0I_Y2X6zKZlTJ WbqM4p4BKBZzngNEL8Z8fW-2tt4xUWismJLOIBp7kW-2Bio7Pf-S3_AiCa5ij89k7kNqzuBfHIJS3jkA Qt8p_5VDPOieKnWQSrMaQDisya2ymfqCiXISPT5qMzIx5yR5iIKvDcT3jfG9-zIc52AqewTH7Y-hNa5X sfkm9u4nNVIAkBXOk-EqP05-YayQSHUUxtz-OVTS4f-vv3jcnXfgYVNFK0fsys8xaMTBpYn4RVenMQF- i-o3BAvUv43Envpsory6SbD1n32PfH2ulbtvPAUpzPJgaCbB_f-SwwNDo0EGuAqhVwwKFMWMqQ-KJPj3 UtAJK8vPE3VaVCrqyA" }

Step 4 - Create Payment-Order

  1. The Third Party has an Access Token which can be used to create a Payment-Order resource (Step 4). The Third Party must obtain the ConsentId so that the Payment-Order resource is associated with the correct ConsentId. This will be sourced from the ConsentId claim from the signed ID Token (default). The Third Party will need to decode the ID Token JWT and locate the claim attribute associated with the ConsentId.

  1. The Third Party can now create the payment-order resource at the /domestic-payments endpoint to submit the payment-order for processing using the Access Token and ConsentId in the payload of the request. This example is sourced from the Payment Initiation API Specification

Request : domestic-payments
POST /domestic-payments HTTP/1.1 Authorization: Bearer iGNPnFetrevIpltXhGZKPTrhHVfGmLWW x-idempotency-key: THIRDPARTY.1317.GFX.22 x-fapi-customer-auth-date: 2023-01-09T11:36:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 134f525f-1819-498a-ae48-707727bd1349 Content-Type: application/json Accept: application/json { "Data": { "ConsentId": "58923", "Initiation": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "THIRDPARTY.21302.GFX.20", "InstructedAmount": { "Amount": "165.88", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "08080021325698", "Name": "ACME Inc", "SecondaryIdentification": "0002" }, "RemittanceInformation": { "Reference": { "CreditorName": "The Creditor", "CreditorReference": { "Particulars": "CreditorPart", "Code": "CreditorCode", "Reference": "CreditorRef" } } } } }, "Risk": { "PaymentContextCode": "EcommerceGoods", "MerchantCategoryCode": "5967", "MerchantCustomerIdentification": "053598653254", "DeliveryAddress": { "AddressLine": [ "Flat 7", "Acacia Lodge" ], "StreetName": "Acacia Avenue", "BuildingNumber": "27", "PostCode": "1010", "TownName": "Auckland", "CountySubDivision": [ "Auckland Central" ], "Country": "NZ" } } }
Response : domestic-payments
HTTP/1.1 201 Created x-fapi-interaction-id: 134f525f-1819-498a-ae48-707727bd1349 Content-Type: application/json { "Data": { "DomesticPaymentId": "58923-001", "ConsentId": "58923", "Status": "AcceptedSettlementInProcess", "CreationDateTime": "2023-01-09T12:19:55+13:00", "StatusUpdateDateTime": "2023-01-09T12:20:02+13:00", "Initiation": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "THIRDPARTY.21302.GFX.20", "InstructedAmount": { "Amount": "165.88", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "08080021325698", "Name": "ACME Inc", "SecondaryIdentification": "0002" }, "RemittanceInformation": { "Reference": { "CreditorName": "The Creditor", "CreditorReference": { "Particulars": "CreditorPart", "Code": "CreditorCode", "Reference": "CreditorRef" } } } } }, "Links": { "Self": "https://apiprovider.co.nz/open-banking/v3.0/domestic-payments/58923-001" }, "Meta": {} }

 

Step 5 - Get Domestic-Payment Status

  1. The Third Party can query for the status of a domestic-payment resource by invoking the /domestic-payments using the known DomesticPaymentId. This can use an existing access token with the 

payments scope or the Third Party can obtain a fresh access token by replaying the client credentials grant request as per Step 2.

Request: domestic-payments/{DomesticPaymentId}
GET /domestic-payments/58923-001 HTTP/1.1 Authorization: Bearer iGNPnFetrevIpltXhGZKPTrhHVfGmLWW x-fapi-customer-auth-date: 2023-01-09T11:36:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 961857e9-bc6b-4cac-ae82-7c05bbccfb3d Accept: application/json
Response: domestic-payments
HTTP/1.1 200 OK x-fapi-interaction-id: 961857e9-bc6b-4cac-ae82-7c05bbccfb3d Content-Type: application/json { "Data": { "DomesticPaymentId": "58923-001", "ConsentId": "58923", "Status": "AcceptedSettlementInProcess", "CreationDateTime": "2023-01-09T12:19:55+13:00", "StatusUpdateDateTime": "2023-01-09T12:20:02+13:00", "Initiation": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "THIRDPARTY.21302.GFX.20", "InstructedAmount": { "Amount": "165.88", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "08080021325698", "Name": "ACME Inc", "SecondaryIdentification": "0002" }, "RemittanceInformation": { "Reference": { "CreditorName": "The Creditor", "CreditorReference": { "Particulars": "CreditorPart", "Code": "CreditorCode", "Reference": "CreditorRef" } } } } }, "Links": { "Self": "https://apiprovider.co.nz/open-banking/v3.0/domestic-payments/58923-001" }, "Meta": {} }
  1. A Third Party can also optionally query for the status of a domestic-payment-consent resource by invoking /domestic-payment-consents/{ConsentId}. This can use an existing access token with

payments scope or the Third Party can obtain a fresh access token by replaying the client credentials grant request as per Step 2.

Authorization Code Flow

The implementation is based on the following known configurations:

Client types

Grant types

Client Credentials grant type

This is with scope payments

  • The Client Credentials Grant Type is used when the Third Party requires an Access Token (on behalf of itself) in order to access a consent resource

  • Only valid API scopes will be accepted when generating an Access Token (i.e., payments)

  • Access tokens generated by a Client Credentials grant may not return any refresh tokens (as per the OAuth 2.0 specification)

Authorization Code Flow

This is with response_type "code"

  • The Payment Initiation APIs illustrate the use of "response_type": "code" for the OIDC Authorization Code Flow implementation

  • The API Provider may optionally choose to return Refresh Tokens for the Authorization Code Flow when issuing an Access Token

Access Tokens

  • For the Payments and Accounts APIs, the Access Token must be obtained within a Secure, Server Side Context between the Third Party and the API Provider

  • Access Tokens must be validated by the Third Party as outlined within OIDC

Refresh Tokens

  • API Providers may optionally return a Refresh Token when an Authorization Request is successfully processed at the Token endpoint. The Hybrid flow supports the provisioning of Refresh Tokens.

  • Refresh Tokens must be validated as outlined in OIDC

ID Tokens

  • ID Tokens must be validated by the Third Party as outlined within OIDC

  • Third Parties must use the ConsentId claim to populate and retrieve the ConsentId for any required validation

  • The full set of claims that can be represented within an ID Token are documented in the Request Object and ID Token sections of the Security Profile

Authorization Codes

  • Authorization Codes are returned within a JARM response JWT

  • Only signed JARM responses are supported (no encryption)

  • Authorization Codes must be validated by the Third Party as outlined within JARM

Pushed Authorization Requests

As per FAPI 1.0:

  • Pushed Authorization Requests (PAR) may be used to send Request Object from Third Party to API Provider.

  • JWT-Secured Authorization Request (JAR) is used to deliver Request Object.

This Security Profile requires PAR is used with Authorization Code Flow.

Proof Key for Code Exchange

FAPI 1.0 requires PKCE is used with PAR.

  • Only S256 is supported for code_challenge_method

  • Section 7.1 of PKCE specifies the code_verifier should be a minimum of 256 bits, or 32 ASCII characters encoded using URL-safe base64 (total 43 characters). The authorisation server may reject lower-entropy code_verifier values.

FAPI JWT-Secured Authorization Response Mode (JARM)

FAPI 1.0 requires JARM ("response_mode":"jwt") when using Authorization Code Flow ("response_type": "code")

Unspecified Behaviour

The implementation guide does not illustrate the following configurations in this section.

Client Types

  • Public clients - as only confidential clients are allowed in the NZ Security Profile

Grant Types

  • OIDC Hybrid Flow (specified in Hybrid Flow section of Security Profile)

  • OIDC Implicit Flow (response_type = "id_token" or "id_token token")

    • "id_token" does not allow for access token issuing

    • "id_token token" forces exposure of access token to user agent

  • Client Credentials Grant Type (scope = "openid email profile")

    • Requesting OIDC specific scopes or any unspecified scopes when using the Client Credentials grant

Validity Lengths

These are to be managed in the competitive space - so different validity lengths are not illustrated. Each API Provider's Authorization / Resource Server will be configured independently to comply with internal API Provider Security Policies and Guidelines. The Accounts and Payments API Specifications do not mandate validity lengths.

Authorization Code

  • OAuth 2.0 Specification suggests an Authorization Code should be short lived to a maximum of 10 minutes. Any codes exceeding this limit to be rejected

ID Token

  • ID Token claims (exp and iat) determine its validity

  • Returned with the token response when the Authorization Code flow is used

Access Token

  • The expires_in attribute returned by the Authorization Server when an Access Token is generated determines its validity

  • Access Tokens are generally short lived, and where they expire, are then exchanged for another using a longer lived Refresh Token

  • Refer to Section 16.18 of OIDC - Lifetimes of Access Tokens and Refresh Tokens.

Refresh Token

  • Refresh Tokens are generally longer lived in comparison to Access Tokens

  • Refresh Token Introspection may be used to retrieve the Refresh Token expiry
    Refer to Section 16.18 of OIDC - Lifetimes of Access Tokens and Refresh Tokens

Success Flows

The sequence diagram below highlights the OAuth 2.0 Client Credentials Grant and OIDC Authorization Code Flow that are used by the Payments API.

 

@startuml Authorization Code Flow participant Customer #LightYellow participant "Third Party" as TPP #LightYellow participant "API Provider Authorisation Server" as AS #LightYellow participant "API Provider Resource Server" as RS #LightYellow autonumber 1 Customer -> TPP: Establish TLS 1.2/1.3 note over Customer, RS Step 1: Agree payment consent end note Customer -> TPP: Agree payment consent note over Customer, RS Step 2: Create payment consent end note TPP <-> AS: Establish TLS 1.2/1.3 MA note left of TPP Client Credentials Grant end note TPP -> AS: POST /token (client authentication credentials, scope:payments) AS -> AS: Validate client authentication credentials, scope AS -> AS: Validate client_id matches client SSL cert AS -> TPP: HTTP 200 (OK) access-token (scope:payments) TPP <-> RS: Establish TLS 1.2/1.3 MA TPP -> RS: POST /domestic-payment-consents (access-token - scope:payments) RS -> RS: Validate access token RS -> RS: Validate scope:payments RS -> RS: Validate client_id matches client SSL cert RS -> RS: Create new domestic-payment-consent resource RS -> RS: Bind ConsentId with client_id RS -> TPP: HTTP 201 (Created), ConsentId note right of TPP Begin OIDC Authorization Code Flow. See OpenID Core 6.1. Passing a Request Object by Value See FAPI 1.0 Advanced, PAR requests & PKCE See OpenID Core 5.5. Requesting Claims using the "claims" Request Parameter The claims parameter must at least request: "id_token": { "ConsentId": {"value": ConsentId, "essential": true} } The request object must be signed using the Third Party's private key. end note TPP -> TPP: Persist ConsentId note right of TPP The Third Party should store the ConsentId in a manner that it can be retrieved again later in the flow in Step 4. This could be stored in the user session (and retrieved using 'state' as a key) or the Customer could use some other unique identifier. This will be re-retrieved in [42]. end note note over Customer, RS Step 3: Authorize consent end note TPP -> TPP: Create signed request object with requested Claims (ConsentId), state, nonce, nbf, exp\ncode_challenge, code_challenge_method=S256, response_type=code, response_mode=jwt TPP -> AS: POST /par with JAR (request=signed JWT), and 'private_key_jwt' client authentication. AS -> TPP: 201 Created; request_uri, expires_in TPP -> Customer: HTTP 302 (Found); Location: /authorize,\nrequest_uri, client_id Customer -> AS: HTTP GET /authorize request_uri, client_id AS -> AS: Validate request_uri, client_id AS -> AS: Validate JWT request claim - ConsentId, scope, redirect_uri, nbf, exp note right of AS Validate the request object by using the Third Party's public key. Third Party certificate will be identified using the kid claim in the JOSE header of the request object. Check that the ConsentId belongs to the client_id that initiated the request. end note AS <-> Customer: Authenticate (login and agree consent) Customer <-> AS: Select debtor account if necessary AS -> RS: Update Consent Status to Authorised RS -> AS: OK note right of AS Implementation of how the resource is updated is API Provider specific. (There is no standardised API for this) end note AS -> AS: Generate authorization-code, JARM response token 'id_token claims:{ 'c_hash: 123, 's_hash: 456 '} 'The generation of c_hash is documented in OIDC: 3.3.2.11. ID Token 'The generation of s_hash is in FAPI R/W spec: Section 5.1 'http://openid.net/specs/openid-financial-api-part-2-wd-02.html#introduction note right of AS JARM Response must be signed using the API Provider's private key. https://openid.net/specs/openid-financial-api-jarm.html#signing-and-encryption end note AS -> Customer: HTTP 302 (Found); Location: redirect-uri (response=JWT) Customer -> TPP: HTTP GET redirect-uri (response=JWT) TPP -> TPP: Validate signature on JARM JWT note right of TPP Validate the JARM JWT by using the API Provider's public key. API Provider certificate will be identified using the kid claim in the JOSE header of the JARM JWT end note TPP -> TPP: Validate authorization-code using JARM Section 4.4\nhttps://openid.net/specs/openid-financial-api-jarm.html#processing-rules note right of TPP Exchange authorization-code for access token. end note TPP <-> AS: Establish TLS 1.2/1.3 MA TPP -> AS: HTTP POST /token (client authentication credentials,\n authorization-code, grant_type, redirect_uri, code_verfiier) AS -> AS: Validate client_id matches client SSL cert AS -> AS: Validate client authentication credentials,\n authorization-code AS -> AS: Generate access-token AS -> AS: Bind access-token to ConsentId AS -> AS: Validate code_verifier against code_challenge supplied in PAR request [17] AS -> TPP: HTTP 200 (OK) access-token (scope:payments) note over Customer, RS Step 4: Create domestic payment end note TPP <-> RS: Establish TLS 1.2/1.3 MA TPP -> TPP: Retrieve ConsentId note left of TPP Retrieve the ConsentId that was issued in Step 2. The method for doing this will depend on how the Third Party persisted the payment id in [16] end note TPP -> TPP: Decode / verify JARM token TPP -> TPP: Read ConsentId from JARM token claims TPP -> TPP: Compare with ConsentId retrieved in [42] TPP -> RS: POST /domestic-payments (access-token - scope:payments) using ConsentId RS -> RS: Validate access-token RS -> RS: Validate access-token matches client SSL cert RS -> RS: Validate scope:payments note right of RS Check binding created in [38] end note RS -> RS: Ensure access-token is bound to ConsentId RS -> RS: Update domestic-payment Status to AcceptedSettlementInProcess RS -> TPP: HTTP 201 (Created), DomesticPaymentId note over Customer, RS Step 5: Get domestic payment status end note opt TPP <-> RS: Establish TLS 1.2/1.3 MA alt Use active access token to retrieve domestic-payment status TPP -> RS: GET /domestic-payments/{DomesticPaymentId} (access-token - scope:payments) RS -> RS: Validate access-token RS -> RS: Validate access-token matches client SSL cert RS -> RS: Validate scope:payments RS -> TPP: HTTP 200 (OK), domestic-payments resource end alt end opt @enduml

Client Credentials Grant Type (OAuth 2.0)

This grant type is used by the Third Party in Step 2 to setup a single payment with the API Provider.

  1. The Third Party initiates an Authorization request using valid Client Credentials Grant type and scope(s)

  2. The API Provider Authorization Server validates the Client Authentication request from the Third Party and generates an Access Token response where the request is valid

  3. The Third Party uses the Access Token to create a new Payment resource against the API Provider Resource Server

  4. The API Provider Resource server responds with the ConsentId for the resource it has created

  5. The Client Credentials Grant may optionally be used by the Third Party in Step 5 to retrieve the status of a consent resource

Authorization Code Flow

  • The Authorization Code flow is mandated as the redirect flow for the NZ Security Profile.

  • FAPI 1.0 Final advanced required JARM responses

  • This Security Profile requires Pushed Authorization Requests (PAR), using signed Authentication Request objects (JAR) with Proof-Key for Code Exchange (PKCE)

  • This is initiated at the end of Step 2 by the Third Party after the ConsentId is generated by the API Provider and returned to the Third Party

  • This is used in a redirect across the Customer and API Provider in Step 3 in order for the Customer to authorize consent with the API Provider

  • This is used across the Third Party and API Provider in Step 4 by exchanging the Authorization Code for an Access Token in order to create the domestic-payment resource

Non-Normative HTTP Request and Response Examples

Step 1 - Agree Payment Consent

There are no Requests and Responses against the Payments API in this Step for the Customer, Third Party and API Provider.

Step 2 - Setup Payment-Order Consent

  1. Third Party obtains an Access Token using a Client Credentials Grant Type. The scope payments must be used. When an Access Token expires, the Third Party will need to re-request for another Access Token using the same request below.

Request: Client Credentials using private_key_jwt

POST /as/token.oauth2 HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=client_credentials& scope=payments& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcwODEwNjU3LCJpYXQiOjE2NzA4MTAwNTcsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiN2U3MzE5YzItYTUyMS00OWQzLTkzOWMtNjEwYmZkMTQ3MzljIiwi bmJmIjoxNjcwODEwMDU3LCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.K3v_ib31h6NID37BWkq ytjNdTkMgYGaVlYp4_B46KpCt6TqLpwuFbaDT5InhRpPyEhKm95QwHBiA3tfcdHpz-u3TCuFhnlhcodQ tjjcKvZl7c2nXP7ZB_hAto-_1SfvKLA_XPy-eiD-C36I-RjttPTuGaM1nOc6fonTC-UelbUl0wt9pPtZ T8oEqXHlTOeTLxaHV1gDMgFdsgsY6zQVwjuqSUrwskQz5QDdL0LLaxdlprK0qE7KoBQEyDvPgMnCufKI YQz9p1c89bjFmjUJZlC35nJzBTZasmP-1Yuq5SHb3XvK64twWL-epON6zKy80j3LMrJBMDGSZufREy9Y n_r7d3FU8TECDsYev5d4ObcPLYw83K9ZXvg4xt8sQoVlOgCKFSEeC6gu_tVtuRS7AJNCF4gHXF2EfciR 9wrvLMHJ1l1hj9LMx_0-nx14kfW2ZvRzyKc89qnxB1Cs1Ie5lHG2n1ux5w_bchaM6UR4Z6yp_V7UGfhs H1eKofrydiogY_TNmOvKao01_EZ6yG_B91nBG_y5k5hvy5yd5SaxQPB7zURyd2rxZPGAmtvbmGxi_hte 57emkxkzYuNmjYqusNGel6_L17AfatPFSBIZnnz1AFjvUJzAm5R0nxm9KqdYVJZt2owkQWpmYh9rL67K h5KlugSH5K9OaaHssCwPcRJ4

Decoded JWT client_assertion

{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "aud": "https://as.apiprovider.co.nz", "exp": 1670810657, "iat": 1670810057, "iss": "Z5O3upPC88QrAjx00dis", "jti": "7e7319c2-a521-49d3-939c-610bfd14739c", "nbf": 1670810057, "sub": "Z5O3upPC88QrAjx00dis" }

Response: Client Credentials

HTTP/1.1 200 OK Content-Length: 117 Content-Type: application/json Date: Mon, 12 Dec 2012 15:18:28 GMT { "access_token": "2YotnFZFEjr1zCsicMWpAA", "expires_in": 3600, "token_type": "bearer", "scope": "payments" }

 

  1. Third Party uses the Access Token (with

payments scope) from the API Provider to invoke the payment-order consent API.

Request: domestic-payments-consents

POST /domestic-payments-consent HTTP/1.1 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA x-idempotency-key: thirdparty-21344534 x-fapi-auth-date: 2022-12-15T10:54:55 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: f83c1b10-7c11-11ed-9b1d-00155d0c7207 x-merchant-ip-address: 93.184.216.34 x-customer-user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Content-Type: application/json Accept: application/json { "Data": { "Consent": { "InstructionIdentification": "thirdparty-pay-12345", "EndToEndIdentification": "e2e.purch.12345.to.234", "DebtorAccountRelease": true, "InstructedAmount": { "Amount": "155.25", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "00-0012-1102111-22", "Name": "Payment Acct" }, "RemittanceInformation": { "Reference": { "CreditorName": "Creditor Name", "CreditorReference": { "Particulars": "Online", "Code": "Goods", "Reference": "Purchase" }, } } } }, "Risk": { "GeoLocation": { "Latitude": "-41.205173", "Longitude": "174.876798" }, "PaymentContextCode": "EcommerceGoods", "MerchantCategoryCode": "5967", "MerchantCustomerIdentification": "string", "DeliveryAddress": { "AddressType": "DeliveryTo", "AddressLine": [ "Acacia Avenue" ], "StreetName": "Acacia Avenue", "BuildingNumber": "221b", "PostCode": "4321", "TownName": "Wellington", "CountrySubDivision": "Lower Hutt", "Country": "NZ" } } }

Response: domestic-payments-consents

HTTP/1.1 201 Created x-fapi-interaction-id: f83c1b10-7c11-11ed-9b1d-00155d0c7207 Content-Type: application/json { "Data": { "ConsentId": "consent-1234", "Status": "AwaitingAuthorisation", "CreationDateTime": "2022-12-15T10:57:52.877Z", "StatusUpdateDateTime": "2022-12-15T10:57:52.877Z", "Consent": { "InstructionIdentification": "thirdparty-pay-12345", "EndToEndIdentification": "e2e.purch.12345.to.234", "DebtorAccountRelease": true, "InstructedAmount": { "Amount": "155.25", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "00-0012-1102111-22", "Name": "Payment Acct" }, "RemittanceInformation": { "Reference": { "CreditorName": "Creditor Name", "CreditorReference": { "Particulars": "Online", "Code": "Goods", "Reference": "Purchase" }, } } } }, "Risk": { "GeoLocation": { "Latitude": "-41.205173", "Longitude": "174.876798" }, "PaymentContextCode": "EcommerceGoods", "MerchantCategoryCode": "5967", "MerchantCustomerIdentification": "string", "DeliveryAddress": { "AddressType": "DeliveryTo", "AddressLine": [ "Acacia Avenue" ], "StreetName": "Acacia Avenue", "BuildingNumber": "221b", "PostCode": "4321", "TownName": "Wellington", "CountrySubDivision": "Lower Hutt", "Country": "NZ" } }, "Links": { "Self": "https://api.provider.co.nz/open-banking-nz/v3.0/domestic-payment-consents/consent-1234", }, "Meta": { } }

The Third Party as received a ConsentId to use in customer consent.

Step 3 - Pushed Authorization Request (PAR)

  1. Third Party creates and submits Authorization Request JWT to directly to API Provider PAR endpoint.

  2. PAR request includes PKCE claims and ConsentId for the consent the customer should authorise

  3. The request is a PAR request, requiring a JARM response ("response_mode": "jwt")

  4. Third Party receives a request_uri from the API Provider which is used as part of customer redirection

Request: OIDC Authorization Code Flow using PAR

Sourced from the NZ Security Profile

POST /as/par HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcxMDU1Njk2LCJpYXQiOjE2NzEwNTUwOTYsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiZTExYmM4MzMtN2FmMy00YmQ1LThmNDEtMDIzNzk1YjczYjc1Iiwi bmJmIjoxNjcxMDU1MDk2LCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.aLlb36nUTzpACl1vOiX mAeWxyoErK05FL8la4neB24NI5SbnIBh9PiSqq4X-Z43LFbnfb3zwEE6BVkwfVaLsX8LIo-PAFqK5zXC H-yXzC0xvOxRc02wVVohfmt3okjNh8cKl7hJb4m9A3LylzIWeeCmZRfMOSdA8JdP39jP5gPqoZDloThB eo2ohjslrfOvkYM7LbetzPFiEvTEC3T0_-CRuc6JtKM4vvFtiMnoUePdjrj7UxIgk2RQsre5miXuumFk QrchS8A29IWGTYdXeuCfLJBcJW_eTymHYIjb8c9XNr-5wBkhpD6qeDngJBC5LzurY6eg87JmgEg8KEMo GqwxG5SSPUa74qjkiv3Kn1SSJfNa3SslAMxFsv_1nl5z1iWSAoHWrBdjktpi_9d_Bkksd6ynQouC0DFW SA7omAvc6pEWYoz6lfuDEItgFWchcK--_Os86WYRABUAguBUQ1JA5-nu_hhV3acPB6KiDUm4GVolAOVn ENW1qq2LNX7SDGVW8IJ7f5F0FRA0gRt1GsTEd-VPsg9LLhmwlKcSSgN4C0Is5jKRH-mdHKmhOaxOmORc 00eeHCff5VVwxKClO9X870vAqM8lz1uMvOyikju0gpodH3kZ1EShoOGONcx_aCrLlMkJzuGDSXLtcj95 Yv2jyKHngbUOjwbSza_FHQ1Q& client_id=Z5O3upPC88QrAjx00dis& request=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5xTzZlOEFK WEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3ZpZGVyLmNvL m56IiwiY2xhaW1zIjp7ImlkX3Rva2VuIjp7IkNvbnNlbnRJZCI6eyJlc3NlbnRpYWwiOnRydWUsInZhb HVlIjoiY29uc2VudC0xMjM0In19fSwiY2xpZW50X2lkIjoiWjVPM3VwUEM4OFFyQWp4MDBkaXMiLCJjb 2RlX2NoYWxsZW5nZSI6Ind4a28zV3JzMGhDOHppY2Q5cHRGRmNMMmNTa252OWlaSHNURFI5VUdNM0EiL CJjb2RlX2NoYWxsZW5nZV9tZXRob2QiOiJTMjU2IiwiZXhwIjoxNjcxMDU1NzA3LCJpYXQiOjE2NzEwN TUxMDcsImlzcyI6Ilo1TzN1cFBDODhRckFqeDAwZGlzIiwianRpIjoiMmM1ZDg4NzEtNjYyMi00NGMzL WI1NDctMTRlN2NjNjBhZWVmIiwibmJmIjoxNjcxMDU1MDk3LCJub25jZSI6IjIzNG5hc2QtMzI0YmRzY S0zMjQiLCJyZWRpcmVjdF91cmkiOiJodHRwczovL3RoaXJkcGFydHkuY28ubnovcmVkaXJlY3QiLCJyZ XNwb25zZV9tb2RlIjoiand0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJzY29wZSI6Im9wZW5pZCBhY 2NvdW50cyBwYXltZW50cyIsInN0YXRlIjoic2FkcmV3dmRIQVNEVEFXIn0.GOuKbi-vZcjhDcWR0qBgq 4JRaLuR3XRF1yfBZamYngo_3rgLX5F9I-0MfsiyCGMzeo1j-FjsUNxnBfqYlvuYrqQRNWqVow_e_m9H_ RYit33PwZZ2SypJ-CIbWChbexg9_LdhPibH6tHjkqqC1Eloq09GMcAfAoQBG-A19xGTJcLlUEWbw7Wil qe-ih-1WZj6mopadEKKAJSXBA88SiaBH2BsV0pw149tHofYv0ZB6J1aAcnlX374ovYbwhTqraun-W5hd ykqJCFZ9HUN-qv0I0QD3WJtEyNSIGnUPRDHPjBY7lZK2kNxVez4MCgQ-k15MdUWtjj3fN4q7UfxTV-li iyCBVPHht-KJVNKJOYe8hpfEl4CLzBQUbV1atHZKD1PsAAMN7yYOKS6nz6mEZY9VCztaGNzX7UhGDxck S8mXjjzgBngEhm3-0dn13qQfr5VmUbElroJ4x8wAV2JNoxXjlHt4W0uidxTMne0wmgSb-0kKrur89-Ne SbQztI_BH1EHa4y71o52-MWb_77x4LVYuNqrOJ4FwwJFssgZL_dtiOIvqwwbwUgruT3QWJrQICTnBAsM HgfRPdSbeyyu8rp5YCwx8Qwt_YhiFIyhcbhV_RgBKxrklBVkHzkkVFs_I6KhPYm8AavxZMAqHguSuqMd OVDnssjtRLexK8z91TWB7U

Decoded request object JWT:

{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "aud": "https://as.apiprovider.co.nz", "claims": { "id_token": { "ConsentId": { "essential": true, "value": "consent-1234" } } }, "client_id": "Z5O3upPC88QrAjx00dis", "code_challenge": "wxko3Wrs0hC8zicd9ptFFcL2cSknv9iZHsTDR9UGM3A", "code_challenge_method": "S256", "exp": 1671055707, "iat": 1671055107, "iss": "Z5O3upPC88QrAjx00dis", "jti": "2c5d8871-6622-44c3-b547-14e7cc60aeef", "nbf": 1671055097, "nonce": "234nasd-324bdsa-324", "redirect_uri": "https://thirdparty.co.nz/redirect", "response_mode": "jwt", "response_type": "code", "scope": "openid accounts payments", "state": "sadrewvdHASDTAW" }

Response: OIDC Authorization Code Flow using PAR

HTTP/1.1 201 Created Content-Type: application/json Cache-Control: no-cache, no-store { "request_uri": "urn:ietf:params:oauth:request_uri:8qi1b0XAGrV9Ypv1cMyLAS_2AIchvqXx", "expires_in": 60 }

 

Step 4 - Authorise Consent with JARM response

Customer is redirected by Third Party to API Provider to grant consent.

Request: Redirect customer using request_uri

GET /authorize?client_id=Z5O3upPC88QrAjx00dis&request_uri=urn%3Aietf%3Aparams %3Aoauth%3Arequest_uri%3A8qi1b0XAGrV9Ypv1cMyLAS_2AIchvqXx HTTP/1.1 Host: as.apiprovider.co.nz

Once the customer has granted consent, they are redirected to the Third Party and a JARM response is provided. Because the JARM response is signed, there is no requirement for the ID Token as detached signature.

Response: JARM response in customer redirect

HTTP/1.1 302 Found Location: https://thirdparty.co.nz/redirect? response=eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BBUU5 3MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJaNU8zdXBQQzg4UXJBangwMGRpcyIsImNv ZGUiOiJnXzBKbks5ZW1BYnctTENQUEFvb1JfVmd3MFRtcG1nbVl6OWE2cXBvVDBRIiwiZXhwIjoxNjcx MDU4NzM3LCJpc3MiOiJodHRwczovL2FzLmFwaXByb3ZpZGVyLmNvLm56Iiwic3RhdGUiOiJzYWRyZXd2 ZEhBU0RUQVcifQ.zsEYMBnwIcgtqzpgk3CVMzhhl8g1AGAL5RBpHesHh3BpSa97tFEAMuKtVMoY2TdAq 3J8_k6QUe0BVOV-GGFVjpr0N029akFZ2sdscES5NkRgTUWWyVlAcukT4vEDcpWmxg223NDJsNJw63tJD dMFPpLZi-MJ6mWalk6NLIXfRoB8NND0fdsWaEt_JNW4Dbv_4yotIEf5fAvsCpIJCvca3ZqF3gbAqnptW FpHb1N6-v-HFYJzs2sBWAcPcpjBeIbcbm_7W2vnMv5OEPRAFTNoiB8C4vYTkbhqgeceoNeT6chPnlPqK EVkYo_O7ept7eB9xODg3KF6915t1sCMIeNkwLvK_HQ7cycEM9zgYMJCffqBEOO5B-DqmXt2DZwVBNYzq LdMnCSvTm16bMTWNfk1fGwzRbqAf0Jt7K_MHF5mBeHXRRM5-lXlduENtp9Eg1J4zhiBmUI8tv3-seRy6 k_nZWQ8m66bidSyQqhCFavqg7JXiLpPjBFNR0iKvTrloGAc4XFTOyNEQorj-RevAY8PdM-Oqk7iWJqr2 nlQLfZyD1HMWnRpLMxSlRQDahqSMND_sVtDDqKw5ip6jFiZ2gce4412Q60i2sejjNFbHmgjIpmfXQ5_n uSnkgPUUZ0yucCLvvn9huCFlSklGgeVHwUt-1ATD3G4VCd5OnRD_8w7OiA

Decoded JARM response:

{ "alg": "PS256", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY", "typ": "JWT" } . { "aud": "Z5O3upPC88QrAjx00dis", "code": "g_0JnK9emAbw-LCPPAooR_Vgw0TmpmgmYz9a6qpoT0Q", "exp": 1671058737, "iss": "https://as.apiprovider.co.nz", "state": "sadrewvdHASDTAW" }

The Third Party must process the JARM response JWT according to section 4.4 of JARM

Additionally, the Third Party must validate the ConsentId claim and refuse further processing if it does not match the expected value.

Step 5 - Retrieve Tokens

The Third Party will now possess the Authorization Code from the API Provider. The Third Party can now obtain tokens from the token endpoint using the authorization code and private_key_jwt for authentication.

The Third Party will present its Authorization Code together with the private_key_jwt. The Access Token is required by the Third Party in order to submit the Payment on behalf of the Customer. The payments scope should already be associated with the Authorization Code generated in the previous step.

Request: Access Token request using Authorization Code and private_key_jwt

POST /as/token.oauth2 HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=authorization_code& code=g_0JnK9emAbw-LCPPAooR_Vgw0TmpmgmYz9a6qpoT0Q& redirect_uri=https://thirdparty.co.nz/redirect& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcxMDU1NzMxLCJpYXQiOjE2NzEwNTUxMzEsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiNWM5MzU0ZDAtZWZmYi00YzE2LTg1NzQtZTJhOGIzMmJkZjg1Iiwi bmJmIjoxNjcxMDU1MTMxLCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.QSXJaEZHm_IQEW9wuTv kbiNI_SvlsNnsCOWWJXBHQvFbYYHOuOQz3JECkEi7scMvKrKVjQ5epxZ1nmxKhYHpugV8vPlelZpRAEE ltWT9kQfUTjvFYSs60iscfdlxiuCpv8F_jUSaAF6S9otYjKs17hYMnBqOzCHpShhdb6o5v_3w8kMDFvK DCa78_ymbCs4WFHTHKPZ_NSXgMzrUQUBXrjaTb8CRwf3OtWygaSOjH0EuZYoJ2EhC6ykyRJi_ZGMUjy7 c8ZtlTnrfF5LpWDy0XkwbkKCZfUJqBEZukDcTjlv_Xt63Omg-qWkm6ly241eRtI7D43zoR64eAulY923 KD9AYxf7zFXGDn-kOjf-ssh1d2ZDk6iOddNadJv1Hu_WUawjmVqeRfAAo2mMOVBcRWujKQH744729Ow- oj5BG8QMSexzk4Q-8EHfhYzBbp___Ee1UL4os1IC4I5NlKrImKkZJhb53fdgCsIvs-lL6BbDHyNSEdsM rHIjlrB0-JKw3pLteeU3Xcel44SQoLV_TXZjikI_c3Vg-5b5oj-JY94c5awh0pGGVYGJ8SifkkMnViNH VDbNdUNe-d1OoTZ9mqNRKKCmpMXYmIuJ3eIcJVodmHjA-f9cYSj5NM-H1ZjZdozOmNhfMbQ39BCQn49w f4N_pYe39hRLjUPOF-jsm08M& client_id=Z5O3upPC88QrAjx00dis& code_verifier=49e5ouLbBKEzjk9oTWmZXq2HmI2GnbH9cC5Bjqcvizz

Decoded client assertion:

{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "aud": "https://as.apiprovider.co.nz", "exp": 1671055731, "iat": 1671055131, "iss": "Z5O3upPC88QrAjx00dis", "jti": "f35a188a-5ad1-459e-bb8a-4915e40d8582", "nbf": 1671055131, "sub": "Z5O3upPC88QrAjx00dis" }

 

Response: Access Token

HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "access_token": "Hqh7hobWMFq0w5aPl8nMUo5PnG2DdQTejpadkQ-4zLM", "token_type": "Bearer", "refresh_token": "nub0HLu_PM-oJxbH5UkVyQVbU-c-OZ4_gp3kiISuoCH5sCN1jXkvLoxWrvY7i239", "expires_in": 600, "id_token":"eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BB UU53MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiJjb25zZW50LTEyMzQiLCJhd WQiOiJaNU8zdXBQQzg4UXJBangwMGRpcyIsImF1dGhfdGltZSI6MTY3MTA1NTEzMSwiY19oYXNoIjoiZ XkzQjVTX0pnQ180VWNSQ2NpemFnQSIsImV4cCI6MTY3MTA1NTc0MSwiaWF0IjoxNjcxMDU1MTQxLCJpc 3MiOiJodHRwczovL2FzLmFwaXByb3ZpZGVyLmNvLm56IiwianRpIjoiYzRhMjRmZTgtYTg1MC00NmZhL TliMDAtNTQ0N2Q2NWRiMmFiIiwibm9uY2UiOiIyMzRuYXNkLTMyNGJkc2EtMzI0Iiwic19oYXNoIjoiT WRBb2lGdTdIRTNSSEVSaHUyTXNlZyIsInN1YiI6IjIzbDM0amRzbGY5MiJ9.LQMQCMvkAOVF6_nH44UI hzih2p1idWUjd2PCgD356oiNIxydDGECDYC5taSoxafz5IR6057RyyhsjSBiDdjzOoNXJZq32xGEqL4N wd5ErgZVLP9Oj2xiPRsFUzAvIhmqGAVtl6sp3mZ8ZnHon_BZp1juNF5WYC25DYqucT5gAsb3-o1RBmkc tMA-wRXkH-kOO3r4NtfJk6ex-qGc-IPRme19NBqzNghqSt_z7UAdDpTsi9gqtkyevkeneoDD8TpJUwj8 awWBQWT_zqJ4aLxpco6CVGRpSoybWWPk4zA81VCElc41UQ4ZWZ7b-XEZfT_XPS19xuLliZj2h-wjs2td 2jvz5zk1VpUjVQrcuMevdAz0M_9Wa0N1ZBuX94DRuqSF_Kch7joVe0jXvpn98gF3dnM5P-x-_YFra1_F YEYIRPfGlSXZDA9gCtoCn4sI4VDTg_4eHSnG17YQXPzZK0qD09_e4D52zFvcbCOhYZ082cKEjjeXcJJb LMeG5t0Ss7cLwwcJiR3bFh06yUDZqJkBfVtfLdKyKzm3KL-YsUU1h7E0KA4uiEI_SwLz1gyNa1lkfY_C QtOEWTBb7WJenKafSOP7TuNub74uYsaLtVS8NzVjgLz0Qf-0jG4DGBIwybxvWBaH24JjeHl9xFL44mE8 ATv01zuD404mYTuk2Pmn7V0" }

Decoded ID Token:

{ "alg": "PS256", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY", "typ": "JWT" } . { "ConsentId": "consent-1234", "aud": "Z5O3upPC88QrAjx00dis", "auth_time": 1671055131, "c_hash": "ey3B5S_JgC_4UcRCcizagA", "exp": 1671055741, "iat": 1671055141, "iss": "https://as.apiprovider.co.nz", "jti": "c4a24fe8-a850-46fa-9b00-5447d65db2ab", "nonce": "234nasd-324bdsa-324", "s_hash": "MdAoiFu7HE3RHERhu2Mseg", "sub": "23l34jdslf92" } . <<signature>>

The Third Party may now introspect the ID Token and use it as a detached signature to check:

  • The hash of the Authorization Code to prove it hasn't been tampered with during redirect (comparing the hash value against the c_hash attribute in ID Token)

  • The hash of the State to prove it hasn't been tampered with during redirect (comparing the state hash value against the s_hash attribute in the ID Token)

Note: the s_hash and c_hash may be omitted since state and auth_code are protected from tampering in JARM JWT

Step 6 - Create Payment Order

  1. The Third Party has an Access Token which can be used to create a Payment-Order resource (Step 4). The Third Party must obtain the ConsentId so that the Payment-Order resource is associated with the correct ConsentId. This will be sourced from the ConsentId claim from the signed ID Token (default). The Third Party will need to decode the ID Token JWT and locate the claim attribute associated with the ConsentId.

  2. The Third Party can now create the payment-order resource at the /domestic-payments endpoint to submit the payment-order for processing using the Access Token and ConsentId in the payload of the request. This example is sourced from the Payment Initiation API Specification.

Request: domestic-payments

POST /domestic-payments HTTP/1.1 Authorization: Bearer Hqh7hobWMFq0w5aPl8nMUo5PnG2DdQTejpadkQ-4zLM x-idempotency-key: thirdparty-988761223 x-fapi-auth-date: 2022-12-15T1:54:55 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 1e703eba-7c12-11ed-8b9b-00155d0c7207 x-merchant-ip-address: 93.184.216.34 x-customer-user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Content-Type: application/json Accept: application/json { "Data": { "ConsentId": "consent-1234", "Initiation": { "InstructionIdentification": "thirdparty-pay-12345", "EndToEndIdentification": "e2e.purch.12345.to.234", "DebtorAccountRelease": true, "InstructedAmount": { "Amount": "155.25", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "00-0012-1102111-22", "Name": "Payment Acct" }, "RemittanceInformation": { "Reference": { "CreditorName": "Creditor Name", "CreditorReference": { "Particulars": "Online", "Code": "Goods", "Reference": "Purchase" }, } } } }, "Risk": { "GeoLocation": { "Latitude": "-41.205173", "Longitude": "174.876798" }, "PaymentContextCode": "EcommerceGoods", "MerchantCategoryCode": "5967", "MerchantCustomerIdentification": "string", "DeliveryAddress": { "AddressType": "DeliveryTo", "AddressLine": [ "Acacia Avenue" ], "StreetName": "Acacia Avenue", "BuildingNumber": "221b", "PostCode": "4321", "TownName": "Wellington", "CountrySubDivision": "Lower Hutt", "Country": "NZ" } } }

Response: domestic-payments

HTTP/1.1 201 Created x-fapi-interaction-id: 1e703eba-7c12-11ed-8b9b-00155d0c7207 Content-Type: application/json { "Data": { "DomesticPaymentId": "payment-1234-001", "Status": "AcceptedSettlementInProcess", "CreationDateTime": "2022-12-15T11:01:02.533Z", "StatusUpdateDateTime": "2022-12-15T11:01:07.954Z", "ConsentId": "consent-1234", "Initiation": { "InstructionIdentification": "thirdparty-pay-12345", "EndToEndIdentification": "e2e.purch.12345.to.234", "DebtorAccountRelease": true, "InstructedAmount": { "Amount": "155.25", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "00-0012-1102111-22", "Name": "Payment Acct" }, "RemittanceInformation": { "Reference": { "CreditorName": "Creditor Name", "CreditorReference": { "Particulars": "Online", "Code": "Goods", "Reference": "Purchase" }, } } } }, "Links": { "Self": "https://api.provider.co.nz/open-banking-nz/v3.0/domestic-payment-consents/consent-1234", }, "Meta": { } }

 

Step 7 Get Domestic-Payment Status

  1. The Third Party can query for the status of a domestic-payment resource by invoking the /domestic-payments using the known DomesticPaymentId. This can use an existing access token with the payments scope or the Third Party can obtain a fresh access token by replaying the client credentials grant request as per Step 2.

Request: domestic-payments/{DomesticPaymentId}

GET /domestic-payments/payment-1234-001 HTTP/1.1 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA x-fapi-customer-auth-date: 2022-12-15T1:54:55 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: d408ff8e-1b39-4b83-879e-bad34d0339f7 Accept: application/json

 

Response: domestic-payments

HTTP/1.1 200 OK x-fapi-interaction-id: d408ff8e-1b39-4b83-879e-bad34d0339f7 Content-Type: application/json { "Data": { "DomesticPaymentId": "payment-1234-001", "Status": "AcceptedSettlementInProcess", "CreationDateTime": "2022-12-15T11:01:02.533Z", "StatusUpdateDateTime": "2022-12-15T11:01:07.954Z", "ConsentId": "consent-1234", "Initiation": { "InstructionIdentification": "thirdparty-pay-12345", "EndToEndIdentification": "e2e.purch.12345.to.234", "DebtorAccountRelease": true, "InstructedAmount": { "Amount": "155.25", "Currency": "NZD" }, "CreditorAccount": { "SchemeName": "BECSElectronicCredit", "Identification": "00-0012-1102111-22", "Name": "Payment Acct" }, "RemittanceInformation": { "Reference": { "CreditorName": "Creditor Name", "CreditorReference": { "Particulars": "Online", "Code": "Goods", "Reference": "Purchase" }, } } } }, "Links": { "Self": "https://api.provider.co.nz/open-banking-nz/v3.0/domestic-payment-consents/consent-1234", }, "Meta": { } }

Decoupled Flow

The implementation is based on the following known configurations:

Client Types

Grant Types

Client Credentials Grant Type

This is with scope accounts

  • The Client Credentials Grant Type is used when the Third Party requires an Access Token (on behalf of itself) in order to access a consent resource

  • Only valid API scopes will be accepted when generating an Access Token (i.e., accounts)

  • Access tokens generated by a Client Credentials grant may not return any refresh tokens (as per the OAuth 2.0 specification)

CIBA Flow

  • The Account Information APIs illustrate the use of the CIBA Flow implementation

  • The API Provider may optionally choose to return Refresh Tokens for the Hybrid Flow when issuing an Access Token

Access Tokens

  • For the Accounts Information APIs, the Access Token must be obtained within a Secure, Server Side Context between the Third Party and the API Provider

Refresh Tokens

  • API Providers may optionally return a Refresh Token when an Authorization Request is successfully processed at the Token endpoint. The Hybrid flow supports the provisioning of Refresh Tokens

  • Refresh Tokens must be validated as outlined in OIDC

ID Tokens

  • ID Tokens must be validated by the Third Party as outlined within OIDC

  • Third Parties must use the ConsentId claim to populate and retrieve the ConsentId for any required validation

  • The full set of claims that can be represented within an ID Token are documented in the Request Object and ID Token sections of the Security Profile

Unspecified Behaviour

The implementation guide does not illustrate the following configurations in this section.

Validity Lengths

These are to be managed in the competitive space - so different validity lengths are not illustrated. Each API Provider's Authorization / Resource Server will be configured independently to comply with internal API Provider Security Policies and Guidelines. The Accounts and Payments API Specifications do not mandate validity lengths. 

ID Token
  • ID Token claims (exp and iat) determine its validity

  • A previously used ID Token may be used in the id_token_hint - we do not specify how this ID Token is issued (i.e., it may come from another OpenID flow other than the NZ Banking Data APIs)

Access Token
  • The expires_in attribute returned by the Authorization Server when an Access Token is generated determines its validity

  • Access Tokens are generally short lived, and where they expire, are then exchanged for another using a longer lived Refresh Token

  • Refer to Section 16.18 of OIDC - Lifetimes of Access Tokens and Refresh Tokens

Refresh Token
  • Refresh Tokens are generally longer lived in comparison to Access Tokens

  • Refer to Section 16.18 of OIDC - Lifetimes of Access Tokens and Refresh Tokens

Success Flows

The sequence diagram below highlights the OAuth 2.0 Client Credentials Grant and CIBA flow used by the Account Information API.

 

Account and Transactions API with Client Credentials Grant and CIBA flow
participant Customer participant Third Party participant API Provider Authorisation Server participant API Provider Resource Server autonumber 1 note over Customer, API Provider Resource Server Step 1: Agree account access consent end note Customer -> Third Party: Agree account access consent opt Customer <-> Third Party: Determine means of identifying Customer with the API Provider note left of Third Party This may either be - A previously used id_token which is used in the "id_token_hint" claim in the signed request object; or - A User Id, Third Party Generated Id or API Provider Generated Id used in the "login_hint_token" claim end note end note over Customer, API Provider Resource Server Step 2: Create account access consent resource end note Third Party <-> API Provider Authorisation Server: Establish TLS 1.2 MA note left of Third Party Client Credentials Grant end note Third Party -> API Provider Authorisation Server: POST /token (client authentication credentials, scope:accounts) API Provider Authorisation Server -> API Provider Authorisation Server: Validate client authentication credentials, scope API Provider Authorisation Server -> API Provider Authorisation Server: Validate ClientId matches client SSL cert API Provider Authorisation Server -> Third Party: HTTP 200 (OK) access-token (scope:accounts) Third Party <-> API Provider Resource Server: Establish TLS 1.2 MA Third Party -> API Provider Resource Server: POST /account-access-consents (access-token - scope:accounts) API Provider Resource Server -> API Provider Resource Server: Validate access token API Provider Resource Server -> API Provider Resource Server: Validate scope:accounts API Provider Resource Server -> API Provider Resource Server: Validate ClientId matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Create new account-access-consent resource API Provider Resource Server -> API Provider Resource Server: Bind ConsentId with ClientId API Provider Resource Server -> Third Party: HTTP 201 (Created), ConsentId note right of Third Party Begin CIBA Flow. See CIBA 7.1.1. Signed Authentication Request The claims must at include: "ConsentId": ConsentId; and "login_hint_token" or "id_token_hint" The request object must be signed using the Third Party's private key. end note Third Party -> Third Party: Persist ConsentId note right of Third Party The Third Party should store the ConsentId in a manner that it can be retrieved again later in the flow in Step 4. This could be stored in the user session (and retrieved using 'state' as a key) or the Customer could use some other unique identifier. This can be re-retrieved in [81] and [96]. end note Third Party -> Third Party: Create signed request object with requested Claims (ConsentId) note over Customer, API Provider Resource Server Step 3: Authorise consent end note Third Party -> API Provider Authorisation Server: POST /bc-authorize, signed JWT \n request object, scope=openid accounts, \n id_token_hint or login_hint_token, \n ConsentId and \n optionally a client_notification_token note right of API Provider Authorisation Server Validate the request object by using the Third Party's public key. Third Party certificate will be identified using the kid claim in the JOSE header of the request object. Check that the ConsentId belongs to the ClientId that initiated the request. end note API Provider Authorisation Server -> Third Party: HTTP 200 (OK) auth_req_id Customer <-> API Provider Authorisation Server: Back-channel authentication (login and agree consent) Customer <-> API Provider Authorisation Server: Select Accounts API Provider Authorisation Server -> API Provider Resource Server: Update account-access-consents Status to Authorised API Provider Resource Server -> API Provider Authorisation Server:OK note right of API Provider Authorisation Server Implementation of how the resource is updated is API Provider specific (There is no standardised API for this) end note API Provider Authorisation Server -> API Provider Authorisation Server: Bind Selected Accounts to ConsentId alt note right of API Provider Authorisation Server If the Third Party has registered for Ping mode The API Provider notifies the Third Party of authorisation success via the registered callback endpoint with the auth_req_id end note API Provider Authorisation Server -> Third Party: POST /cb, auth_req_id, client_notification_token note right of Third Party The Third Party validates that the client_notification_token is valid and is associated with the auth_req_id end note Third Party -> API Provider Authorisation Server: HTTP 204 (No Content) end Third Party <-> API Provider Authorisation Server: Establish TLS 1.2 MA Third Party -> API Provider Authorisation Server: HTTP POST /token (client credentials, \n grant_type=urn:openid:params:grant-type:ciba, auth_req_id) API Provider Authorisation Server -> API Provider Authorisation Server: Validate ClientId matches client SSL cert API Provider Authorisation Server -> API Provider Authorisation Server: Validate client credentials API Provider Authorisation Server -> API Provider Authorisation Server: Validate auth_req_id API Provider Authorisation Server -> API Provider Authorisation Server: Generate access-token API Provider Authorisation Server -> API Provider Authorisation Server: Bind access-token to ConsentId note right of API Provider Authorisation Server Implies an association of Accounts to access-token end note alt Access Token API Provider Authorisation Server -> Third Party: HTTP 200 (OK) access-token (scope:accounts) else Optional Refresh Token API Provider Authorisation Server -> API Provider Authorisation Server: Generate Refresh Token API Provider Authorisation Server -> Third Party: HTTP 200 (OK) access-token, refresh-token (scope:accounts) end note over Customer, API Provider Resource Server Step 4: Request data end note Third Party <-> API Provider Resource Server: Establish TLS 1.2 MA Third Party <-> Third Party: Retrieve access-token note left of Third Party Retrieve the access-token that was issued in Step [42]. The access-token is linked with consented Accounts from Steps [27] and [39] end note alt Valid Access Token Third Party -> API Provider Resource Server: GET /accounts (access-token - scope:accounts) API Provider Resource Server -> API Provider Resource Server: Validate access-token API Provider Resource Server -> API Provider Resource Server: Validate access-token matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Validate scope:accounts API Provider Resource Server -> Third Party: HTTP 200 (OK), List of accounts containing AccountId(s) Third Party -> API Provider Resource Server: GET /accounts/{AccountId}/transactions (access-token - scope:accounts) API Provider Resource Server -> API Provider Resource Server: Validate access-token API Provider Resource Server -> API Provider Resource Server: Validate access-token matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Validate scope:accounts API Provider Resource Server -> API Provider Resource Server: Validate access-token bound to AccountId API Provider Resource Server -> Third Party: HTTP 200 (OK), List of transactions else Expired Access Token Third Party -> Third Party: Retrieve Refresh Token from [44] Third Party -> API Provider Authorisation Server:HTTP POST /token (client authentication credentials,\ngrant_type=refresh_token,refresh_token=[58],\nscope=openid accounts) API Provider Authorisation Server -> API Provider Authorisation Server: Validate ClientId matches client SSL cert API Provider Authorisation Server -> API Provider Authorisation Server: Validate client authentication credentials,\refresh_token API Provider Authorisation Server -> API Provider Authorisation Server: Generate Access Token and Refresh Token API Provider Authorisation Server -> Third Party: HTTP 200 (OK) access-token, refresh-token (scope:accounts) Third Party -> API Provider Resource Server: GET /accounts (access-token - scope:accounts) API Provider Resource Server -> API Provider Resource Server: Validate access-token API Provider Resource Server -> API Provider Resource Server: Validate access-token matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Validate scope:accounts API Provider Resource Server -> Third Party: HTTP 200 (OK), List of accounts containing AccountId(s) Third Party -> API Provider Resource Server: GET /accounts/{AccountId}/transactions (access-token - scope:accounts) API Provider Resource Server -> API Provider Resource Server: Validate access-token API Provider Resource Server -> API Provider Resource Server: Validate access-token matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Validate scope:accounts API Provider Resource Server -> API Provider Resource Server: Validate access-token bound to AccountId API Provider Resource Server -> Third Party: HTTP 200 (OK), List of transactions end alt Account Access Consent - Get Status Third Party <-> API Provider Authorisation Server: Establish TLS 1.2 MA note left of Third Party Client Credentials Grant end note Third Party -> API Provider Authorisation Server: POST /token (client authentication credentials, scope:accounts) API Provider Authorisation Server -> API Provider Authorisation Server: Validate client authentication credentials, scope API Provider Authorisation Server -> API Provider Authorisation Server: Validate ClientId matches client SSL cert API Provider Authorisation Server -> Third Party: HTTP 200 (OK) access-token (scope:accounts) Third Party <-> API Provider Resource Server: Establish TLS 1.2 MA Third Party -> Third Party: Retrieve ConsentId from [16] Third Party -> API Provider Resource Server: GET /account-access-consents/{ConsentId} (access-token - scope:accounts) API Provider Resource Server -> API Provider Resource Server: Validate access token API Provider Resource Server -> API Provider Resource Server: Validate scope:accounts API Provider Resource Server -> API Provider Resource Server: Validate ClientId matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Lookup ConsentId resource API Provider Resource Server -> Third Party: HTTP 200 (OK), account-access-consents Status end alt Account Access Consent - Customer revokes consent with the Third Party at a later point in time Customer -> Third Party: Remove Consent Third Party <-> API Provider Authorisation Server: Establish TLS 1.2 MA note left of Third Party Client Credentials Grant end note Third Party -> API Provider Authorisation Server: POST /token (client authentication credentials, scope:accounts) API Provider Authorisation Server -> API Provider Authorisation Server: Validate client authentication credentials, scope API Provider Authorisation Server -> API Provider Authorisation Server: Validate ClientId matches client SSL cert API Provider Authorisation Server -> Third Party: HTTP 200 (OK) access-token (scope:accounts) Third Party <-> API Provider Resource Server: Establish TLS 1.2 MA Third Party -> Third Party: Retrieve ConsentId from [16] Third Party -> API Provider Resource Server: DELETE /account-access-consents/{ConsentId} (access-token - scope:accounts) API Provider Resource Server -> API Provider Resource Server: Validate access token API Provider Resource Server -> API Provider Resource Server: Validate scope:accounts API Provider Resource Server -> API Provider Resource Server: Validate clientId matches client SSL cert API Provider Resource Server -> API Provider Resource Server: Delete ConsentId resource API Provider Resource Server -> Third Party: HTTP 204 (No Content) Third Party -> Customer: Consent Removed end

Client Credentials Grant Type (OAuth 2.0)

This grant type is used by the Third Party in Step 2 to register an intent for the Customer to allow the Third Party to retrieve their Account Information from an API Provider.

  1. The Third Party initiates an Authorization request using valid Client Credentials Grant type and scope(s)

  2. The API Provider Authorization Server validates the Client Authentication request from the Third Party and generates an Access Token response where the request is valid

  3. The Third Party uses the Access Token to create a new Account Access Consent resource against the API Provider Resource Server

  4. The API Provider Resource server responds with the ConsentId representing the resource it has created

CIBA Flow

  • This is initiated at the end of Step 2 by the Third Party after the ConsentId is generated by the API Provider and returned to the Third Party

Non-Normative HTTP Request and Response Examples

Step 1 - Agree Account Access Consent

There are no Requests and Responses against the Account Information API in this Step for the Customer, Third Party and API Provider

Step 2 - Setup Account Access Consent

  1. Third Party obtains an Access Token using a Client Credentials Grant Type. The scope 

accounts must be used. When an Access Token expires, the Third Party will need to re-request for another Access Token using the same request below.

Request : Client Credentials using private_key_jwt
POST /oauth2/token HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=client_credentials& scope=accounts& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcyOTQ4MTI1LCJpYXQiOjE2NzI5NDc1MjUsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiYjkwOTBkYzQtMzIyNy00MjI3LTllOGUtMDA1ZGFhMDhjYTA1Iiwi bmJmIjoxNjcyOTQ3NTI1LCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.o9DeRYkFqfcYx19DXcj tk4EKHKNLRH8_Ne7vfIGQovH24aUxuz_YxGfBjrz_5TDFDcys4fBItAiNPMe7-EoFfWQh7Mx_L9Ln89T Itgv7sDFrsnS7YKwag64BvkE9_Q6gGxBQJSuyh7HBIU4KgyG3tJDunG2XkXby8g9EDM8-OkAr1Y05Qjq 0k2oB7QCPwjZ0JpGAN-UdMFz_QF3QYHkN980Svooob0wJvgRTUCUfN3AOEiwKm4Efo_sIpZouclzFxlA su2c3wNdydm3e8K6cjML9MMhSXpSjbjNdtS5feFdrZRU-qy0mPW3Lk7gzB8u6fYGiwglp6Y_oOId-Z7Y mYtRph3Abw3QQFQryl6zdKd-pnsnkMPyh53sYm7qkoTPP8fHo0PvxoozTBch6NPSg7tGRtqRYIhAO35z 7g_KzmuIdtx7nOjBWyHT7XAX0bY-gIuo1JLh76hcAIJqPpMsLegOPtSf0eK0vTaBqCKkvym0Nb7kMLDb QGWqDnpCkx5xe0eGdIuWfo-Tpw7aL-LvjdpmLLSN8NBMedSaEwtZ0Kogblf-jgK2d0VdUeDyatRmCJ5m e7DEEOozbLRv-BBhKXKMsF1ZeE_ZUdKMLEt0L7V16HKFrC07kJMyF4BN6neAOHw1ziPQd1vuwb8i-lLj DJp4ZV_CLqSyj0iQCjE5Yd2o
Non-Base64 JWT client_assertion
{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "aud": "https://as.apiprovider.co.nz", "exp": 1672948125, "iat": 1672947525, "iss": "Z5O3upPC88QrAjx00dis", "jti": "b9090dc4-3227-4227-9e8e-005daa08ca05", "nbf": 1672947525, "sub": "Z5O3upPC88QrAjx00dis" } . <<signature>>
Response : Client Credentials
HTTP/1.1 200 OK Content-Length: 1103 Content-Type: application/json Date: Fri, 06 Jan 2023 08:40:03 GMT { "access_token": "2YotnFZFEjr1zCsicMWpAA", "expires_in": 3600, "token_type": "bearer", "scope": "accounts" }
  1. Third Party uses the Access Token (with 

accounts scope) from the API Provider to create an account-access-consent resource.

Request: Accounts API
POST /account-access-consents HTTP/1.1 Host: apiprovider.co.nz Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA x-fapi-customer-auth-date: 2023-01-06T08:35:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Content-Type: application/json Accept: application/json { "Data": { "Consent": { "Permissions": [ "ReadAccountsDetail", "ReadBalances", "ReadBeneficiariesDetail", "ReadDirectDebits", "ReadStandingOrdersDetail", "ReadTransactionsCredits", "ReadTransactionsDebits", "ReadTransactionsDetail" ], "ExpirationDateTime": "2023-05-02T00:00:00+00:00", "TransactionFromDateTime": "2022-05-03T00:00:00+00:00", "TransactionToDateTime": "2022-12-03T00:00:00+00:00" } }, "Risk": {} }
Response: Accounts API
HTTP/1.1 201 Created x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Content-Type: application/json { "Data": { "ConsentId": "88379", "Status": "AwaitingAuthorisation", "CreationDateTime": "2023-01-06T08:41:00+12:00", "StatusUpdateDateTime": "2023-01-06T08:41:05+12:00", "Consent": { "Permissions": [ "ReadAccountsDetail", "ReadBalances", "ReadBeneficiariesDetail", "ReadDirectDebits", "ReadStandingOrdersDetail", "ReadTransactionsCredits", "ReadTransactionsDebits", "ReadTransactionsDetail" ], "ExpirationDateTime": "2023-05-02T00:00:00+00:00", "TransactionFromDateTime": "2022-05-03T00:00:00+00:00", "TransactionToDateTime": "2022-12-03T00:00:00+00:00" } }, "Risk": {}, "Links": { "Self": "https://api.alphabank.com/open-banking/v3.0/account-access-consents/88379" }, "Meta": { "TotalPages": 1 } }

Step 3 - Authorize Consent

  1. Third Party receives a ConsentId from the API Provider. The Third Party then creates an Authorization request (using a signed JWT Request containing the ConsentId as a claim) for the Customer to consent to the account-access-consent directly with their API Provider. The request is a CIBA flow. In this example, the Third Party has pre-registered for a Ping notification response, and included a client_notification_token in the signed Authorization Request.

Request : CIBA Authorization Request

Sourced from the NZ Security Profile Authorisation Request section

Base 64 Encoded Example
POST /bc-authorize HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencode request=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5xTzZlOEFK WEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiJ1cm4tYWxwaGFiYW5rLWludGVud C01ODkyMyIsImF1ZCI6Imh0dHBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubnoiLCJjbGllbnRfbm90aWZpY 2F0aW9uX3Rva2VuIjoiZDBmM2Q5NjUtYmFlZS00YTBhLWI2MWYtMTQ2MDY1MDRkYjg1IiwiZXhwIjoxN jcyOTUwNzg3LCJpYXQiOjE2NzI5NTAxODcsImlzcyI6Ilo1TzN1cFBDODhRckFqeDAwZGlzIiwianRpI joiY2IyMzUwNmMtMzVmOS00ZThlLWIxMzgtOGJjZGNjN2FmMzM4IiwibG9naW5faGludF90b2tlbiI6I mV5SmhiR2NpT2lKUVV6STFOaUlzSW10cFpDSTZJbFp6T0ZGRU16bEthRkpQY0haUFR6aGtTbEZJTFc0M 1RVNXhUelpsT0VGS1dFaDJNVEEwWkd0dU5VMGlmUS5leUp6ZFdKcVpXTjBJanA3SW5Cb2IyNWxJam9pS 3pZMExUSXlNRFkyT0RjNElpd2ljM1ZpYW1WamRGOTBlWEJsSWpvaWNHaHZibVVpZlgwLlNzdWp2N3A3Z kYxYVowVFhhbGhVVzlxdjZxbm9LbTlKYTEwSW5aazgxRG1HTWQ4ZUd0SUk0em9GQ0VPMmRKcXFfSVhrR zhZSktSRGZ1cEcyYVR3NDItWW84RDlHc2tJb2ctR2tpaU1RMmtsNWc2aXdUeldZYXBsRzBMOEJoT2xBM FpBLVM3RHpVdUdZQ3V3a2JMQktkdjhESFZPc0pVdDAyZ2J5NUpEdXR1a1Y0LWpHdUV1OUNIX0d4OHNrU 3BqVFFSMGc2dUtwTDE0T202VXNSVmRiN09fSTNRLUdDWHp5UXlwQUVRaUFSNHp4cHlraU1jSUNzN2VHS mF6SExOUHljWEtSajY2ajE0eXBDcHN5bFNQTDZpcmRiRm8zWURBcmtrR1prLTU0cXE2RmFESkdLNmFDU ThyUW9wd0ZiS0NnaGRjbS0zRWZPcWNaeXg0X0l5VWU2a0NiRWVYZDRWZFlxYXRBZUlXX2c0T29iUDhKd GRuckZRMjBVRl9vR2dwTm1ucXlCN1hfMWVUMXRnbUs0QTNWQzBZMkdBU19HRUZhbTRSVUNPWFgwVlBCU 2phcm9zamt4Ui1VZkZoNGRldTlxSHBwbFNYdkJ0QUFqblVVSkVnT2RkQjFyZWdERU5UTDhUbVBLUC1RR VdzOGlGSjVtXzlzQXh6SDAxbW9xbTJVRGJmd0FOOXc1d09ITm1YWnFmQUlqWTFwMmx2SmNYRUdZdjVLL UExUzlNOEhmZ29QaURYQkdubEdTcjB1ZURtWldpNjVpby1waU1EREFFOWVsU01ydWtqM2NLMzdDMUExU kszMUpsRHVJTk5WODZBLW12UlhWV3VLUmYwNFBfN1l4ekhRbmoweExITUo4dXdOS00tM3pxM0cyanRkM C1PbVpKbmE0bFFsZTVFIiwibmJmIjoxNjcyOTUwMTc3LCJzY29wZSI6Im9wZW5pZCBwYXltZW50cyJ9. gX1r0Pe7Ixz4dcpDt4s_vJfUJhvxEsp_uBvI7af7tWL93NoZYuza8xIWFo0RuUzhRw0XCgyoDwaJJhFv KbnsHRKjQCeZDlsagb6rOKBK1s-p-E4jB84x_rD9KznIsWAAUJE2fdDsoiy09lHtRzU3q-mVcZQFncn6 KBXPlOBcrbz1igiRKNs_KBGbgAzJkkFcoyDOmJ_lxJfiDa-HzCa2ashd9flmEbcwifvosiJ0BIWI9nkR bVaW1Vea-A_GkxeLoTxXWK2IzR7jJ_dBeZBr6PjhAxTbUgaqss7GXkPaQH0Ylt55JwBAHK6WlzzPosSk o8VAoFpRLxdvUR5dA_DmL4Up56NpuS-o_yMvhvZ3FFH47Y1_9OjyU6cd4_IfxRWTtFl9ml21YjXTmtOg WRHl_SD37cGI12hg-KQcJmFFTqypbg8_eRiXngdlQDmVO5HDKHckte2xUWNwI5mt8h9IhVpXKRmidZnG quKDeybP_5ykpWlC62UFu5nM0YF9Kt9FvH6gQzSkBcKHs-j-dzvF5FIdIaZBeILnNCk1A39FLZ1oEbtx wbzpmX2enCRbAC3EZNPjjUaxxoHYB50q4ObdDaFOIMUkX2fq4E3Rs8Y3MpgsKnDjZ9e2maUNE93zPkmg R1gckV-esdldVG5mFY-UH15WV-afCwRy-QiCONmNYSs& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcyOTUwNzg1LCJpYXQiOjE2NzI5NTAxODUsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiNmNjZjE0NzUtMjgzZS00Y2M0LTllMjMtMmUxMmM4MDJjM2RmIiwi bmJmIjoxNjcyOTUwMTg1LCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.hfj_iyMSB-zkXv36hMa rsmDWLtWc8AgKQhsT_1sjYnUoSdwQBG_nDfAl2oaZSRZtikUAobsTJnWFyNBN3GF5hdQc9BS_K2mlFlR ueIs9dbEoXsEuQBikGMRzjCJJcVEYiLfm2mhyWx4-HdTEhSjqf95T4SlZ8dJKxmfns7Q0LMlLnpfVOnn CCu1JcvP2sOYL6IpUzHcgvtZ6LpLPbDgIY2VvGHQ4OKpSDd97Wm-IwQxDBCrwTl3d9l7MqXuGN1BTEYF 7LoOSgW587oV3DVaF9ftRBMptCKYF250EBqFWJYcbTa7WT7GXPqbga5QxhU0kz9NtDMvHA4ropbHaOgA sv4sxTSE3KXSxiFzgga-aR8rIMOr09qZRXZYQdFSDdDUjdouvKrdys6z5pDFpXj28rGTRWWGFUi5E4cx TvjnwvjDI2sEtw2a-CukbjM7dyuVg3GWFoynvfdAMfnOT6RtVQIUNx1m6QQxJ1Z-uRXJsM71XK_T3Kgi AqhYzr3GJKxF2FmmhmHx3Thv7hMyCEJ0WY9Yqp0cZMa6BYySME8zmujsyn4P19D69B_A6NEsb9g7Mi8_ vya1ZFBxTq1Qwye8q7mrNvE0aD45u71Fm6dHKuJ6hTHMzN45u9MypVJGwCKTWjYg3moL0KmrY5ToUDWQ CPZjQZl4Sc9guE4yEt-BuU4w
Non-Base64 encoded example of the request object
{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "ConsentId": "urn-alphabank-intent-58923", "aud": "https://as.apiprovider.co.nz", "client_notification_token": "d0f3d965-baee-4a0a-b61f-14606504db85", "exp": 1672950787, "iat": 1672950187, "iss": "Z5O3upPC88QrAjx00dis", "jti": "cb23506c-35f9-4e8e-b138-8bcdcc7af338", "login_hint_token": "eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSl FILW43TU5xTzZlOEFKWEh2MTA0ZGtuNU0ifQ.eyJzdWJqZWN0Ijp7InBob25lIjoiKzY0LT IyMDY2ODc4Iiwic3ViamVjdF90eXBlIjoicGhvbmUifX0.Ssujv7p7fF1aZ0TXalhUW9qv6 qnoKm9Ja10InZk81DmGMd8eGtII4zoFCEO2dJqq_IXkG8YJKRDfupG2aTw42-Yo8D9GskIo g-GkiiMQ2kl5g6iwTzWYaplG0L8BhOlA0ZA-S7DzUuGYCuwkbLBKdv8DHVOsJUt02gby5JD utukV4-jGuEu9CH_Gx8skSpjTQR0g6uKpL14Om6UsRVdb7O_I3Q-GCXzyQypAEQiAR4zxpy kiMcICs7eGJazHLNPycXKRj66j14ypCpsylSPL6irdbFo3YDArkkGZk-54qq6FaDJGK6aCQ 8rQopwFbKCghdcm-3EfOqcZyx4_IyUe6kCbEeXd4VdYqatAeIW_g4OobP8JtdnrFQ20UF_o GgpNmnqyB7X_1eT1tgmK4A3VC0Y2GAS_GEFam4RUCOXX0VPBSjarosjkxR-UfFh4deu9qHp plSXvBtAAjnUUJEgOddB1regDENTL8TmPKP-QEWs8iFJ5m_9sAxzH01moqm2UDbfwAN9w5w OHNmXZqfAIjY1p2lvJcXEGYv5K-A1S9M8HfgoPiDXBGnlGSr0ueDmZWi65io-piMDDAE9el SMrukj3cK37C1A1RK31JlDuINNV86A-mvRXVWuKRf04P_7YxzHQnj0xLHMJ8uwNKM-3zq3G 2jtd0-OmZJna4lQle5E", "nbf": 1672950177, "scope": "openid payments" } . <<signature>>
Non-Base64 encoded example of the login hint token
{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M" } . { "subject": { "phone": "+64-22066878", "subject_type": "phone" } } . <<signature>>
Response : CIBA Authorization Request

The API Provider responds with an auth_req_id that relates to the authorization request. This is used to retrieve the token once authorised.

HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1", "expires_in": 3600, "interval": 2 }
  1. The API Provider contacts the Customer out of band to authorise the request on an authorisation device (that may be separate from the consumption device the Customer is interacting with the Third Party). 

If the Third Party has registered for a Ping response mode, the API Provider contacts the Third Party at their registered callback endpoint with the client_notification_token as the Bearer token in the Authorization header.

Request : Third Party Ping Response
POST /cb HTTP/1.1 Host: thirdparty.co.nz Authorization: Bearer d0f3d965-baee-4a0a-b61f-14606504db85 Content-Type: application/json { "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1" }
Response : No Content
HTTP/1.1 204 No Content
  1. If the Third Party has registered for Poll response mode, the Third Party will poll the token endpoint for a successful authorisation.

Else, if the Third Party registered for Ping response mode and the API Provider has successfully contacted the Third Party at their callback endpoint, the Third Party may now request the token from the token endpoint.

Request : Access Token Request
POST /token HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded grant_type=urn%3Aopenid%3Aparams%3Agrant-type%3Aciba& auth_req_id=1c266114-a1be-4252-8ad1-04986c5b9ac1& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3A client-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcyOTUwNzkyLCJpYXQiOjE2NzI5NTAxOTIsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiNWYxYTAzMzctYzY0Yi00ZDNhLWFhY2QtNmE3MDA1MWQxMjNiIiwi bmJmIjoxNjcyOTUwMTkyLCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.DW0wOH1042qRHliqXkr 2b1EXsH-tjVD0U0xIM7Aiit0ij7rrgtZbNRmzRZAB9Fr58AIhQr_n_A7AkddaY34Eg065zFB-HY4wpDV MMGaYMI6iXES7OoTnxgHpHZQAtmDRBG9Y4v9FjBHpgje-uJECVmWLDhhLWjuwpuapMk5itnvin_Yq4Qe X7oC8TYPGfjz9hC3eiVkK_2rR8s3pViGfQq0d8qM4bdDa8HA95U75wrbG671JSLpm51dIDlFCrqL4OFI kEajlatNOJiCIhXxsqYXYOe2ZZGr60LfIKh3md3QbTzqqk4NX-Cr47C9Y_Qt00qgI6JR5s-gHr1J6s4i qB7eujpN-BBVPnuD5ML6p1PsTgODaITCjQnKGdjkhSjME3ugsfLFJNNl8cwsghuRlivF0RuNdY71me-l lGWtJO_zhATKnGlo3qCEGnPvQkEzpUUaX5DwlxRgpVn47C2SFjUj7QNf3T_nyBMZHbU7VZpSMtIrXGHD IRMzghkTEC_UlFUdIgfvGNITGAcX3jVGg5YhtOgwt2o6VSb6xqXsQ5Nx3B33AVjZk-IDzxRe5Ub1PucZ I32JYvOSIuh3Ohxi11Odyxmsp_9BcBU_Z0BKifgiSRDv2-RaZXL6fR-J6MfgH6f3mVX98mMimTUJrkTH OcZE57_OthAp1QvbiTNgvNow
Non-Base64 encoded example of the client assertion:
{ "alg": "PS256", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "typ": "JWT" } . { "aud": "https://as.apiprovider.co.nz", "exp": 1672950792, "iat": 1672950192, "iss": "Z5O3upPC88QrAjx00dis", "jti": "5f1a0337-c64b-4d3a-aacd-6a70051d123b", "nbf": 1672950192, "sub": "Z5O3upPC88QrAjx00dis" } . <<signature>>
Response : Access Token (with Optional Refresh Token)
HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store { "access_token": "G5kXH2wHvUra0sHlDy1iTkDJgsgUO1bN", "token_type": "Bearer", "refresh_token": "4bwc0ESC_IAhflf-ACC_vjD_ltc11ne-8gFPfA2Kx16", "expires_in": 3600, "id_token":"eyJhbGciOiJQUzI1NiIsImtpZCI6Ikh0cEEwaGYtZUFwNGFTU2MxZ3JwYTZ5SWxxb1BB UU53MGo1aEI2cldNWlkiLCJ0eXAiOiJKV1QifQ.eyJDb25zZW50SWQiOiJ1cm4tYWxwaGFiYW5rLWlud GVudC01ODkyMyIsImF1ZCI6Ilo1TzN1cFBDODhRckFqeDAwZGlzIiwiZXhwIjoxNjcyOTUwNzk3LCJpY XQiOjE2NzI5NTAxOTcsImlzcyI6Imh0dHBzOi8vYXMuYXBpcHJvdmlkZXIuY28ubnoiLCJqdGkiOiI1O TBmYzU2MC0zYWI5LTRkMmYtOGFkNy0wYTJmM2I2N2QyZWYiLCJzdWIiOiIyM2wzNGpkc2xmOTIifQ.yL IkHnmqhmHC_SRfUF7Zg-LGgwwJSeCebwQut99RYefkNvooDjrzCSI-UuEwifU6PSlGAvpMPJeswv_2cq bxo98rbGAWfGvYsIx2N-VvKW2qTyaB2xuCGPuM-bqjE8G8IK6LBJmhvoeytXkidWntdQO5N7vsLvYjQ6 p44qGUr1OhAIcTBvOI7DNmyxPhi3M0wy46G97ImoGQr0W8rbFjsHFnPBPeShzGsfIooOY9LLXV8qXGbM PxBLwdNjTB-tgp3G4Z4x58qI6l35zqke2Uuxh9EXLQCJ0Lzgiu-_byxKoi3qwz5mnJiGJL41K-pC4Q4q eHM91czKhYH_yj97i4xxH_mCvzlW2Gf4u0NYafxlDMV0maqa09M11Lf2Lje7-bG1CoSlYnhSVZCk9dHl xVdNwrXKvTEfNDmYqJas-hBMw85zdeOqI5vqezyfTs-PtxRFr7S7JP5P6b4tjvUzJ6aZiHwNyD_WYgcL orafXgIdJqhhcrcTGijWfp4g3tjL_sHlKktxbhifz7T9jJBiBeKCSxU6ik7Szc0qRZ-ro-38KQ-BQkQW 2NXqzMF6bByB2vHuihestl1Kvdq9tcazr2FoKnAYBmn0XShzwCIyEFoatEJtJuFqTFB5A_JJ4Qihji2s in-uJDQ7XPkzbddxqhOQD2_CIRAzoP6KJdqDGtQwo" }
ID Token - Non-Base 64 Encoded
{ "alg": "PS256", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY", "typ": "JWT" } . { "ConsentId": "urn-alphabank-intent-58923", "aud": "Z5O3upPC88QrAjx00dis", "exp": 1672950797, "iat": 1672950197, "iss": "https://as.apiprovider.co.nz", "jti": "590fc560-3ab9-4d2f-8ad7-0a2f3b67d2ef", "sub": "23l34jdslf92" } . <<signature>>

Step 4 - Request Account Data

  1. The Third Party can use the Access Token to retrieve Accounts (bulk or specific). 

Where the initial Access Token expires, the Third Party can use the Refresh token in order to obtain a fresh Access Token.

Request : Bulk accounts resource
GET /accounts HTTP/1.1 Host: apiprovider.co.nz Authorization: Bearer G5kXH2wHvUra0sHlDy1iTkDJgsgUO1bN x-fapi-customer-auth-date: 2023-01-06T08:35:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 95594665-da84-4361-8ac3-b2df6c8d9673 Accept: application/json
Response: Bulk accounts resource
HTTP/1.1 200 OK x-fapi-interaction-id: 95594665-da84-4361-8ac3-b2df6c8d9673 Content-Type: application/json { "Data": { "Account": [{ "AccountId": "22289", "Currency": "NZD", "Nickname": "Bills", "Account": { "SchemeName": "BECSElectronicCredit", "Identification": "80200110203345", "Name": "Mr Kevin", "SecondaryIdentification": "00021" } }, { "AccountId": "31820", "Currency": "NZD", "Nickname": "Household", "Account": { "SchemeName": "BECSElectronicCredit", "Identification": "80200110203348", "Name": "Mr Kevin" } } ] }, "Links": { "Self": "https://api.alphabank.com/open-banking/v3.0/accounts" }, "Meta": { "TotalPages": 1 } }
Request : Specific Account Id
GET /accounts/22289 HTTP/1.1 Host: apiprovider.co.nz Authorization: Bearer G5kXH2wHvUra0sHlDy1iTkDJgsgUO1bN x-fapi-customer-auth-date: 2023-01-06T08:35:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 02a72ecf-0d09-466f-8c5c-77ea19db9ee7 Accept: application/json
Response: Specific Account Id
HTTP/1.1 200 OK x-fapi-interaction-id: 02a72ecf-0d09-466f-8c5c-77ea19db9ee7 Content-Type: application/json { "Data": { "Account": [{ "AccountId": "22289", "Currency": "NZD", "Nickname": "Bills", "Account": { "SchemeName": "BECSElectronicCredit", "Identification": "80200110203345", "Name": "Mr Kevin", "SecondaryIdentification": "00021" } }] }, "Links": { "Self": "https://api.alphabank.com/open-banking/v3.0/accounts/22289" }, "Meta": { "TotalPages": 1 } }
Request: Refresh Token Request using private_key_jwt
POST /as/token.oauth2 HTTP/1.1 Host: as.apiprovider.co.nz Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=refresh_token& refresh_token=4bwc0ESC_IAhflf-ACC_vjD_ltc11ne-8gFPfA2Kx16& scope=openid%20accounts& client-assertion-type%3Ajwt-bearer& client_assertion=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5 xTzZlOEFKWEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaXByb3Zp ZGVyLmNvLm56IiwiZXhwIjoxNjcyOTY3NTgxLCJpYXQiOjE2NzI5NjY5ODEsImlzcyI6Ilo1TzN1cFBD ODhRckFqeDAwZGlzIiwianRpIjoiMTQyNzc0ZmItZjQ0NS00YThmLWJjYjQtOGIxYzY4ZGE1Mzc3Iiwi bmJmIjoxNjcyOTY2OTgxLCJzdWIiOiJaNU8zdXBQQzg4UXJBangwMGRpcyJ9.ZkGo5EcFc7JWsz53ftv mUUUQ25fQ4aLolo5z1RFxx8FUZlvQrAr_4LHO42MmGVEUFdAENtAdG9-yWoGJx8uIJBbpBpOaUuUkKL9 jtriP7sb4qdKnKagTjwyP1A_aQuJKIY5ukUOJmpCTiFZL5BjNnpFtSJqmD4AkQuvSFRPl4fnRoOFzYVu IObA359MEdIZFmyda5JdHHjHrQoSnanmawJ_AWF6TqYJ5cuyQ2rHO8uv-7iVtJCAo0sxbYxJIRF8KDHT 7ivjhQHI5r8fQ-SC_bitjEhsv5Kxnl7m19YP96zZRAWpUIBJnmkUa1ixQD75W7DXxAkWzur1DqBzGTqz mjMJ3Zpm3QC9t6jpjdnCYZIED7lxEYXt7ZIr5YsLY65Oiwwga6Ab1OxlvrnRfPjrkoopFexQhcr9Daut ucIYs1OMQzeuww-dtqGZhI-Z2p0R6vaoZ8-JBUx5bedf_dioQi50XJ9UyQJWnAjUzI6Qv0dx8u_t7Spf YV7n9YJgTb4w7IsN3s07ktOumsKL9f_0KljE8iyxR_EFD97407SxoukvHOVPtjuXVoPbgoE9MWIKDG-D 2HlmWZyav5mIFbZsskUIOBKjR304dqxdGxx-LmrRzK4EVXJnefF8ZuH8tTGr-88W0-yt_KaqbfI7Gj7A koKCKnTOIo36_Rxjyt0vyByw
Response: Refresh Token

A new Access Token and Refresh Token will be returned to the Third Party for them to query /accounts resources

HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "access_token": "PEOFYwaeMgIXTtZBuwnyVWJsgpUdCjZh", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "wXWfV3YFafpaa8KIXig7s3DUxJGfvBxge9fi_ZNX6NU" }

 

Refresh token introspection

Overview

Refresh tokens are required for the utility of long-lived consents. The lifetimes of refresh tokens are determined by the API Provider, and retrieved through an RFC7662 OAuth 2.0 token introspection interaction. This requires the API Provider to return the token expiry time in the exp claim in the introspection response. The API Provider may also include other optional standard and extension claims, but must not return any PII information.

Only introspection of refresh tokens is supported.

Steps

Pre-requisites:

  • TPP and customer agree on a long-lived consent

  • TPP and customer successfully follow Hybrid or Decoupled flow

  • TPP successfully retrieves tokens, including refresh token

Step 1 - introspect token

  • Establish MTLS from TPP to API Provider

  • TPP creates a client assertion JWT

  • Client makes an introspection request to API provider introspection endpoint

  • API provider validates the TPP client assertion JWT authentication credential

  • API provider verifies that the supplied token belongs to the TPP

  • API provider responds with an introspection response

Endpoints

The OAuth 2.0 Introspection endpoint and mandatory/conditional/optional status are given below.

Resource

Endpoints

Mandatory?

Resource

Endpoints

Mandatory?

introspection

POST /introspect

Mandatory

POST /introspect

The Introspection endpoint allows the TPP to ask an API Provider for information on a previously issued refresh token.

Sequence diagram

actor customer participant "Third Party" as TPP participant "API provider" as api autonumber note over customer, api Pre-requisites end note customer -> TPP : Request service TPP -> api : Request consent customer <-> TPP : Start consent authorisation customer <-> api : Authenticate and authorise consent TPP -> api : Request tokens api -> TPP : Access token\nRefresh token\nID token TPP -> TPP : Store tokens TPP <--> customer : Any interaction note over customer, api Step 1. Introspection end note TPP <-> api: Establish TLS 1.2/1.3 MA TPP -> api : Introspect refresh token api -> TPP : Introspection response, including refresh token expiry

Data model

This section contains the schemas for the token introspection request and response.

Introspection request

The IntrospectionRequest object will be used for the call to:

  • POST /introspect

UML diagram
Data Dictionary

Name

Occurrence

XPath

EnhancedDefinition

Class

Codes

Pattern

Name

Occurrence

XPath

EnhancedDefinition

Class

Codes

Pattern

client_assertion

1..1

client_assertion

A RFC7523 client authentication assertion as per OIDC Core section 9 private_key_jwt

xs:string

 

 

client_assertion_type

1..1

client_assertion_type

The type of client assertion used

xs:Max64Text

urn:ietf:params:oauth:client-assertion-type:jwt-bearer

 

client_id

0..1

client_id

The ID assigned to the Third Party software by the API Proivder. Must match the sub claim in the assertion JWT

xs:string

 

 

token

1..1

token

The refresh token issued to the TPP

xs:string

 

 

token_type_hint

0..1

token_type_hint

Version for the event notification.

Max32Text

refresh_token

 

Introspection response

The IntrospectionResponse object will be used for a response to a call to:

  • POST /introspect

UML diagram
Data Dictionary

Name

Occurrence

XPath

EnhancedDefinition

Class

Codes

Pattern

Name

Occurrence

XPath

EnhancedDefinition

Class

Codes

Pattern

active

1..1

active

Boolean indicator of whether or not the presented token is currently active

xs:boolean

true
false

 

scope

0..1

scope

Scopes associated to the token

Max128Text

 

 

client_id

0..1

client_id

ID assigned to the third party

Max128Text

 

 

username

0..1

username

Human readable identifier for the resource owner

Max128Text

 

 

token_type

0..1

token_type

Type of the token as defined in Section 5.1 of OAuth 2.0

Max128Text

 

 

exp

1..1

exp

The timestamp at which the token will expire, as per RFC7519

xs:int

 

 

iat

0..1

iat

The timestamp at which the token was issued, as per RFC7519

xs:int

 

 

nbf

0..1

nbf

The timestamp before which the token is not considered valid, as per RFC7519

xs:int

 

 

sub

0..1

sub

Subject of the token, as defined in JWT RFC7519. The ID assigned to the Third Party Software by the API Provider See RFC7523

Max128Text

 

 

aud

0..1

aud

Service-specific string identifier or list of string identifiers representing the intended audience for this token, as defined in JWT RFC7519

xs:any

 

 

iss

0..1

iss

String representing the issuer of this token, as defined in RFC7519

Max128Text

 

 

jti

0..1

jti

String identifier for the token, as defined in

Max128Text

 

 

Endpoint Authentication

The token introspection endpoint will require private_key_jwt authentication. The TPP must provide a signed JWT as part of the authentication request, otherwise introspection will be rejected.

Metadata

An API provider must include introspection metadata values in their OIDC Discovery metadata, as per RFC8414, section 2

For example:

{ "introspection_endpoint": "https://as.exampleprovider.co.nz/oauth2/introspect", "introspection_endpoint_auth_methods_supported": [ "private_key_jwt" ], "introspection_endpoint_auth_signing_alg_values_supported": [ "PS256", "ES256" ] }

Usage Examples

The following non-normative examples are used to illustrate the introspection flow.

POST Introspection request

POST /introspect HTTP/1.1 Host: as.alphabank.co.nz Accept: application/json Content-Type: application/x-www-form-urlencoded client_assertion=eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL2FzLmFscGhhYmFuay5jby5ueiIsImV4cCI6MTY2NTYwNzg0NCwiaWF0IjoxNjY1NjA3MjQ0LCJpc3MiOiJaNU8zdXBQQzg4UXJBangwMGRpcyIsImp0aSI6IjlhMzk4YjcxLTM3MjItNGQ0MS05N2E1LTI3NDlkZjhjZjc0NyIsIm5iZiI6MTY2NTYwNzI0NCwic3ViIjoiWjVPM3VwUEM4OFFyQWp4MDBkaXMifQ.fqh7R0V6VrlyLuGPBWc5XMCQTtieEzjqdTMnNGF0JrwO7KXa8dHr_N6ktEnxVPRCv8I8qgWnetnXifvCksAaQZ6RZtZxh2MG70gEFxbuHALglr3zc5UsCbtmQ8RYOE1FFSobFRVWWjqn4tOsaqqK7T14Gr1m2FxM5HIK9B2DWIRAqDp7IvKGKJXuhMMCYbsZhR9qYIaRDytcx5DglpiYmoRJER3cj4fS6tK4Gdsu872LOxVHZoE6YERxyQjKz_kQq_6uOelRXt10l49EOaydXXn4i5Y4TfOwkGRdr2dgD1wHaooSGXBqsiZBQ1szl6ZD_G1eBiB4nGmf8mX1FvTVYwcfXGuxxdgDrRYAEX_AhIwFLyKLfENjh5O1EcYLP1NOm1ruAOxfMq0126pK2nZp50UdjOviFr_LYhmHTIHKH6L2R2DrZ65wM2TVLaR2RvAfoVC_ijT-iXSOzhAOyEmXOAXPgJWCiCea6S-5Ifr8jKvmrIosDhJM2c6QL9Uv5wwisZElxOmy6BBv01uD-2Qv2wQ-ZP9XbAuWzbo5zUvDtIIa56EVNaoylTGbLHBoKC2nipkFvUBjY2TtQWoXCzAi3VwMxdAh4a6TNB_rhmRtee_--IyCGx0VEyqlshtw4hfMdADHECD30lPpjQzwXmC4nwwo6iMoMTjY3iJKZyR9tFg& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& token=2YotnFZFEjr1zCsicMWpAA& token_type_hint=refresh_token

POST Introspection response

HTTP/1.1 200 OK Content-Type: application/json { "active": true, "sub": "Z5O3upPC88QrAjx00dis", "exp": 1668538708 }

Errors

If the private_key_jwt authentication supplied by the Third Party in the introspection request is invalid, the authorisation server responds with a 401 Unauthorized response, as required by RFC7662, section 2.3. The client may try again with a different credential.

As per RFC7662, introspection of a token that has expired or is otherwise invalid is not considered an error.

Edge Cases

This section provides further information on potential edge cases that may arise via the implementation of Accounts and Payments API Specifications. 

Scenario

Workflow Step

Impact

Solution Options

Scenario

Workflow Step

Impact

Solution Options

Due to an interruption, the Customer does not complete the Authorization of a Consent resource with the API Provider when redirected by the Third Party (after creating a ConsentId)

Step 3: Authorize Consent

Consent Status remains as AwaitingAuthorisation

The Third Party may choose to implement a separate follow up process which reminds the Customer to complete their Authorization consent steps with the API Provider.

This would imply re-using the ConsentId that has a status of AwaitingAuthorisation and re-issuing another Hybrid Flow request. Authorisation Code Flow request or CIBA Flow request to the API Provider.

The implementation of how the follow up process is initiated is in the competitive space for the Third Parties to decide.

JSON Security Suite

JWT Best Current Practices Guides to be followed where appropriate: [BCP-225] https://www.rfc-editor.org/rfc/rfc8725  

Creating a JWS

Step 1: Select the Certificate and Private Key that will be used for Signing the JWS

As the JWS is used for non-repudiation, it must be signed using one of the JWS issuer's private keys.

The signing certificate must be valid at the time of creating the JWS.

Step 2: Form the JOSE Header

All participants should include "kid" and "jku" of the key that was used to sign the payloads.

The jku should be considered a hint only and parties should derive and then validate wherever possible the appropriate JWKS endpoint for the message signer.

https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1

The JOSE header is a JSON object consisting of at least two mandatory fields (claims):

Claim

RFC 7515 Standard ?

Required ?

Description

Claim

RFC 7515 Standard ?

Required ?

Description

alg

Yes

Mandatory

The algorithm that will be used for signing the JWS. This is defined in https://datatracker.ietf.org/doc/html/rfc7518#section-3.1

  • should use PS512 or ES512

The list of allowed algorithms:

  • RS512

  • PS512

  • ES384

  • ES512

kid

Yes (optional)

Mandatory

The kid (key ID) Header Parameter is a hint indicating which key was used to secure the JWS.
This must match the certificate id of the certificate selected in step 1.
The receiver should use this value to identify the certificate to be used for verifying the JWS.

Step 3: Form the Payload to be Signed

The JSON payload to be signed must have the following claims:

Claim

Required ?

Description

Claim

Required ?

Description

iss

Mandatory

The issuer of the JWS.

This must match the dn of the certificate selected in step 1.

The payload to be signed is computed as:

payload = base64Encode(JOSEHeader) + "." + base64Encode(json)

Where:

  • JOSEHeader: is the header created in Step 2 and

  • json: is the message the original data to be sent

Step 4: Sign and Encode the Payload

The signed payload is computed as:

signedAndEncodedPayload = base64Encode(encrypt(privateKey, payload))

Where:

  • privateKey: is the private key selected in step 1

  • payload: is the payload computed in Step 3

  • encrypt: Is an encryption function that implements the alg identified in Step 2.

Step 5: Assemble the JWS

The JWS is computed as:

JWS = payload + "." + signedAndEncodedPayload

Where:

  • payload: is the payload computed in Step 3

  • signedAndEncodedPayload: is the signed element computed in Step 5.

Prerequisites

This section outlines the prerequisites for the NZ Security Profile.

Certificates

There are network endpoint certificates used for mutual TLS communication and message signing public/private key pairs used for signing and validating signed requests.

API Providers and Third Parties must obtain their own certificates from one of the approved Certificate Authority Issuers, and:

  • must have different public/private key pairs for network establishment and message signing

  • message signing public keys must be in the form of certificates.

Network Endpoint Certificates

The requirements for certificates used in production are:

  • must use X.509 v3 format

  • must use an RSA public key or an elliptic curve public key

  • should include certificate chain in the PEM file

  • RSA keys must have a key length of at least 4096 bits

  • EC keys must have a key length of at least 384[1] bits

  • must have a validity period of at most 2 years (between the NotBefore date and NotAfter date), and not more than 398 days for those that will be accessible via browser

  • must be an end-entity certificate (i.e., not a CA cert)

  • must be from one of these Certificate Authority issuers:

    • DigiCert

    • Entrust

    • Sectigo (formerly Comodo)

  • must be an OV (organisation validation) certificate

  • must have different certificates for network establishment and message signing

Message Signing Keys

The public/private key pairs used for message signing will meet the following requirements:

  • must be either an RSA or elliptic curve (EC) key pair

  • must be in X.509 V3 certificate format

  • Public keys must be published in RFC7517 JWK format

    • must populate the x5c claim with the certificate containing the public key

    • must include the kid claim to uniquely identify the public key

  • For RSA key pairs:

    • must use as a minimum RS512 as a signing algorithm, should use as a minimum PS512 as a signing algorithm

    • must use a key length of at least 4096 bits

  • For EC key pairs:

    • must have a key length of at least 384 bits, should have a key length of at least 521 bits

    • must use as a minimum ES384 as a signing algorithm, should use ES512 as a signing algorithm

  • must have a validity period of at most 2 years (between the NotBefore date and NotAfter date)

  • must have at least one key usage policy for signing:

    • digitalSignature (0)

    • nonRepudiation (1) -- recent editions of X.509 have renamed this bit to contentCommitment

    • keyEncipherment (2)

    • keyAgreement (4)

  • must not have any key usage policies for network

  • must be signed by one of the approved issuing certificate authorities

    • DigiCert

    • Entrust

    • Sectigo (formerly Comodo)

API Centre Register

Organisations

Once an organisation is verified with the Payments NZ API Centre as an API service user, an organisation record will be created for the API service user in the API Centre Register.

The Payments NZ API Centre will maintain the status of the API service user in the API Centre Register.

Keys

Once an organisation record has been created on the API Centre Register, an organisation will be able to upload their certificates (public keys) into the API Centre Register.

The API Centre Register service will only store message signing certificates.

The API Centre Register service will check that all signing certificates used in the API ecosystem in a production environment meet the requirements of Message Signing Keys

API service users (i.e., both API Providers and Third Parties):

  • must check that the specific certificate in use has not been revoked with the CA issuer (OCSP or CRL);

    • If the CA issuer is unavailable - the API service user must assume that the certificate is still “Active” with the CA for at least 24 hours. After 24 hours of unavailability it is at the API service user’s discretion to decide on treatment.

  • must check that the specific certificate in use is in an “Active” status in the API Centre Register;

    • If the API Centre Register is unavailable - the API service user must assume that the certificate is still “Active” with the API Centre Register for at least 24 hours. After 24 hours of unavailability it is at the API service user’s discretion to decide on treatment.

  • may override the status of the CA or API Centre Register - e.g., if an API Provider is told directly by a Third Party that the Third Party’s certificates are revoked prior to removal from the API Centre Register;

  • should check the status of certificates in the API Centre Register every hour, and should cache results;

  • must not use the API Centre Register as a transactional service (i.e., must not check the central public key store for each interaction between an API Provider and Third Party);

  • may perform other checks that are deemed necessary; and

  • must load replacement certificates at least 30 days before certificate expiry

Authorisation Servers

Once an organisation record has been created on the API Centre Register, an API Provider will be able to create records for their authorisation servers into the API Centre Register.

Third Parties will be able to retrieve authorisation server records from the API Centre Register.

Swagger

https://github.com/PaymentsNZ/API-Centre-Register


Keys used in examples

The following public keys may be used to verify the signatures of example JWT tokens. Certificates included in x5c claim are non-normative examples and are self-signed.

API provider:

{ "e": "AQAB", "kid": "HtpA0hf-eAp4aSSc1grpa6yIlqoPAQNw0j5hB6rWMZY", "kty": "RSA", "n": "z6SOiYPPU45domyKots4A53ZVaMiZ5MQhiXbV5rIXy9iO8nwRzcJr3pJjWSwukBYI4LtPUziYFh1xd5xkw5gHe7dLaqmPhm4CnzqCNgFOxDe_YHdLaXj3j8V7xa0-uYX21nhwGSINBB-mNwXgBeR2017ohWzfWUjy8RsJO23txP4Xt3J8rOyQEdpt-kHDHHqTl5rdhEnHwnAY3x0sCaW0qva3dlwzotWS7BgEvWAH6dhoaW51ziSKcwg2_YRUySsyfFZnjwpRyi3N1hThRXe7JUCLBugQZln1cYFT7072AaFBPxxuEhV0z4LDNmbDehkaEi8k42I7AjsBfDV9XsvyiVWfAdAhx1JmsHxi8ycontREUfs1q1QzqO1All_7qHW19AWkUajoZTZIp3P-rCt5uwbCOENOO9ACBAhCrPilCGB8GVtteuVBp-3bDZsM22XKiYmrpV084gsCw6XOJqOCCAUdmSWJ3YVM7mfB1F9F-xKyB3NHcsHImdNRXScHwO4DrVRq5jp-Gc3pc_D7cfnA3xAAfm1VxddGh1_BfGQoXJXl3mgpMR-LhMOXTk7WwChXCdrHanhQjY1xwM-JjMGxjLTyklVzbo8Q9v063tTunrQ1Wn8fFliBRdcq46ImpjSoldu9Q-ZRYLFSb0uYD3_G13X2gOHZQeT1NEVOp2a9tc", "x5c": "MIIGYTCCBBSgAwIBAgIUJ+URFE7sbmnn8Wtw7MmMCxa3pfMwQgYJKoZIhvcNAQEKMDWgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIEAgIBvjCBjjELMAkGA1UEBhMCTloxEzARBgNVBAgMCldlbGxpbmd0b24xEzARBgNVBAcMCldlbGxpbmd0b24xFDASBgNVBAoMC1BheW1lbnRzIE5aMRMwEQYDVQQLDApBUEkgQ2VudHJlMSowKAYDVQQDDCFpc3N1ZXIuYXBpY2VudHJlLnBheW1lbnRzbnouY28ubnowHhcNMjQwODAxMjMzMDI0WhcNMjUwOTAyMjMzMDI0WjCBhTELMAkGA1UEBhMCTloxEzARBgNVBAgMCldlbGxpbmd0b24xEzARBgNVBAcMCldlbGxpbmd0b24xHzAdBgNVBAoMFlBheW1lbnRzIE5aIEFQSSBDZW50cmUxKzApBgNVBAMMInN1YmplY3QuYXBpY2VudHJlLnBheW1lbnRzbnouY28ubnowggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDPpI6Jg89Tjl2ibIqi2zgDndlVoyJnkxCGJdtXmshfL2I7yfBHNwmvekmNZLC6QFgjgu09TOJgWHXF3nGTDmAd7t0tqqY+GbgKfOoI2AU7EN79gd0tpePePxXvFrT65hfbWeHAZIg0EH6Y3BeAF5HbTXuiFbN9ZSPLxGwk7be3E/he3cnys7JAR2m36QcMcepOXmt2EScfCcBjfHSwJpbSq9rd2XDOi1ZLsGAS9YAfp2GhpbnXOJIpzCDb9hFTJKzJ8VmePClHKLc3WFOFFd7slQIsG6BBmWfVxgVPvTvYBoUE/HG4SFXTPgsM2ZsN6GRoSLyTjYjsCOwF8NX1ey/KJVZ8B0CHHUmawfGLzJyie1ERR+zWrVDOo7UCWX/uodbX0BaRRqOhlNkinc/6sK3m7BsI4Q0470AIECEKs+KUIYHwZW2165UGn7dsNmwzbZcqJiaulXTziCwLDpc4mo4IIBR2ZJYndhUzuZ8HUX0X7ErIHc0dywciZ01FdJwfA7gOtVGrmOn4Zzelz8Ptx+cDfEAB+bVXF10aHX8F8ZChcleXeaCkxH4uEw5dOTtbAKFcJ2sdqeFCNjXHAz4mMwbGMtPKSVXNujxD2/Tre1O6etDVafx8WWIFF1yrjoiamNKiV271D5lFgsVJvS5gPf8bXdfaA4dlB5PU0RU6nZr21wIDAQABo1QwUjAyBgNVHREEKzApgg9hcGljZW50cmUuY28ubnqCFmlzc3Vlci5hcGljZW50cmUuY28ubnowDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCA+gwQgYJKoZIhvcNAQEKMDWgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIEAgIBvgOCAgEAMPo8rnubg76e+SX93LPofXp5uR7uxwTW6A7EjfhVHfuVwlYPd2wPl4MMIH0MT+kzxPdBEM60zO33wTMkMaSU9WmA2S4RI+3LwqbeoxRupwBra1QlVrVWzhhLNsRZM6Jnmqr9WW2C1LJ1wpYeXIn14vwtBcqT4gbdpCpyfdERtcSopnBkE+/lT80BQ8gi+TnnswblgU78i37Po28/rqpJSywShQBzwaY0FptQTxdzR9uVbNPN+ys6DqUl0CP+X1SgE3AaJvFjVYGpCTY6JQrz8/8YrbqrY7SYicMFUE2FoPYuMvJiqpgRr/zmsVPq6ckj8dRq1VkkY1rade12InFBgz2dyoGFtrlhbv6nz6YDQfxRJe8hWwB08VqSF0DuRfru1XlP48aKuggE1KIuBHhPzofpGjnxhGX/oINFCjKWrKpFkLrBn/kErcZcJqlLMpnU7CoSfu8th02oM2HFli7vQsyFpcPU1e2NIIB2utU5yv8p3sq+DZnSWLy/cgdcFdLColeuzLaRBRK9lZyCJKLeWTsrq+Qr+6VIWEsJND14qgB4KpS8LBmkHMipQtOjD4LG+Qn47O9UAo3N+vSnVVZWDNWf4zPafm64csYOsVphtNJaZItAUhikFc26PcJ9uZH2QUV1vMRlYo5sPiiZu1f/IBVW5XYUBZq4R9bAzfm1nKk=" }

Third Party:

{ "e": "AQAB", "kid": "Vs8QD39JhROpvOO8dJQH-n7MNqO6e8AJXHv104dkn5M", "kty": "RSA", "n": "t9bVrCuoN7-8-DCP9zATMC4yRdJi9FCfgVp3ImCNBUQ5jIpTpxLR2pqxhWx5BPGZt_APK3791Wl4mST8pAlRTv1oQVc8CZ7tJ0bXjmPAKbcXz8anLxYdudB-0i0pvRzJAulFB2vAtTVPTDNCTPyrsueWm687xgBxjcs_BjxIiELnp_ym7pHe1PudsI5DEYWz5Kfm72fB4azpMs7dgf6gR0EHVl8C3VvG9JMHicI5XHxaJwwroj9PR5nzoec1Jn0VPk0W76LdUStBdashtVddacy30dPJdNpwbp5WaaNyB8szoZzCknN0zfTaEo4aNR8r7JZ7TOk7Ez0nvD2zRF3BJAlf-KZs_z11TBTTuanTsbztbY2MX64esj50nfa1-WAFPiGesQtj-DZVUfoHTgAat91G_Nn7B9aaldzUib6ZfGWGmmCO7wAGALWyhqKGmsW6S45rPNTdzbY8IFhX8uIZDmi-XyEwCizjZ2rgyQCbS8FYYWXNTX2xCkvDIW7N_Rjxyj0k-MAsTeVgp1pWr_0di7SjwIPAhonmUkX--y-TDpHTWJFYX-qgw6VH8uj6eNs7wYGUo6GJ3BJkaankSLI4j6H0sheJfjqgMmVnCr_QXuANMkK61DjUbl_2xOr-CPe5gzbvC8pm-X-ZQWeouiZ0sW4VFRTxu0UOSULPLRG4gks", "x5c": "MIIGRTCCA/igAwIBAgIUOFSW5lgjbzxnMiVealR172oBtqYwQgYJKoZIhvcNAQEKMDWgDzANBglghkgBZQMEAgMFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgMFAKIEAgIBvjCBhjELMAkGA1UEBhMCTloxETAPBgNVBAgMCEF1Y2tsYW5kMREwDwYDVQQHDAhBdWNrbGFuZDEYMBYGA1UECgwPVGhpcmQgUGFydHkgTHRkMRUwEwYDVQQLDAxPcGVuIEJhbmtpbmcxIDAeBgNVBAMMF2lzc3Vlci50aGlyZHBhcnR5LmNvLm56MB4XDTI0MDgwMTIzMzAyNFoXDTI1MDkwMjIzMzAyNFowcDELMAkGA1UEBhMCTloxETAPBgNVBAgMCEF1Y2tsYW5kMREwDwYDVQQHDAhBdWNrbGFuZDEYMBYGA1UECgwPVGhpcmQgUGFydHkgTHRkMSEwHwYDVQQDDBhzdWJqZWN0LnRoaXJkcGFydHkuY28ubnowggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC31tWsK6g3v7z4MI/3MBMwLjJF0mL0UJ+BWnciYI0FRDmMilOnEtHamrGFbHkE8Zm38A8rfv3VaXiZJPykCVFO/WhBVzwJnu0nRteOY8AptxfPxqcvFh250H7SLSm9HMkC6UUHa8C1NU9MM0JM/Kuy55abrzvGAHGNyz8GPEiIQuen/Kbukd7U+52wjkMRhbPkp+bvZ8HhrOkyzt2B/qBHQQdWXwLdW8b0kweJwjlcfFonDCuiP09HmfOh5zUmfRU+TRbvot1RK0F1qyG1V11pzLfR08l02nBunlZpo3IHyzOhnMKSc3TN9NoSjho1HyvslntM6TsTPSe8PbNEXcEkCV/4pmz/PXVMFNO5qdOxvO1tjYxfrh6yPnSd9rX5YAU+IZ6xC2P4NlVR+gdOABq33Ub82fsH1pqV3NSJvpl8ZYaaYI7vAAYAtbKGooaaxbpLjms81N3NtjwgWFfy4hkOaL5fITAKLONnauDJAJtLwVhhZc1NfbEKS8Mhbs39GPHKPST4wCxN5WCnWlav/R2LtKPAg8CGieZSRf77L5MOkdNYkVhf6qDDpUfy6Pp42zvBgZSjoYncEmRpqeRIsjiPofSyF4l+OqAyZWcKv9Be4A0yQrrUONRuX/bE6v4I97mDNu8Lymb5f5lBZ6i6JnSxbhUVFPG7RQ5JQs8tEbiCSwIDAQABo1YwVDA0BgNVHREELTArghB0aGlyZHBhcnR5LmNvLm56ghdpc3N1ZXIudGhpcmRwYXJ0eS5jby5uejAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwID6DBCBgkqhkiG9w0BAQowNaAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogQCAgG+A4ICAQClTNUEtXL4Q9ZaXo5ZvBvZF5OvV/PovlvbfLP/BA1+9+F6GhcfJ6mqwFqgH3cxwztzDV4dkdeKC8NusOUDreA33/KdjvcmG8R6BGzoSRr6xEd+3HVZTbs/GQTOqkhpbn3m5usL4wakAuUTOuKZA8v/0CtwDdH8gZHJJC4kywr/HDwWURyPqthNvcDxp4Ylv8ls82by2WtAoDYICJ7mUMCx4/rcW+Y8J9faafq719WFS45vHoBMJPjBL/dusD5vlus4lq+sm9QF5ZwraNnii/Rk8TvNJV1iXdhqwdmyA8GsregSkkrMcO8UbW2vhyICp1NEE7fcH6zrJ58A2Ju1VJXWfqEw+oMUqswElLxDsoxS3SgaMD9pDmpV1JJIFv+suLi96/LvI0cIkUIlpFnNR6BNDS2Qk7FMdFF7lWTZl6R4svwWTat9mwbB4OI2byVlGyEKEkXtyKAi/DI0fvnAVvDiM+BJYEfOjJceMU5Dd5Y3t0uUmHIWRCFRNrLmFsE4tpqNaCZ+gy/EiETTN0626PZI6l3pZRtibubpQoKWYqDYV33LaEfdZNbTNKhN30k2Dd9zuAPKE9upQDBya3J7tP0W2Whz6mvQLJ3fxn9Olx6fXM0xBu3d9GDp6SMKU997ulRO+7shK8NEKEuJBDok0HtJh4fsobXlmPauguLVrVvkvg==" }

 

 

Related content