NZ Banking Data Security Profile v2.0.0

 

Version Control

Version

Date

Author

Comments

Version

Date

Author

Comments

v1.0.0

May 10, 2019 

Payments NZ

Baseline from v1.0.0-draft2

v2.0-draft2

Sep 10, 2019 

@Gavin Wong

Restructuring for v2.0

v2.0-draft3

Sep 17, 2019 

@Gavin Wong

Additions:

Updates:

  • References to Intent Id to "ConsentId" to unify the specifications

  • Separate section for the "NZ Read and Write API Security Profile" which extends the [FAPI Read+Write profile]

  • In 5.2.2.6 updated to "shall issue an ID Token in the token response" as the openid scope must be requested by the Third Party

  • Updated draft3-ImplementationGuide section:

    • To have (1) one example of the Hybrid Flow for the Payment Initiation API and (2) one example of the Decoupled Flow for the Account Information API

    • With updated examples for v2.0 API endpoint names and payloads

  • Updated state to be mandatory in the Hybrid Flow Authorization Request

  • Updated openbanking_intent_id to ConsentId

  • Updated urn:openbanking to urn:apicentre as per Technical Decision - 001 - Namespacing Token Claims

  • Updated nonce to be required "The API Provider must be replay the supplied nonce parameter in any ID Token response."

  • Updated at_hash to be optional in ID Token response

  • Clarification that a Confidential Client "shall accept and verify signed ID Tokens (JWS)"

  • Clarification that "OpenID Connect Request Object values (in the JWT) supersede those which are passed using the OAuth 2.0 request query parameter syntax." in the draft3-RequestObject

  • Clarifications on the claims request parameter in the draft3-RequestObject

  • Clarified that the ID Token sub shall always be populated with the ConsentId as per Technical Decision - 012 - Sub in ID Token

Removed:

  • From draft3-JWKSEndpoints

    • "Each API Provider will host their own JWKS endpoint. Upon issuance of a certificate a JWK Set will be created or updated for a given Third Party."

    • "The private key must have been used by the issuer to get a signing certificate issued from OB."

  • Reference to public clients as OPs are not supporting this functionality

  • References to the request_uri as this functionality is not supported

  • References to the userinfo endpoint as this functionality is not supported

  • In NZ Read and Write API Security Profile 5.2.2

    • Removed client_secret_basic and client_secret_post

    • Removed client_secret_jwt

  • As how to "authenticate the confidential client at the token endpoint" now aligns with FAPI-RW - have removed the variation on authentication methods

  • References to acr as this was optional to support and no guidance is given on how to support

  • From Non-Normative examples of Hybrid Flow - removed at_hash from ID Token as this is not required with the response type "code id_token"

  • Removed support for RSASSA-PKCS1-v1_5 (e.g. RS256) from 8.6JWSAlgorithmConsiderations and 7.10AlgorithmConsiderations as per Technical Decision - 013 - JWS Signing Algorithms

  • Removed references to azp as per Technical Decision - 014 - ID Token Authorized Party Field

  • Removed references to amr as per Technical Decision - 015 - ID Token Authentication Methods References

Errata:

  • Updated 8.2.1 to state "Authorization servers must not support the Request Object Endpoint (request_uri)"

  • "The scope parameter must contain openid" as the profile mandates the hybrid flow

  • "Third Parties must specify code id_token" as the profile mandates the hybrid flow

v2.0-rc2

Jan 3, 2020

@Gavin Wong

Updates:

  • Clarified in Unspecified Behaviour section that “The implementation guide does not illustrate the following configurations in this section.”

  • Updated unspecified behaviour for “Client Credentials Grant Type (scope=openid email profile)”

Removed:

  • Section on “Notation Conventions”

v2.0.0

Mar 31, 2020

@Gavin Wong

Errata:

  • Updated references to “third_party_client_credential” for consistency

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 NZ Banking Data 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 NZ Banking Data 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 NZ Banking Data API Standard. 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 NZ Banking 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.

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.

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.

Non-Normative Examples

Hybrid Flow

This section describes parameters that should be used with a hybrid grant flow request so that an 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 the redirect authorisation flow for the NZ Banking Data 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 an 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:

1 2 3 4 5 6 7 8 GET /authorize? response_type=code%20id_token &client_id=s6BhdRkqt3 &state=af0ifjsldkj& &scope=openid%20payments &nonce=n-0S6_WzA2Mj &redirect_uri=https://api.mytpp.com/cb &request=eyJraWQiOiJsdGFjZXNidyIsImFsZyI6I.....JjVqsDuushgpwp0E.5leGFtcGxlIiwianRpIjoiM....JleHAiOjE0.olnx_YKAm2J1rbpOP8wGhi1BDNHJjVqsDuushgpwp0E

Parameters

Parameter

NZ Banking Data Profile

Notes

Parameter

NZ Banking Data 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 be 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.

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:

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

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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 { "alg": "PS256", "kid": "GxlIiwianVqsDuushgjE0OTUxOTk" } . { "aud": "https://api.alphanbank.com", "iss": "s6BhdRkqt3", "response_type": "code id_token", "client_id": "s6BhdRkqt3", "redirect_uri": "https://api.mytpp.com/cb", "scope": "openid payments", "state": "af0ifjsldkj", "nonce": "n-0S6_WzA2Mj", "max_age": 86400, "claims": { "id_token": { "ConsentId": { "value": "urn-alphabank-intent-58923", "essential": true } } } } . <<signature>>

Claims

Where appropriate follow the JWT Good Practice Guides http://self-issued.info/docs/draft-sheffer-oauth-jwt-bcp-00.html#rfc.section.3.1 

Field

NZ Banking Data Profile

Notes

Field

NZ Banking Data Profile

Notes

aud

Required

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

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.

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 be 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.

ID Token

This is a non-normative example of an ID Token returned - with the sub being populated with the ConsentId.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { "alg": "PS256", "kid": "12345", "typ": "JWT" } . { "iss": "https://api.alphabank.com", "iat": 1234569795, "auth_time": 1234569785, "sub": "urn:alphabank-intent-58923", "ConsentId": "urn:alphabank-intent-58923", "aud": "s6BhdRkqt3", "nonce": "n-0S6_WzA2Mj", "exp": 1311281970, "s_hash": "76sa5dd", "c_hash": "asd097d" } . <<signature>>

Claims

Where appropriate please follow the JWT Good Practice Guides http://self-issued.info/docs/draft-sheffer-oauth-jwt-bcp-00.html#rfc.section.3.1 

Field

NZ Banking Data Profile

Notes

Field

NZ Banking Data 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 unique and non-repeating identifier for the subject.

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

  • The sub must be populated with the ConsentId.

ConsentId

Required

It's acknowledged that this field duplicates the value in "sub".

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.

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 an 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:

1 2 3 4 5 6 7 8 9 10 POST /bc-authorize HTTP/1.1 Host: server.example.com Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded request=eyJraWQiOiJsdGFjZXNidyIsImFsZyI6IlJTMjU2In0.GasCmoMYSMohPOb nwAlkm8Yf0uglhxM83B0dj_I10vwlMGnVFvydaH9wnacM4Ln7E-JIYOxtZa33abf 1PB3fLs29GKOBmgNPn3NrxJ0iCLb0F243556Ypzdhcyj7vM8ukNzkKT3eQ0ZWJ1v VRToThgKyIN-HvLFpeSfJtSH5ycMYOjob-qXUgKpQryUbgbpqsM1XnUV-8aBD5d8 VF5fQoz0.PQWq63B_zpC22nstIFxNmfxztSFpnW0vgX0htNKOtL_HMwFRfwh71g

This is the example Request Object - without Base64 encoding:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 { "alg": "PS256", "kid": "GxlIiwianVqsDuushgjE0OTUxOTk" } . { "aud": "https://api.alphanbank.com", "iss": "s6BhdRkqt3", "nbf": 1537818886, "exp": 1537820086, "iat": 1537819486, "jti": "4LTCqACC2ESC5BWCnN3j58EnA", "client_notification_token": "8d67dc78-7faa-4d41-aabd-67707b374255", "scope": "openid payments" "ConsentId": "urn-alphabank-intent-58923", "login_hint_token": "eyJraWQiOiJsdGFjZXNidyIsImFsZyI6IlJTMjU2I n0.eyJzdWJqZWN0Ijp7InN1YmplY3RfdHlwZSI6InBob25lIiwicGhvbmUiO iIrMTMzMDI4MTgwMDQifX0.YB8_8OksJd1FwfVsIUlH-rs9cPhkIa0DUi7OV W_Da9gP6huBxf7aSDl3qKXA20uT1zThuSiYz0bdz8J_KPRHuC6vwoFlz9yBJ 9ksWOP28sHPPi19_4-xidwnb8P12-RoXwY2eAF82_NAn2vmpvqUjluoWyNHa y8vguChIutqziV0bFl-7oaxp36i4elbvT_DYeg20a0jz4wIBKc_46K8I28Er kwbI5O35GfElPXl-4J55NHkkOsDxuUYQtWjSM3wme19735XWq2DIT2nmLFi4 HzzT27W0cnJg7L_ai9uNNBvIx_Mp5AbcmkR83apR4jxnQuE5Xf23qyRpAhaw e7IPQ" } . <<signature>>

Claims

Field

NZ Banking Data Profile

Notes

Field

NZ Banking Data Profile

Notes

aud

Required

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

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.

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 Banking Data API 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.

1 2 3 4 5 6 7 8 9 10 11 12 13 { "alg": "PS256", "kid": "GxlIiwianVqsDuushgjE0OTUxOTk" } . { "subject": { "subject_type": "phone", "phone": "+64-220466878" } } . <<signature>>

Claims

Field

NZ Banking Data Profile

Notes

Field

NZ Banking Data Profile

Notes

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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 { "alg": "PS256", "kid": "GxlIiwianVqsDuushgjE0OTUxOTk" } . { "aud": "https://api.alphanbank.com", "iss": "s6BhdRkqt3", "nbf": 1537818886, "exp": 1537820086, "iat": 1537819486, "jti": "4LTCqACC2ESC5BWCnN3j58EnA", "client_notification_token": "8d67dc78-7faa-4d41-aabd-67707b374255", "scope": "openid payments" "ConsentId": "urn-alphabank-intent-58923", "id_token_hint": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE2NzcyNiJ9.eyJpc3MiOiJo dHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsInN1YiI6IjI0ODI4OTc2MTAwMSIs ImF1ZCI6InM2QmhkUmtxdDMiLCJlbWFpbCI6ImphbmVkb2VAZXhhbXBsZS5jb20i LCJleHAiOjE1Mzc4MTk4MDMsImlhdCI6MTUzNzgxOTUwM30.aVq83mdy72ddIFVJ LjlNBX-5JHbjmwK-Sn9Mir-blesfYMceIOw6u4GOrO_ZroDnnbJXNKWAg_dxVynv MHnk3uJc46feaRIL4zfHf6Anbf5_TbgMaVO8iczD16A5gNjSD7yenT5fslrrW-NU _vtmi0s1puoM4EmSaPXCR19vRJyWuStJiRHK5yc3BtBlQ2xwxH1iNP49rGAQe_LH fW1G74NY5DaPv-V23JXDNEIUTY-jT-NbbtNHAxnhNPyn8kcO2WOoeIwANO9BfLF1 EFWtjGPPMj6kDVrikec47yK86HArGvsIIwk1uExynJIv_tgZGE0eZI7MtVb2UlCw DQrVlg" } . <<signature>>

Authorization Request Response

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

1 2 3 4 5 6 7 8 9 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 Banking Data Profile

Notes

Field

NZ Banking Data 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.

1 2 3 4 5 6 7 POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW grant_type=urn%3Aopenid%3Aparams%3Agrant-type%3Aciba &auth_req_id=1c266114-a1be-4252-8ad1-04986c5b9ac1

Token Request Response

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE2NzcyNiJ9....eyJpc3MiOiJ dHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsInN1YiI6IjI0ODI4OTc2MTAwMSIs LCJleHAiOjE1Mzc4MTk4MDMsImlhdCI6MTUzNzgxOTUwM30....83mdy72ddIFVJ MHnk3uJc46feaRIL4zfHf6Anbf5_TbgMaVO8iczD16A5gNjSD7yenT5fslrrW-NU DQrVlg" }

Ping Callback

The following is a non-normative example of a Ping callback response. 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.

1 2 3 4 5 6 7 8 POST /cb HTTP/1.1 Host: client.example.com Authorization: Bearer 8d67dc78-7faa-4d41-aabd-67707b374255 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 the ConsentId.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { "alg": "PS256", "kid": "12345" } . { "aud": "s6BhdRkqt3", "iss": "https://api.alphabank.com", "sub": "urn:alphabank-intent-58923", "ConsentId": "urn:alphabank-intent-58923", "iat": 1234569795, "exp": 1311281970 } . <<signature>>

Claims

Where appropriate please follow the JWT Good Practice Guides http://self-issued.info/docs/draft-sheffer-oauth-jwt-bcp-00.html#rfc.section.3.1 

Field

NZ Banking Data Profile

Notes

Field

NZ Banking Data 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 unique and non-repeating identifier for the subject.

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

  • The sub must be populated with the ConsentId.

ConsentId

Required

It's acknowledged that this field duplicates the value in "sub".

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.

Implementation Guide

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

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

  • 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.

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 Banking Data 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 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 Core5.5. Requesting Claims using the "claims" Request Parameter The claims parameter must at least request: "id_token": { "ConsentId": {"value": ConsentId, "essential": true} } The response 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 mandated as the redirect flow for the NZ Banking Data 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

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

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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 POST /as/token.oauth2 HTTP/1.1 Host: https://authn.alphabank.com 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=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRw czovL2p3dC1pZHAuZXhhbXBsZS5jb20iLCJzdWIiOiJtYWlsdG86bWlrZUBleGFtcGxlLmN vbSIsIm5iZiI6MTQ5OTE4MzYwMSwiZXhwIjoxNDk5MTg3MjAxLCJpYXQiOjE0OTkxODM2MD EsImp0aSI6ImlkMTIzNDU2IiwidHlwIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9yZWdpc3Rlc iJ9.SAxPMaJK_wYl_W2idTQASjiEZ4UoI7-P2SbmnHKr6LvP8ZJZX6JlnpK_xClJswAni1T p1UnHJslc08JrexctaeEIBrqwHG18iBcWKjhHK2Tv5m4nbTsSi1MFQOlMUTRFq3_LQiHqV2 M8Hf1v9q9YaQqxDa4MK0asDUtE_zYMHz8kKDb-jj-Vh4mVDeM4_FPiffd2C5ckjkrZBNOK0 01Xktm7xTqX6fk56KTrejeA4x6D_1ygJcGfjZCv6Knki7Jl-6MfwUKb9ZoZ9LiwHf5lLXPuy _QrOyM0pONWKj9K4Mj7I4GPGvzyVqpaZUgjcOaZY_rlu_p9tnSlE781dDLuw
Non-Base64 JWT client_assertion
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { "alg": "PS256", "kid": "12345", "typ": "JWT" } . { "iss": "s6BhdRkqt3", "sub": "s6BhdRkqt3", "exp": 1499187201, "iat": 1499183601, "jti": "id123456", "aud": "https://authn.alphabank.com/as/token.oauth2" } . <<signature>>
Response : Client Credentials
1 2 3 4 5 6 7 8 9 10 11 HTTP/1.1 200 OK Content-Length: 1103 Content-Type: application/json Date: Mon, 26 Jun 2017 15:18:28 GMT { "access_token": "2YotnFZFEjr1zCsicMWpAA", "expires_in": 3600, "token_type": "bearer", "scope": "payments" }

 

2. Third Party uses the Access Token (with payments scope) from the API Provider to invoke the payment-order consent API. 

Request : domestic-payment-consents
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 POST /domestic-payment-consents HTTP/1.1 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA x-idempotency-key: FRESCO.21302.GFX.20 x-fapi-customer-auth-date: 2017-06-13T11:36: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": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "FRESCO.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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 HTTP/1.1 201 Created x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Content-Type: application/json { "Consent": { "ConsentId": "58923", "Status": "AwaitingAuthorisation", "CreationDateTime": "2017-06-05T15:15:13+00:00", "StatusUpdateDateTime": "2017-06-05T15:15:13+00:00", "Consent": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "FRESCO.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://api.alphabank.com/open-banking/v2.0/domestic-payment-consents/58923" }, "Meta": {} }

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 Banking Data Security Profile Request Object section

Base 64 Encoded Example
1 2 3 4 5 6 7 8 9 GET /authorize? response_type=code id_token &client_id=s6BhdRkqt3 &state=af0ifjsldkj &scope=openid payments &nonce=n-0S6_WzA2Mj &redirect_uri=https://api.mytpp.com/cb &request=CJleHAiOjE0OTUxOTk1ODd.....JjVqsDuushgpwp0E.5leGFtcGxlI iwianRpIjoiM....JleHAiOjE0.olnx_YKAm2J1rbpOP8wGhi1BDNHJjVqsDuushgpwp0E
Non-Base64 encoded example of the request parameter object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 { "alg": "PS256", "kid": "GxlIiwianVqsDuushgjE0OTUxOTk" } . { "iss": "https://api.alphabank.com", "aud": "s6BhdRkqt3", "response_type": "code id_token", "client_id": "s6BhdRkqt3", "redirect_uri": "https://api.mytpp.com/cb", "scope": "openid payments", "state": "af0ifjsldkj", "nonce": "n-0S6_WzA2Mj", "max_age": 86400, "claims": { "id_token": { "ConsentId": { "value": "urn:alphabank:intent:58923", "essential": true } } } } . <<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

1 2 3 4 5 HTTP/1.1 302 Found Location: https://api.mytpp.com/cb# code=SplxlOBeZQQYbYS6WxSbIA &id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso &state=af0ifjsldkj

 

2. 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 Banking Data Security Profile Request Object section

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { "alg": "PS256", "kid": "12345", "typ": "JWT" } . { "iss": "https://api.alphabank.com", "iat": 1234569795, "auth_time": 1234569785, "sub": "urn:alphabank:payment:58923", "ConsentId": "urn:alphabank-intent-58923", "aud": "s6BhdRkqt3", "nonce": "n-0S6_WzA2Mj", "exp": 1311281970, "s_hash": "76sa5dd", "c_hash": "asd097d" } . <<signature>>

3. 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 POST /as/token.oauth2 HTTP/1.1 Host: https://authn.alphabank.com Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=authorization_code &code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https://api.mytpp.com/cb &client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer &client_assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRw czovL2p3dC1pZHAuZXhhbXBsZS5jb20iLCJzdWIiOiJtYWlsdG86bWlrZUBleGFtcGxlLmN vbSIsIm5iZiI6MTQ5OTE4MzYwMSwiZXhwIjoxNDk5MTg3MjAxLCJpYXQiOjE0OTkxODM2MD EsImp0aSI6ImlkMTIzNDU2IiwidHlwIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9yZWdpc3Rlc iJ9.SAxPMaJK_wYl_W2idTQASjiEZ4UoI7-P2SbmnHKr6LvP8ZJZX6JlnpK_xClJswAni1T p1UnHJslc08JrexctaeEIBrqwHG18iBcWKjhHK2Tv5m4nbTsSi1MFQOlMUTRFq3_LQiHqV2 M8Hf1v9q9YaQqxDa4MK0asDUtE_zYMHz8kKDb-jj-Vh4mVDeM4_FPiffd2C5ckjkrZBNOK0 01Xktm7xTqX6fk56KTrejeA4x6D_1ygJcGfjZCv6Knki7Jl-6MfwUKb9ZoZ9LiwHf5lLXPuy _QrOyM0pONWKj9K4Mj7I4GPGvzyVqpaZUgjcOaZY_rlu_p9tnSlE781dDLuw
Non-Base64 JWT client_assertion
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { "alg": "PS256", "kid": "12345", "typ": "JWT" } . { "iss": "s6BhdRkqt3", "sub": "s6BhdRkqt3", "exp": 1499187201, "iat": 1499183601, "jti": "id123456", "aud": "https://authn.alphabank.com/as/token.oauth2" } . <<signature>>
Response : Access Token
1 2 3 4 5 6 7 8 9 10 11 HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "access_token": "SlAV32hkKG", "token_type": "Bearer", "expires_in": 3600, "id_token": "eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso" }

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.

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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 POST /domestic-payments HTTP/1.1 Authorization: Bearer SlAV32hkKG x-idempotency-key: FRESNO.1317.GFX.22 x-fapi-customer-auth-date: 2017-06-13T11:36: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": { "ConsentId": "58923", "Initiation": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "FRESCO.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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 HTTP/1.1 201 Created x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Content-Type: application/json { "Data": { "DomesticPaymentId": "58923-001", "ConsentId": "58923", "Status": "AcceptedSettlementInProcess", "CreationDateTime": "2017-06-05T15:15:22+00:00", "StatusUpdateDateTime": "2017-06-05T15:15:22+00:00", "Initiation": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "FRESCO.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://api.alphabank.com/open-banking/v2.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}
1 2 3 4 5 6 GET /domestic-payments/58923-001 HTTP/1.1 Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA x-fapi-customer-auth-date: 2017-06-13T11:36:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Accept: application/json
Response: domestic-payments
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 HTTP/1.1 200 OK x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Content-Type: application/json { "Data": { "DomesticPaymentId": "58923-001", "ConsentId": "58923", "Status": "AcceptedSettlementInProcess", "CreationDateTime": "2017-06-05T15:15:22+00:00", "Initiation": { "InstructionIdentification": "ACME412", "EndToEndIdentification": "FRESCO.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://api.alphabank.com/open-banking/v2.0/domestic-payments/58923-001" }, "Meta": {} }

2. 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.

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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 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 response 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

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

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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 POST /as/token.oauth2 HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=client_credentials &scope=accounts &client-assertion-type%3Ajwt-bearer &client_assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRw czovL2p3dC1pZHAuZXhhbXBsZS5jb20iLCJzdWIiOiJtYWlsdG86bWlrZUBleGFtcGxlLmN vbSIsIm5iZiI6MTQ5OTE4MzYwMSwiZXhwIjoxNDk5MTg3MjAxLCJpYXQiOjE0OTkxODM2MD EsImp0aSI6ImlkMTIzNDU2IiwidHlwIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9yZWdpc3Rlc iJ9.SAxPMaJK_wYl_W2idTQASjiEZ4UoI7-P2SbmnHKr6LvP8ZJZX6JlnpK_xClJswAni1T p1UnHJslc08JrexctaeEIBrqwHG18iBcWKjhHK2Tv5m4nbTsSi1MFQOlMUTRFq3_LQiHqV2 M8Hf1v9q9YaQqxDa4MK0asDUtE_zYMHz8kKDb-jj-Vh4mVDeM4_FPiffd2C5ckjkrZBNOK0 01Xktm7xTqX6fk56KTrejeA4x6D_1ygJcGfjZCv6Knki7Jl-6MfwUKb9ZoZ9LiwHf5lLXPuy _QrOyM0pONWKj9K4Mj7I4GPGvzyVqpaZUgjcOaZY_rlu_p9tnSlE781dDLuw
Non-Base64 JWT client_assertion
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { "alg": "PS256", "typ": "JWT", "kid": "1234adsf" } . { "iss": "s6BhdRkqt3", "sub": "s6BhdRkqt3", "exp": 1499187201, "iat": 1499183601, "jti": "id123456", "aud": "https://server.example.com/as/token.oauth2" } . <<signature>>
Response : Client Credentials
1 2 3 4 5 6 7 8 9 10 11 HTTP/1.1 200 OK Content-Length: 1103 Content-Type: application/json Date: Mon, 26 Jun 2017 15:18:28 GMT { "access_token": "2YotnFZFEjr1zCsicMWpAA", "expires_in": 3600, "token_type": "bearer", "scope": "accounts" }

2. Third Party uses the Access Token (with accounts scope) from the API Provider to create an account-access-consent resource.

Request: Accounts API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 POST /account-access-consents HTTP/1.1 Host: server.example.com Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA x-fapi-customer-auth-date: 2017-06-13T11:36: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": "2017-05-02T00:00:00+00:00", "TransactionFromDateTime": "2017-05-03T00:00:00+00:00", "TransactionToDateTime": "2017-12-03T00:00:00+00:00" } }, "Risk": {} }
Response: Accounts API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 HTTP/1.1 201 Created x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Content-Type: application/json { "Data": { "ConsentId": "88379", "Status": "AwaitingAuthorisation", "CreationDateTime": "2017-05-02T00:00:00+00:00", "StatusUpdateDateTime": "2017-05-02T00:00:00+00:00", "Consent": { "Permissions": [ "ReadAccountsDetail", "ReadBalances", "ReadBeneficiariesDetail", "ReadDirectDebits", "ReadStandingOrdersDetail", "ReadTransactionsCredits", "ReadTransactionsDebits", "ReadTransactionsDetail" ], "ExpirationDateTime": "2017-08-02T00:00:00+00:00", "TransactionFromDateTime": "2017-05-03T00:00:00+00:00", "TransactionToDateTime": "2017-12-03T00:00:00+00:00" } }, "Risk": {}, "Links": { "Self": "https://api.alphabank.com/open-banking/v2.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 Banking Data Security Profile Authorisation Request section

Base 64 Encoded Example
1 2 3 4 5 6 7 8 POST /bc-authorize HTTP/1.1 Host: server.example.com Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded request=eyJraWQiOiJsdGFjZXNidyIsImFsZyI6IlJTMjU2In0...GasCmoMYSM nwAlkm8Yf0uglhxM83B0dj_I10vwlMGnVFvydaH9wnacM4Ln7E-JIYOxtZa33abf VF5fQoz0....Pq63B_zpC22nstIFxNmfxztSFpnW0vgX0htNKOtL_HMwFRfwh71g
Non-Base64 encoded example of the request object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 { "alg": "PS256", "kid": "GxlIiwianVqsDuushgjE0OTUxOTk" } . { "aud": "https://api.alphanbank.com", "iss": "s6BhdRkqt3", "nbf": 1537818886, "exp": 1537820086, "iat": 1537819486, "jti": "4LTCqACC2ESC5BWCnN3j58EnA", "scope": "openid accounts" "client_notification_token": "8d67dc78-7faa-4d41-aabd-67707b374255", "ConsentId": "urn-alphabank-intent-58923", "login_hint_token": "eyJraWQiOiJsdGFjZXNidyIsImFsZyI6gIlJTMjU2I n0....eyJzdWJqZWN0IjNHkkOsDxuUYQtWjSM3wme19735XWq2DIT2nmLFi4 HzzT27W0cnJg7L_ai9uNNBvIx_Mp5AbcmkR83apR4jxnQ....123qyRpAhaw e7IPQ" } . <<signature>>
Non-Base64 encoded example of the login hint token
1 2 3 4 5 6 7 8 9 10 11 12 13 { "alg": "PS256", "kid": "GxlIiwianVqsDuushgjE0OTUxOTk" } . { "subject": { "subject_type": "phone", "phone": "+13302818004" } } . <<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.

1 2 3 4 5 6 7 8 9 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 }

2. 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
1 2 3 4 5 6 7 8 POST /cb HTTP/1.1 Host: client.example.com Authorization: Bearer 8d67dc78-7faa-4d41-aabd-67707b374255 Content-Type: application/json { "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1" }
Response : No Content
1 HTTP/1.1 204 No Content

3. 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
1 2 3 4 5 6 7 POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Bearer czZCaGRSa3F0MzpnWDFmQmF0M2JW grant_type=urn%3Aopenid%3Aparams%3Agrant-type%3Aciba &auth_req_id=1c266114-a1be-4252-8ad1-04986c5b9ac1
Response : Access Token (with Optional Refresh Token)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE2NzcyNiJ9.eyJpc3MiOiJo dHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsInN1YiI6IjI0ODI4OTc2MTAwMSIs ImF1ZCI6InM2QmhkUmtxdDMiLCJlbWFpbCI6ImphbmVkb2VAZXhhbXBsZS5jb20i LCJleHAiOjE1Mzc4MTk4MDMsImlhdCI6MTUzNzgxOTUwM30.aVq83mdy72ddIFVJ LjlNBX-5JHbjmwK-Sn9Mir-blesfYMceIOw6u4GOrO_ZroDnnbJXNKWAg_dxVynv MHnk3uJc46feaRIL4zfHf6Anbf5_TbgMaVO8iczD16A5gNjSD7yenT5fslrrW-NU _vtmi0s1puoM4EmSaPXCR19vRJyWuStJiRHK5yc3BtBlQ2xwxH1iNP49rGAQe_LH fW1G74NY5DaPv-V23JXDNEIUTY-jT-NbbtNHAxnhNPyn8kcO2WOoeIwANO9BfLF1 EFWtjGPPMj6kDVrikec47yK86HArGvsIIwk1uExynJIv_tgZGE0eZI7MtVb2UlCw DQrVlg" }
ID Token - Non-Base 64 Encoded
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 { "alg": "PS256", "kid": "12345", "typ": "JWT" } . { "iss": "https://server.example.com", "iat": 1234569795, "exp": 1311281970, "sub": "urn-alphabank-intent-88379", "ConsentId": "urn-alphabank-intent-88379", "aud": "s6BhdRkqt3", "https://www.apicentre.paymentsnz.co.nz/refresh_token_expires_at": 2592000 } . <<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
1 2 3 4 5 6 7 GET /accounts HTTP/1.1 Host: server.example.com Authorization: Bearer G5kXH2wHvUra0sHlDy1iTkDJgsgUO1bN x-fapi-customer-auth-date: 2017-06-13T11:36:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Accept: application/json
Response: Bulk accounts resource
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 HTTP/1.1 200 OK x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d 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/v2.0/accounts" }, "Meta": { "TotalPages": 1 } }
Request : Specific Account Id
1 2 3 4 5 6 7 GET /accounts/22289 HTTP/1.1 Host: server.example.com Authorization: Bearer G5kXH2wHvUra0sHlDy1iTkDJgsgUO1bN x-fapi-customer-auth-date: 2017-06-13T11:36:09 x-fapi-customer-ip-address: 104.25.212.99 x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d Accept: application/json
Response: Specific Account Id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 HTTP/1.1 200 OK x-fapi-interaction-id: 93bac548-d2de-4546-b106-880a5018460d 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/v2.0/accounts/22289" }, "Meta": { "TotalPages": 1 } }
Request: Refresh Token Request using private_key_jwt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 POST /as/token.oauth2 HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Accept: application/json grant_type=refresh_token &refresh_token=4bwc0ESC_IAhflf-ACC_vjD_ltc11ne-8gFPfA2Kx16 &scope=openid accounts &client-assertion-type%3Ajwt-bearer &client_assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRw czovL2p3dC1pZHAuZXhhbXBsZS5jb20iLCJzdWIiOiJtYWlsdG86bWlrZUBleGFtcGxlLmN vbSIsIm5iZiI6MTQ5OTE4MzYwMSwiZXhwIjoxNDk5MTg3MjAxLCJpYXQiOjE0OTkxODM2MD EsImp0aSI6ImlkMTIzNDU2IiwidHlwIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9yZWdpc3Rlc iJ9.SAxPMaJK_wYl_W2idTQASjiEZ4UoI7-P2SbmnHKr6LvP8ZJZX6JlnpK_xClJswAni1T p1UnHJslc08JrexctaeEIBrqwHG18iBcWKjhHK2Tv5m4nbTsSi1MFQOlMUTRFq3_LQiHqV2 M8Hf1v9q9YaQqxDa4MK0asDUtE_zYMHz8kKDb-jj-Vh4mVDeM4_FPiffd2C5ckjkrZBNOK0 01Xktm7xTqX6fk56KTrejeA4x6D_1ygJcGfjZCv6Knki7Jl-6MfwUKb9ZoZ9LiwHf5lLXPuy _QrOyM0pONWKj9K4Mj7I4GPGvzyVqpaZUgjcOaZY_rlu_p9tnSlE781dDLuw
Response: Refresh Token

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

1 2 3 4 5 6 7 8 9 10 11 HTTP/1.1 200 OK Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "access_token": "TYstftas123j", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "XUUGas123ed" }

 

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 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 practice to be followed where appropriate:

http://self-issued.info/docs/draft-sheffer-oauth-jwt-bcp-00.html#rfc.section.3.1

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://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-4.1

The JOSE header is a JSON object consisting of two 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.

The list of valid algorithms is here https://tools.ietf.org/html/rfc7518#section-3.1.

This must be an algorithm that support asymmetric encryption.

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:

1 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:

1 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:

1 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 Banking Data Security Profile.

Certificates

API Providers and Third Parties must obtain their own network and message signing certificates from one of the accepted CA Issuers.

The requirements for production certificates are:

  • must use X.509 v3 format

  • must use an RSA public key algorithm

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

  • should include certificate chain in the PEM file

  • must have a key length of at least 4096 bits

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

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

  • must be from one of these Certificate Authority issuers:

    • Comodo

    • DigiCert

    • Entrust

    • Thawte

    • Verisign

  • must be an OV (organisation validation) certificate

  • must have different certificates for network establishment and message signing

API Centre Register

Organisations

Once an organisation is verified with the Payments NZ API Centre as an API service user, the 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 message signing certificates uploaded for an organisation meet these requirements:

  • Is in X.509 v3 format

  • Is an RSA public key algorithm

  • Uses RS512 or PS512 as a signing algorithm

  • Has a key length of at least 4096 bits

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

  • Has key usage policies for signing, and does not have key usage policies for network

    • digitalSignature (0)

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

    • keyEncipherment (2)

    • keyAgreement (4)

  • Is an end-entity certificate

The API Centre Register service will check that all signing certificates used in the API ecosystem in a production environment meet these requirements:

  • Has a certificate Issuer Organisation name that is one of the valid issuers:

    • Comodo

    • DigiCert

    • Entrust

    • Thawte

    • Verisign

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

The repository for the Security Profile can be found in GitHub at the below location:

https://github.com/PaymentsNZ/API-Security-Profile/tree/master/dist/v2.0.0