v3.0.1 Security Profile
- 1 Version Control
- 2 Introduction
- 2.1 Security Architecture
- 2.1.1 OAuth 2.0
- 2.1.2 OIDC Core
- 2.1.3 OIDC Client Initiated Backchannel Authentication
- 2.1.4 FAPI
- 2.2 Scope
- 2.3 Normative References
- 2.4 Terms and Definitions
- 2.5 Symbols and Abbreviated Terms
- 2.6 Authorisation Scopes
- 2.7 Consent Authorisation
- 2.8 Token Expiry
- 2.8.1 Token Expiry Time
- 2.9 Supported Grant Types
- 2.9.1 Client Credentials Grant
- 2.9.2 Authorization Code Flow
- 2.9.2.1 ID Token
- 2.9.2.2 Error Condition
- 2.9.3 Hybrid Flow
- 2.9.3.1 ID Token
- 2.9.3.2 Error Condition
- 2.9.4 Decoupled Flow (CIBA)
- 2.9.4.1 ID Token Hint
- 2.9.4.2 Login Hint Token
- 2.10 Changes to Consent Status
- 2.11 Consent Re-authorisation
- 2.11.1 Use of Refresh Token
- 2.1 Security Architecture
- 3 NZ Read and Write API Security Profile
- 3.1 5.2 Read and Write API Security Provisions
- 3.1.1 5.2.1 Introduction
- 3.1.2 5.2.2 Authorization Server
- 3.1.3 5.2.4 Confidential Client
- 3.2 6. Accessing Protected Resources
- 3.2.1 6.1 Introduction
- 3.2.2 6.2 Access Provisions
- 3.2.2.1 6.2.1 Protected resources provisions
- 3.2.2.2 6.2.2 Client Provisions
- 3.3 7. Request Object Endpoint
- 3.3.1 7.1 Introduction
- 3.4 8. Security Considerations
- 3.1 5.2 Read and Write API Security Provisions
- 4 NZ Client Initiated Backchannel Authentication Profile
- 5 Non-Normative Examples
- 5.1 Hybrid Flow
- 5.1.1 Authorization Request
- 5.1.1.1 Parameters
- 5.1.2 Request Object
- 5.1.2.1 Claims
- 5.1.3 Authorisation Response
- 5.1.4 ID Token
- 5.1.4.1 Claims
- 5.1.1 Authorization Request
- 5.2 Authorization Code Flow
- 5.2.1 Pushed Authorization Requests (PAR) with JWT-Secured Authorization Requests & Proof-Key Code Exchange
- 5.2.1.1 Proof Key Code Exchange
- 5.2.2 Authentication
- 5.2.3 PAR Request using JAR
- 5.2.4 PAR Response
- 5.2.5 Error Response
- 5.2.6 Authorize request with PAR
- 5.2.7 OIDC metadata
- 5.2.8 JWT-Secured Authorization Response Mode (JARM)
- 5.2.8.1 FAPI 1.0
- 5.2.8.2 Signing and encryption
- 5.2.8.3 Example JARM response
- 5.2.8.4 Error response
- 5.2.8.5 Token request
- 5.2.8.6 Token response
- 5.2.1 Pushed Authorization Requests (PAR) with JWT-Secured Authorization Requests & Proof-Key Code Exchange
- 5.3 Decoupled Request
- 5.3.1 Authorization Request
- 5.3.1.1 Claims
- 5.3.2 Login Hint Token
- 5.3.2.1 Claims
- 5.3.3 ID Token Hint
- 5.3.4 Authorization Request Response
- 5.3.4.1 Claims
- 5.3.5 Token Request
- 5.3.6 Token Request Response
- 5.3.7 Ping Callback
- 5.3.8 ID Token
- 5.3.8.1 Claims
- 5.3.1 Authorization Request
- 5.1 Hybrid Flow
- 6 Implementation Guide
- 6.1 Hybrid Flow
- 6.1.1 Client Types
- 6.1.2 Grant Types
- 6.1.2.1 Client Credentials Grant Type
- 6.1.2.2 Hybrid Flow
- 6.1.3 Access Tokens
- 6.1.4 Refresh Tokens
- 6.1.5 ID Tokens
- 6.1.6 Authorization Codes
- 6.1.7 Unspecified Behaviour
- 6.1.7.1 Client Types
- 6.1.7.2 Grant Types
- 6.1.7.3 Validity Lengths
- 6.1.8 Success Flows
- 6.1.8.1 Client Credentials Grant Type (OAuth 2.0)
- 6.1.8.2 OIDC Hybrid Flow
- 6.1.9 Non-Normative HTTP Request and Response Examples
- 6.1.9.1 Step 1 - Agree Payment Consent
- 6.1.9.2 Step 2 - Setup Payment-Order Consent
- 6.1.9.3 Step 3 - Authorize Consent
- 6.1.9.4 Step 4 - Create Payment-Order
- 6.1.9.5 Step 5 - Get Domestic-Payment Status
- 6.2 Authorization Code Flow
- 6.2.1 Client types
- 6.2.2 Grant types
- 6.2.2.1 Client Credentials grant type
- 6.2.2.2 Authorization Code Flow
- 6.2.3 Access Tokens
- 6.2.4 Refresh Tokens
- 6.2.5 ID Tokens
- 6.2.6 Authorization Codes
- 6.2.7 Pushed Authorization Requests
- 6.2.7.1 Proof Key for Code Exchange
- 6.2.8 FAPI JWT-Secured Authorization Response Mode (JARM)
- 6.2.9 Unspecified Behaviour
- 6.2.9.1 Client Types
- 6.2.9.2 Grant Types
- 6.2.9.3 Validity Lengths
- 6.2.9.4 Authorization Code
- 6.2.9.5 ID Token
- 6.2.9.6 Access Token
- 6.2.9.7 Refresh Token
- 6.2.10 Success Flows
- 6.2.10.1 Client Credentials Grant Type (OAuth 2.0)
- 6.2.10.2 Authorization Code Flow
- 6.2.11 Non-Normative HTTP Request and Response Examples
- 6.2.11.1 Step 1 - Agree Payment Consent
- 6.2.11.2 Step 2 - Setup Payment-Order Consent
- 6.2.11.3 Step 3 - Pushed Authorization Request (PAR)
- 6.2.11.4 Step 4 - Authorise Consent with JARM response
- 6.2.11.5 Step 5 - Retrieve Tokens
- 6.2.11.6 Step 6 - Create Payment Order
- 6.2.11.7 Step 7 Get Domestic-Payment Status
- 6.3 Decoupled Flow
- 6.3.1 Client Types
- 6.3.2 Grant Types
- 6.3.2.1 Client Credentials Grant Type
- 6.3.2.2 CIBA Flow
- 6.3.3 Access Tokens
- 6.3.4 Refresh Tokens
- 6.3.5 ID Tokens
- 6.3.6 Unspecified Behaviour
- 6.3.6.1 Validity Lengths
- 6.3.7 Success Flows
- 6.3.7.1 Client Credentials Grant Type (OAuth 2.0)
- 6.3.7.2 CIBA Flow
- 6.3.8 Non-Normative HTTP Request and Response Examples
- 6.4 Refresh token introspection
- 6.4.1 Overview
- 6.4.1.1 Steps
- 6.4.2 Endpoints
- 6.4.2.1 POST /introspect
- 6.4.3 Sequence diagram
- 6.4.4 Data model
- 6.4.4.1 Introspection request
- 6.4.4.2 Introspection response
- 6.4.5 Endpoint Authentication
- 6.4.6 Metadata
- 6.4.7 Usage Examples
- 6.4.7.1 POST Introspection request
- 6.4.7.2 POST Introspection response
- 6.4.8 Errors
- 6.4.1 Overview
- 6.5 Edge Cases
- 6.1 Hybrid Flow
- 7 JSON Security Suite
- 8 Prerequisites
- 8.1 Certificates
- 8.2 API Centre Register
- 8.2.1 Organisations
- 8.2.2 Keys
- 8.2.3 Authorisation Servers
- 8.2.4 Swagger
- 8.3 Keys used in examples
- 8.3.1 API provider:
- 8.3.2 Third Party:
Version Control
Version | Date | Author | Comments |
|
---|---|---|---|---|
3.0.0-draft1 | May 3, 2022 | Payments NZ API Working Group | Baseline |
|
3.0.0-draft2 | Nov 21, 2022 | @Nigel Somerfield | Added refresh token introspection |
|
3.0.0-draft2 | Dec 15, 2022 | @Nigel Somerfield |
|
|
3.0.0-draft2 | Jan 5, 2023 | @Nigel Somerfield | Updated Decoupled Flow examples |
|
3.0.0-draft2 | Jan 9, 2023 | @Nigel Somerfield | Updated Decoupled Flow implementation guide |
|
3.0.0-draft2 | Jan 10, 2023 | @Nigel Somerfield | Updated Hybrid Flow implementation guide |
|
3.0.0-draft2 | Feb 15, 2023 | @Nigel Somerfield | Added supported authorisation grant types |
|
3.0.0-draft2 | Feb 21, 2023 | @Nigel Somerfield | Updated:
Added:
|
|
3.0.0-draft2 | Mar 1, 2023 | @Nigel Somerfield | Added:
Updated:
|
|
3.0.0-draft2 | Mar 13, 2023 | @Nigel Somerfield | Removed |
|
3.0.0-draft2 | Apr 4, 2023 | @Nigel Somerfield | Added missing |
|
3.0.0-draft2 | Apr 24, 2023 | @Nigel Somerfield | Updated:
Added:
|
|
3.0.0-rc1 | May 5, 2023 | @Nigel Somerfield | Migrated:
Updated:
|
|
3.0.0-rc1 | Jun 16, 2023 | @Nigel Somerfield | Updated:
|
|
3.0.0-rc1 | Jul 21, 2023 | @Nigel Somerfield | Corrected:
|
|
3.0.0-rc2 | Sep 12, 2023 | @Nigel Somerfield | Baselined for release candidate 2 |
|
3.0.1 | Sep 3, 2024 | @Nigel Somerfield | Updated sections 7.1.2, 8.1 and 8.3. Clarify signing algorithms, certificate section and updated example keys to use Jira issue addressed: Patch release documentation: #005 v2.1.3, V2.2.3, v2.3.3, V3.0.1 Proposed update page that has been merged: |
|
Introduction
This document is based on the OpenID Foundation's Financial-grade API Read+Write specification FAPI-RW, which in turn is based on the Read only specification document FAPI. In addition, the Financial-grade API: Client Initiated Backchannel Authentication Profile FAPI-CB has been incorporated, to support a decoupled authentication flow. The Security Profile will further shape these profiles in some cases tightening restrictions and in others loosening requirements using keywords. Please see the introduction to FAPI-RW for a general introduction to the aims of this document.
The Security Profile outlines the differences between the FAPI-RW and FAPI-CB with clauses and provisions necessary to reduce delivery risk for API Providers.
Security Architecture
OAuth 2.0
OAuth 2.0 will be the foundational framework for API Security for the in-scope API standards. OAuth 2.0 itself is a framework which can be deployed in many ways, some of them completely incompatible with financial models. In order to securely use the OAuth 2.0 framework, a profile must exist by which both Third Parties and API Providers are certified to have correctly configured their clients and servers.
OIDC Core
The OpenID Connect Request object uses exactly the same claims object for specifying claim names, priorities, and values as OAuth 2.0. However if the Request object is used, the Claims object becomes a member in an assertion that can be signed and encrypted, allowing the API Provider to authenticate the request from the Third Party and ensure it hasn't been tampered with. The OpenID Connect Request object can either be passed as a query string parameter, or can be referenced at an endpoint that could theoretically be protected by MATLS. The use of JWT Request objects by reference is not supported due a number of delivery risks and remaining security concerns.
In addition to specifying a ticket, the Third Party can optionally require a minimum strength of authentication context or request to know how long ago the user was actually authenticated. Multiple tickets could be passed if necessary. Everything is fully specified. Vendors who implement this feature are not creating a one-off proprietary feature, they are simply supporting the OpenID Connect standard.
Full accountability is available as required by all participants. Not only can the API Provider prove that they received the original request from the Third Party, but the Third Party can prove that the access token that comes back was the token that was intended to be affiliated to this specific ConsentId.
OIDC Client Initiated Backchannel Authentication
The OIDC Client Initiated Backchannel Authentication (CIBA) profile enables a Client (Third Party) to initiate the authentication of the end-user (Customer) with the OpenID Provider (API Provider) in an out of band mechanism. This direct out of band mechanism between the Third Party and API Provider means that the Customer is not redirected to authenticate through the Customer's browser (or consumption device).
FAPI
The Financial API working group in the OpenID Foundation has created a draft standard for configuration of Financial-grade API security regimes. If any FAPI-compliant vendor can participate in the Open Data API ecosystem, it means that vendors can work to the standard and reach many customers, rather than having to create different solutions for different banking platforms. The FAPI profiles apply to both OIDC Core and OIDC CIBA profiles.
Scope
This part of the document specifies the method of
Applications to obtain the OAuth tokens in an appropriately secure manner for financial data access;
Applications to use OpenID flows to identify the Customer; and
Using tokens to interact with the REST endpoints that provides financial data;
This document is applicable to higher risk use cases which includes commercial and investment banking.
Normative References
The following referenced documents are strongly recommended to be used in conjunction with this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.
[FAPI] - FAPI ReadOnly profile [FAPI]: http://openid.net/specs/openid-financial-api-part-1.html
[FAPI-RW] - FAPI Read+Write profile [FAPI-RW]: http://openid.net/specs/openid-financial-api-part-2.html
[OIDC] - OpenID Connect Core 1.0 incorporating errata set 1 [OIDC]: http://openid.net/specs/openid-connect-core-1_0.html
[MTLS] - Mutual TLS Profile for OAuth 2.0 [MTLS]: https://datatracker.ietf.org/doc/rfc8705/
[CIBA] - OpenID Connect Client Initiated Backchannel Authentication Flow - Core 1.0 draft-02 [CIBA]: https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html
[FAPI-CB] - Financial-grade API: Client Initiated Backchannel Authentication Profile [FAPI-CB]: https://openid.net/specs/openid-financial-api-ciba-ID1.html
[OAUTH-CLIENT-AUTH] - Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants [OAUTH-CLIENT-AUTH]: https://tools.ietf.org/html/rfc7521
[JARM] - OpenID FAPI JWT-Secured Authorization Response Mode: https://openid.net/specs/openid-financial-api-jarm.html
[PAR] - OAuth 2.0 Pushed Authorization Requests: https://www.rfc-editor.org/rfc/rfc9126.html
[JAR] - The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR): https://www.rfc-editor.org/rfc/rfc9101.html
[PKCE] - Proof Key for Code Exchange by OAuth Public Clients: https://www.rfc-editor.org/rfc/rfc7636.html
[BCP-225] - JSON Web Token Best Current Practices: https://www.rfc-editor.org/rfc/rfc8725
Terms and Definitions
For the purpose of this document, the terms defined in [FAPI ReadOnly profile] FAPI, [FAPI Read+Write profile] FAPI-RW, [OpenID Connect Core] OIDC, [OpenID Connect Client Initiated Backchannel Authentication Flow] CIBA, and [FAPI: Client Initiated Backchannel Authentication Profile] FAPI-CB apply.
Symbols and Abbreviated Terms
API Provider - provides APIs in a manner that complies with the API Standards (e.g. Account Information and Payment Initiation APIs), and connects those APIs with a Third Party.
Third Party - the entity that consumes an API in a manner that complies with the API Standards.
Customer - a natural or legal person that operates banking accounts.
Authorisation Scopes
To access each of the APIs, the API must be called with an access token in the HTTP Authorization
header.
The scopes required with these access tokens and the grant type used to get the access token are specified in the specific API documentation.
Consent Authorisation
OAuth 2.0 scopes are coarse grained and the set of available scopes are defined at the point of client registration. There is no standard method for specifying and enforcing fine grained scopes (e.g. a scope to specify that account information should only be provided for certain time periods or to enforce payments of a specified amount on a specified date).
A consent (identified with a ConsentId) is used to define the fine-grained permissions that are granted by the Customer to the Third Party. The API specifications define a variety of consents resources such as account-access-consents and domestic-payment-consents. The act of a Customer providing authorisation of a consent with an API Provider is called consent authorisation.
Two generic consent types are used in the API specification:
Short lived consents - these are used for one-off access to a protected resource
Long lived consents - these are used for enduring access to a protected resource
Steps for consent authorisation are:
The Third Party requests an API Provider to create a consent (with the fine-grained permissions) using a client credentials grant.
The API Provider creates the consent and responds with a ConsentId.
The Third Party then initiates an authorisation flow (passing in the ConsentId as a parameter) where the Customer authorises the consent with the API Provider. The supported grant types for the authorisation flow are described below.
The API Provider issues an access token to the Third Party tied to the authorised consent and the Customer.
Token Expiry
An API Provider may issue an access token and refresh token for a long-lived consent. These tokens may expire before the consent expires. In such a situation, the state of the consent does not change and the API Provider must not modify the state of the consent.
Token Expiry Time
The expiry time for issued access tokens and refresh tokens must be deterministic for the Third Party.
In order to achieve this:
The API Provider must indicate the lifetime in seconds of the access token in the
expires_in
field of the JSON object returned by the token endpoint (see https://tools.ietf.org/html/rfc6749#section-4.2.2 ).If the API Provider issues a refresh token, the API Provider must support refresh token introspection, as per the Security Profile
The location of the introspection endpoint is indicated in authorisation server metadata
introspection_endpoint
.If the API Provider issues a refresh token that does not expire, the API Provider must populate refresh token introspection response claim
exp
with a value representing the number of seconds to 03:14:07 UTC on 19 January 2038 (end of 32-bit UNIX epoch), or a value further in the future.
Supported Grant Types
OAuth2.0 and OIDC provide support for a variety of methods for the Authorization Server to issue an access token to the Client. These methods are called Grants.
Some of these Grant Types only identify the client, but not the resource owner. It is sufficient to provide the client's identity.
On the other hand, other grant types identify the client and resource owner. The resource owner must be authenticated to issue access tokens through such a grant type.
The Security Profile supports a sub-set of these grants as well as the FAPI Profile CIBA grant.
Grant Type | Mandatory? |
---|---|
Client Credentials | Mandatory |
Authorization Code Flow (using PAR with PKCE and JARM) | Mandatory |
Hybrid Flow | Optional |
Decoupled Flow (CIBA) | Mandatory |
Client Credentials Grant
Some of the APIs can be accessed using an access token issued through a Client Credentials Grant. These APIs are not restricted resources owned by the Customer and do not require Customer consent authorisation. It is sufficient to identify and authenticate the Third Party in order to call these APIs.
The Client Credentials Grant is documented in Section 4.4 of the OAuth 2.0 RFC.
Authorization Code Flow
The Authorization Code Flow (see https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth ), used with PAR, PKCE and JARM is both more secure and offers a better consumer experience than the Hybrid Flow.
The Authorization Code Flow uses Pushed Authorization Requests, aka PAR (with PKCE) to submit an authorization request for validation, before redirecting the customer. Third Parties can then redirect when an authorization request has passed technical validation with the API provider.
The JARM response removes the need for ID token to be exposed via the redirect, and as such prevents leakage of identity information. Because the JARM response is a signed-JWT, there is no requirement for detached signature, code hash or state hash.
ID Token
When an access token is generated through a Authorization Code Flow, an OIDC Authorization Server will also issue an ID Token along with the access token.
The ID Token is a signed JWT that consists of a number of claims that identify the resource owner. In the NZ Open Data API context, the ID Token always identifies the consent (using ConsentId
claim) that was authorised and Customer who authorised it (using the sub
claim).
As the ID Token is signed by the API Provider and bound to a specific Third Party (through the aud
claim), the ID Token could be leveraged to identify the Customer in subsequent authorisation requests. OIDC caters for this by allowing the ID Token to be passed into an authorization code grant request as the id_token_hint
query parameter (as documented here).
Error Condition
If the Customer does not complete a successful consent authorisation (e.g. if the Customer is not authenticated successfully), the authorization flow ends with a redirection to the Third Party with an error response as described in section 4.1.1 herehttps://openid.net/specs/openid-financial-api-jarm.html#the-jwt-response-document . The Customer is redirected to the Third Party with an error parameter indicating the error that occurred.
Hybrid Flow
The Hybrid Flow enables access to APIs that require the Customer as well as Third Party to be identified and authenticated.
The Hybrid Flow (see Section 3.3. of the OIDC Specification) provides a redirect based mechanism to redirect a Customer to the API Provider's authorisation pages in order to authenticate the Customer and generate an authorization code. The Third Party can then exchange this authorization code for an access token (and optionally refresh token) by calling the API Provider's token endpoint and authenticating itself.
The Security Profile and FAPI Read & Write API Security Profile specify a more stringent set of requirements that API Providers and Third Parties must adhere to.
ID Token
When an access token is generated through a Hybrid Flow, an OIDC Authorization Server will also issue an ID Token along with the access token.
The ID Token is a signed JWT that consists of a number of claims that identify the resource owner. In the Security Profile API context, the ID Token always identifies the consent (using ConsentId
claim) that was authorised and Customer who authorised it (using the sub
claim).
As the ID Token is signed by the API Provider and bound to a specific Third Party (through the aud
claim), the ID Token could be leveraged to identify the Customer in subsequent authorisation requests. OIDC caters for this by allowing the ID Token to be passed into an authorization code grant request as the id_token_hint
query parameter (as documented here).
Error Condition
If the Customer does not complete a successful consent authorisation (e.g. if the Customer is not authenticated successfully), the hybrid flow ends with a redirection to the Third Party with an error response as described in RFC 6749 Section 4.1.2.1. The Customer is redirected to the Third Party with an error parameter indicating the error that occurred.
Decoupled Flow (CIBA)
The CIBA flow is a decoupled authentication flow that enables access to APIs that require the Customer as well as Third Party to be identified and authenticated.
The Client Initiated Back-channel Authentication flow is part of the OpenID specifications. A FAPI Profile of the CIBA specification is available and API Providers that implement the CIBA Flow must adhere to this FAPI profile.
An API Provider must implement the CIBA Flow to allow Customers to authenticate themselves using a decoupled authentication device that may be distinct from the consumption device on which they consume the Third Party application.
The NZ Security Profile specifies a more stringent set of requirements that API Providers and Third Parties must adhere to.
An API Provider:
must support the
id_token_hint
as a method of identifying the Customer to be authenticated.may support
login_hint_token
as a method of identifying the Customer to be authenticated.must document on their developer portal, the methods of identifying a Customer that the API Provider supports.
A Third Party:
must pass a method of identifying the Customer in the authorisation request object using either the
login_hint_token
orid_token_hint
(i.e., not both).must create a consent with the API Provider prior to creating the CIBA authorisation request.
must pass the generated ConsentId as a custom claim in the authorisation request object (this allows the access token that is eventually generated to be bound to a specific consent).
If an API Provider does not support a specific method of identifying a Customer, the API Provider must return an error with the error
field set to invalid_request
as per https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.13 .
ID Token Hint
To identify a Customer through a previously issued ID Token - the Third Party must issue an authorisation request object with an id_token_hint
which contains an ID Token from a previously successful authentication event for the Customer. As this is a previously used ID Token, it is valid for a Third Party to use an expired ID Token.
Third Parties must provide either a login_hint_token
or id_token_hint
(i.e., not both).
Login Hint Token
The login_hint_token is a token in the CIBA authorisation request object that contains a subject_type and corresponding claim that identifies the Customer for whom authentication is being requested.
Third Parties must provide either a login_hint_token or an id_token_hint (i.e., not both).
The Security Profile and related APIs support these login_hint_token identification claims:
phone
email
username
api_provider_token
third_party_token
UML Diagram
Data Model
Name | Occurrence | XPath | EnhancedDefinition | Class | Codes |
---|---|---|---|---|---|
NZLoginHintToken1 |
| NZLoginHintToken1 |
| NZLoginHintToken1 |
|
subject | 0..1 | NZLoginHintToken1/subject |
| NZLoginHintType1 |
|
subject_type | 1..1 | NZLoginHintToken1/subject/subject_type | The type of subject identification used in the login_hint_token. The subject_type must be accompanied by the corresponding claim field. E.g., a subject_type of "phone" must be accompanied by the corresponding phone claim. | NZCIBASubject1Code | api_provider_token |
phone | 0..1 | NZLoginHintToken1/subject/phone | A phone number that identifies the Customer with the API Provider. | PhoneNumber |
|
0..1 | NZLoginHintToken1/subject/email | An email address that identifies the Customer with the API Provider. | Max256Text |
| |
username | 0..1 | NZLoginHintToken1/subject/username | The username that identifies the Customer with the API Provider. | Max70Text |
|
api_provider_token | 0..1 | NZLoginHintToken1/subject/api_provider_token | A token generated by a Customer's authentication device that identifies the Customer with the API Provider. This token is passed to the Third Party. | xs:string |
|
third_party_token | 0..1 | NZLoginHintToken1/subject/third_party_token | A token generated by a Third Party and registered with a Customer's authentication device by the Customer. | xs:string |
|
Example
This is an example of a login_hint_token using the phone number as the subject_type:
{
"alg": "PS256",
"kid": "GxlIiwianVqsDuushgjE0OTUxOTk"
}
.
{
"subject": {
"subject_type": "phone",
"phone": "+64-220466878"
}
}
.
<<signature>>
Changes to Consent Status
A Customer may revoke their consent either through the Third Party or directly through the API Provider. This only applies to long-lived consents.
When the Customer revokes their consent with the API Provider, the API Provider must update the consent Status as
Revoked
.When the Customer revokes their consent with the Third Party, the Third Party must make a request to DELETE the consent using the ConsentId.
In each of the above cases, the consent states are terminal i.e., the API Provider must not allow any further state changes. The API Provider must not permit any authorisation code grants to be initiated with such a consent.
Consent Re-authorisation
Consent re-authorisation is the scenario where the API Provider requests a long-lived consent to be re-authorised (e.g., because of fraud risk). In this scenario, the Third Party reuses the existing ConsentId, and the API Provider may tailor the re-authorisation flow to be more efficient than the full consent authorisation flow.
A Third Party may request a Customer to re-authorise an existing long-lived consent that is in the Authorised
state (using the existing ConsentId) at any point of time. This includes before and after the tokens bound to the consent have expired.
An API Provider must accept a request from a Third Party to re-authorise a long-lived consent (that is in the Authorised
state) at any point of time. This includes before and after the tokens bound to the consent have expired.
Once a consent is re-authorised, the Third Party must not use access tokens and refresh tokens that were previously issued for the same consent.
If an API Provider issues a new access token and refresh token as a result of consent re-authorisation, it may invalidate the previously issued access tokens and refresh tokens for the same consent.
Use of Refresh Token
An API Provider may issue a refresh token along with an access token as a result of consent re-authorisation.
When an access token expires, the Third Party may attempt to get a new access and refresh token as defined in Section 6 of the OAuth 2.0 specification.
If the Third Party fails to get an access token using a refresh token, the Third Party must initiate a consent re-authorisation flow.
NZ Read and Write API Security Profile
The NZ Read and Write API Security Profile extends from [FAPI Read+Write profile] FAPI-RW.
This section identifies variations from FAPI-RW and the numbered section references where there is a variation in FAPI-RW.
5.2 Read and Write API Security Provisions
5.2.1 Introduction
The Security Profile does not distinguish between the security requirements from a technical level between "read" and "write" resources. The security requirements for accessing Customer resources held at API Providers require more protection level than a basic OAuth 2.0 (RFC6749) supports.
As a profile of the OAuth 2.0 Authorization Framework, this document mandates the following to the specified APIs.
5.2.2 Authorization Server
The Authorization Server
shall only support confidential clients;
shall secure its token endpoint using mutually authenticated TLS;
shall only support the
response_type
valuescode
andcode id_token
;shall require the ConsentId to be passed in the authorisation request as an essential claim;
shall issue an ID Token in the token response as in Section 3.1.3.3 of OIDC with its "sub" value corresponding to a Pairwise Pseudonymous Identifier (PPID) for the Customer - that uniquely identifies the Customer to the Third Party. This PPID must not be reused for another Third Party.
may support refresh tokens;
shall require the request object to contain an
nbf
claim that is no longer than 60 minutes in the past;shall require the request object to contain an
exp
claim that has a lifetime of no longer than 60 minutes after thenbf
claimshall provide a discovery endpoint that does not require a client certificate to authenticate using a TLS certificate that should be trusted by the user agent; and
shall only support
private_key_jwt
for client authentication
5.2.4 Confidential Client
A Confidential Client
may use separate and distinct Redirect URI for each Authorization Server that it talks to; and
shall accept and verify signed ID Tokens (JWS);
6. Accessing Protected Resources
6.1 Introduction
The FAPI endpoints are OAuth 2.0 protected resource endpoints that return various financial information for the resource owner associated with the submitted access token.
6.2 Access Provisions
6.2.1 Protected resources provisions
The resource server with the FAPI endpoints
shall mandate mutually authenticated TLS; and
shall verify that the client identifier bound to the underlying mutually authenticated TLS transport session matches the client that the access token was issued to.
6.2.2 Client Provisions
The confidential client supporting this document
shall use mutually authenticated TLS;
shall supply the last time the customer logged into the client as defined by FAPI clause 6.2.2.3;
shall supply the customer's IP address if this data is available as defined by FAPI clause 6.2.2.4;
shall supply the merchant's IP address if this data is available in the x-merchant-ip-address header, e.g., x-fapi-merchant-ip-address: 198.51.100.119; and
shall supply the customer's user agent if this data is available in the x-customer-user-agent header.
7. Request Object Endpoint
7.1 Introduction
OPs:
shall only support
request_uri
when used with PAR, and not OIDC Request Object by Reference;shall only support Request Objects passed by value as in clause 6.3 of OIDC and as per PAR.
8. Security Considerations
The Message containment failure considerations in FAPI section 7.4 shall be followed.
8.5 TLS Considerations
The TLS considerations in FAPI section 7.1 shall be followed; and
The TLS considerations in FAPI-RW section 8.5 shall be followed.
8.6 JWS Algorithm Considerations
The JWS algorithm considerations in FAPI-RW section 8.6 shall be followed.
NZ Client Initiated Backchannel Authentication Profile
The NZ Client Initiated Backchannel Authentication Profile extends from [FAPI: Client Initiated Backchannel Authentication Profile] FAPI-CB.
This section identifies variations from FAPI-CB and the numbered section references where there is a variation in FAPI-CB.
The Client Initiated Backchannel Authentication Flow [CIBA] specifies an alternate method of users granting access to their resources whereby the flow is started from a consumption device, but authorized on an authentication device.
5.2 Read and Write API Security Provisions
5.2.2 Authorization Server
The Authorization Server
shall require a previously staged ConsentId to be passed in the authentication request;
shall not require clients to provide a request_context claim - as these fraud and threat parameters will be passed in the consent object;
shall only support login_hint_token and id_token_hint; and
shall not support the user_code parameter in the authentication request.
6. Accessing Protected Resources
6.1 Introduction
The FAPI endpoints are OAuth 2.0 protected resource endpoints that return various financial information for the resource owner associated with the submitted access token.
6.2 Access Provisions
6.2.1 Protected resources provisions
The resource server with the FAPI endpoints
shall mandate mutually authenticated TLS; and
shall verify that the client identifier bound to the underlying mutually authenticated TLS transport session matches the client that the access token was issued to.
6.2.2 Client Provisions
The confidential client supporting this document
shall use mutually authenticated TLS;
shall supply the last time the customer logged into the client as defined by FAPI clause 6.2.2.3;
shall supply the customer's IP address if this data is available as defined by FAPI clause 6.2.2.4;
shall supply the merchant's IP address if this data is available in the x-merchant-ip-address header, e.g., x-fapi-merchant-ip-address: 198.51.100.119; and
shall supply the customer's user agent if this data is available in the x-customer-user-agent header.
7. Security Considerations
7.9 TLS Considerations
The TLS considerations in FAPI-CB section 7.9 shall be followed.
7.10 Algorithm Considerations
The JWS algorithm considerations in FAPI-CB section 7.10 shall be followed.
Non-Normative Examples
Hybrid Flow
This section describes parameters that should be used with a hybrid grant flow request so that a ConsentId can be passed from the Third Party to an API Provider for minimum conformance for the NZ Read and Write API Security Profile (extending FAPI-RW). The hybrid flow is used as an optional redirect authorisation flow for the NZ Banking Data and other specified APIs.
Prior to this step,
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.
The API Provider would have responded with a ConsentId (this is the unique identifier for the consent resource).
Authorization Request
This section describes the bare minimum set of Authorization Request parameters that an API Provider must support. The definitive reference is specified in OIDC Section 3.3.2.1 (Authentication Request) and OIDC Section 3.1.2.1 (Authentication Request)
All API Providers must support the issuance of OIDC ID Tokens, a Third Party must request that an ID Token is issued.
This is a non-normative example of the Authorization Request:
GET /authorize?
response_type=code%20id_token
&client_id=Z5O3upPC88QrAjx00dis
&state=zSYkfyTKWQuZOBikzsmc&
&scope=openid%20payments
&nonce=w8q2mp1-z0o5w3mVHf-Mlt
&redirect_uri=https://thirdparty.co.nz/redirect
&request=eyJhbGciOiJQUzI1NiIsImtpZCI6IlZzOFFEMzlKaFJPcHZPTzhkSlFILW43TU5xTzZlOEFK
WEh2MTA0ZGtuNU0iLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJodHRwczovL2FzLmFwaS5wcm92aWRlci5jb
y5ueiIsImNsYWltcyI6eyJpZF90b2tlbiI6eyJDb25zZW50SWQiOnsiZXNzZW50aWFsIjp0cnVlLCJ2Y
Wx1ZSI6InVybi1hbHBoYWJhbmstaW50ZW50LTU4OTIzIn19fSwiY2xpZW50X2lkIjoiWjVPM3VwUEM4O
FFyQWp4MDBkaXMiLCJleHAiOjE2NzE3NTg2NDIsImlhdCI6MTY3MTc1ODA0MiwiaXNzIjoiWjVPM3VwU
EM4OFFyQWp4MDBkaXMiLCJqdGkiOiJlZTBlYTE4Yy1lMGEyLTQwODYtYTQ0Yy0xOTJjMGIzNzRmN2QiL
CJuYmYiOjE2NzE3NTgwMzIsIm5vbmNlIjoidzhxMm1wMS16MG81dzNtVkhmLU1sdCIsInJlZGlyZWN0X
3VyaSI6Imh0dHBzOi8vdGhpcmRwYXJ0eS5jby5uei9yZWRpcmVjdCIsInJlc3BvbnNlX3R5cGUiOiJjb
2RlIGlkX3Rva2VuIiwic2NvcGUiOiJvcGVuaWQgcGF5bWVudHMiLCJzdGF0ZSI6InpTWWtmeVRLV1F1W
k9CaWt6c21jIn0.A7iPTBmVa2Ngf2ZWMSDVUo_g0eZdE1jGv_LYksUjLANBGjbCMCptMSIj4XuW-26o1
lwtfsFIpOZ2H4gi10jVwmS9igWRKvauR2cjFooTxj4sidlH_JbSMQOZ-q2jQd7hwbiCnSGakFe5uqTiK
Q8ZAzAM485YvQcGPQXxGW3OSEgIE34QeE0AOfm7t_k16jAsF0Xzr7CscYeL3jZ0QKhuFYweM1xf3v7gC
8mQZJ1MfGUrSbU4Hwq0VDNqjnF-jX1KUa_LzZ39psHUEB8xm612ikNpqVz9gFBEQ6NhH9LU_wdLAIB0_
OMCutZDkosoCTBN2IDtBuNDua65BEMwQk-4apIg2slQeEriEELbLQNM_c02gS7gh8NwWICWgyfszw72d
UigoIGJCDN2rDiY21wDRUodU_N6X1w1ilNKDYKDt_PyE3a1MlaI732iQpqw1rqmc8nZM1MCBYmtKy2ZJ
PbqqYdzM4CD1Tne6saavffN5mu_bopmvqoSQmK-jm8Vc1wZuf8-v4TnP6yDu_w8v_7p_DI2viv8pnZ7n
nhUeDRVW1HfQCrg4ldxE06xBTwUMIYsEpg_0IUf7BR3BtJSH1cMsZ9Pq0tWIDCUylqapMR7bCAG8von8
OeqBibTmRI6H9ihPRizY5k06GJDIobSC9knqUSsoGRmfQRXWC-6kOAGuyg
Parameters
Parameter | NZ Security Profile | Notes |
---|---|---|
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 " The values for these parameters must match those in the Request Object, if present. |
client_id | Required | Third Parties must provide this value and set it to the Client Id issued to them by the API Provider to which the authorization code grant request is being made. |
redirect_uri | Required | Third Parties must provide the URI to which they want the resource owner's user agent to be redirected to after authorization. This must be a valid, absolute URL that was registered during Client Registration with the API Provider. |
state | Required | Third Parties must provide a state parameter. The parameter may be of any format and is opaque to the API Provider. The API Provider must play back the value in the redirect to the Third Party. The API Provider must include the s_hash in the ID Token. |
nonce | Required | Third Parties must provide a nonce parameter. Used to help mitigate against replay attacks. The API Provider must replay the supplied nonce parameter in any ID Token response. |
request | Required | The Third Party must provide a value for this parameter. The Request Object parameter must contain a JWS that is signed by the Third Party. The JWS payload must consist of a JSON object containing a Request Object as per OIDC Section 6.1. |
Request Object
This section describes the Request Object which is used in the request Authorization Request parameter. The definitive reference is specified in OIDC Section 6.1 (Request Object). All standards and guidance MUST be followed as per the OIDC specification. Note that FAPI 1.0 Baseline and FAPI 1.0 Advanced place additional constraints on the Request Object.
As per OIDC - when the Request Object is used, the OpenID Connect Request Object values (in the JWT) supersede those which are passed using the OAuth 2.0 request query parameter syntax.
The Request Object:
must contain a "claims" request parameter with the ConsentId in the "id_token" object as an essential claim
may contain additional "claims" to be requested if the API Provider's Authorization Server support them - these claims must be listed on the OIDC Well Known configuration endpoint.
In OIDC - the "claims" request parameter in the Request Object is used to request that specific Claims be returned in either the ID Token or at the userinfo endpoint. Hence the top level members of the "claims" request parameter are:
id_token
userinfo
The userinfo and id_token members of the claims request parameter are JSON objects with the names of the individual Claims being requested as the member names. Within an individual Claims field, the "essential" field is required to indicate whether the Claim being requested is an Essential Claim. If the value is true, this indicates that the claim is an Essential Claim.
For instance, the claim request:
"claims": {
"id_token": {
"ConsentId": {
"essential": true,
"value": "urn-alphabank-intent-58923"
}
}
}
can be used to specify that it is essential to return the ConsentId as a claim in the ID Token.
This is a non-normative example of the Request Object JWS - without Base64 encoding:
Claims
Where appropriate follow the JWT Best Current Practices Guides [BCP-225] https://www.rfc-editor.org/rfc/rfc8725
Field | NZ Security Profile | Notes |
---|---|---|
iss | Required | The iss value should be the Client Id of the Third Party, unless it was signed by a different party than the Third Party. |
aud | Required | The aud value should be or include the API Provider's Issuer Identifier URL. |
scope | Required | Third Parties must specify the scopes that are being requested. The scope parameter must contain openid The scopes must be a sub-set of the scopes that were registered during Client Registration with the API Provider. |
response_type | Required | Third Parties must provide this field and set its value to 'code id_token'. The values must match those in the request parameter. |
client_id | Required | Third Parties must provide this value and set it to the Client Id issued to them by the API Provider to which the authorization code grant request is being made. |
redirect_uri | Required | Third Parties must provide the URI to which they want the resource owner's user agent to be redirected to after authorization. This must be a valid, absolute URL that was registered during Client Registration with the API Provider. |
state | Required | Third Parties must provide a state parameter. The parameter may be of any format and is opaque to the API Provider. The API Provider must play back the value in the redirect to the Third Party. The API Provider must include the s_hash in the ID Token. |
nonce | Required | Third Parties must provide a nonce parameter. Used to help mitigate against replay attacks. The API Provider must replay the supplied nonce parameter in any ID Token response. |
max_age | Optional | Third Parties may provide a maximum authentication age parameter. This specifies the allowable elapsed time in seconds since the last time the End-User was actively authenticated by the API Provider. If the elapsed time is greater than this value, the API Provider must attempt to actively re-authenticate the Customer. (The max_age request parameter corresponds to the OpenID 2.0 PAPE [OpenID.PAPE] max_auth_age request parameter.) If the parameter is provided, the API Provider must include an auth_time Claim value in the ID Token. |
claims.id_token.ConsentId | Required | Third Parties must provide a ConsentId. The ConsentId must be the identifier for a consent resource returned by the API Provider to Third Party that is initiating the authorisation request. |
exp | Required | Third Parties must provide an The |
nbf | Required | Third Parties must provide an The |
iat | Optional | Third Parties may provide a time at which the Request Object was issued. |
jti | Optional | Third Parties may provide a unique identifier for the token as per RFC7519. |
Authorisation Response
The following is a non-normative HTTP authorization response, showing code
, state
and id_token
parameters, as required by OIDC Core 1.0, section 3.3.2.5:
ID Token
This is a non-normative example of an ID Token returned - with the sub being populated with a PPID uniquely identifying the Customer to the Third Party.
Decoded ID Token JWT
Claims
Where appropriate please follow the JWT Best Current Practices Guides [BCP-225] https://www.rfc-editor.org/rfc/rfc8725
Field | NZ Security Profile | Notes |
---|---|---|
aud | Required | Audience that the ID Token is intended for. OpenID Connect protocol mandates this must include the ClientID of the Third Party's OAuth Client. |
iss | Required A JSON string that represents the issuer identifier of the authorization server as defined in RFC7519. When a pure OAuth 2.0 is used, the value is the redirection URI. When OpenID Connect is used, the value is the issuer value of the authorization server. | Issuer of the token. Token issuer will be specific to the business. |
sub | Required
| Token subject identifier. A Pairwise Pseudonymous Identifier (PPID) for the Customer - that uniquely identifies the Customer to the Third Party. This PPID must not be reused for another Third Party. The sub must be the same for an ID Token created by the Authorisation and Token endpoints during the Hybrid flow. |
ConsentId | Required | The ConsentId of the originating request. |
exp | Required The validity length will be at the discretion of the API Providers as long as it does not impact the functionality of the APIs. E.g., an expiry time of 1 second is insufficient for all resource requests | Token expiration date/time. Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519. |
iat | Required | Token issuance date/time. Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519. |
auth_time | Case-Specific | The date/time the Customer was authorised. This field must be provided when max_age is in the Authorization Request is made or max_age is included as an essential claim. In order to be compliant with the protocol we therefore need to support it. Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519. |
nonce | Required | 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, 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 |
jti | Optional | JWT Token Identifier An API Provider may include a unique identifier in the ID token as defined in RFC7519 |
Authorization Code Flow
This section describes parameters that should be used with a authorization code flow request so that a ConsentId can be passed from the Third Party to an API Provider for minimum conformance for the NZ Read and Write API Security Profile (extending FAPI-RW). The authorization code flow is used as the redirect authorisation flow for the NZ Banking Data and other specified APIs.
Authorization Code Flow is mandatory in this version of the NZ Security Profile.
Prior to this step;
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.
The API Provider would have responded with a ConsentId (this is the unique identifier for the consent resource).
Pushed Authorization Requests (PAR) with JWT-Secured Authorization Requests & Proof-Key Code Exchange
Pushed Authorisation Requests (PAR, RFC9126) allow an OAuth 2.0 authorization request to be lodged directly with the authorization server, without the need to redirect the client. This results in better security (the OIDC authentication request object is not exposed to user-agent) and customer experience, since the client is only redirect if the authentication request is considered appropriate to proceed.
FAPI 1.0 requires PAR requests to use JAR (RFC9101) method to submit a request object JWT, which must include PKCE claims.
FAPI 1.0 supports PAR requests with hybrid flow ("response_type": "code id_token"
), however this specification requires PAR only for authorization code flow ("response_type": "code"
).
Proof Key Code Exchange
As per FAPI 1.0, PKCE (RFC 7636) is required for PAR requests and subsequent token requests. Only S256
for code_challenge_method
is supported.
Note: Section 7.1 of PKCE specifies the code_verifier
should be a minimum of 256 bits, or 32 ASCII characters encoded using URL-safe base64 (total 43 characters).
PKCE code_challenge
and code_challenge_method
are required in the PAR request object, while the token request includes code_verifier
to facilitate verification before issuing tokens.
Authentication
The PAR endpoint requires private_key_jwt
for client authentication. The endpoint must use MTLS for secure transport.
PAR Request using JAR
The authentication request object is required to be specified in the request
parameter, and request_uri
is not supported in PAR request. Only signed JWT tokens (JWS) are supported.
The following is a non-normative PAR request:
Decoded PAR request object JWT body:
PAR Response
The following shows a non-normative example success response. PAR requires HTTP 201 Created
for success. Both request_uri
and expires_in
are required.
The expires_in
value is the time-to-live in seconds for the request_uri
expected to be short, normally between 5 and 600 seconds and it is the API provider responsibility to set and publish values for this.
The request_uri
format is at the discretion of the API provider, but must contain at least some part that is randomly generated in a cryptographically strong manner, consistent with section 10.10 of OAuth 2.0. The authorization server may choose to use the PAR-specified format of urn:ietf:params:oauth:request_uri:<reference-value>
. where <reference-value>
is the randomly generated part.
Error Response
PAR error responses use the same format as OAuth 2.0 and related extensions.
The following is an non-normative example of and error response:
PAR also defines the following additional error responses in section 2.3 of PAR:
HTTP Response Code | Description |
---|---|
405 | If the request did not use the "POST" method, the authorization server responds with an HTTP 405 (Method Not Allowed) status code |
413 | If the request size was beyond the upper bound that the authorization server allows, the authorization server responds with an HTTP 413 (Payload Too Large) status code. |
429 | If the number of requests from a client during a particular time period exceeds the number the authorization server allows, the authorization server responds with an HTTP 429 (Too Many Requests) status code. |
Authorize request with PAR
The following shows a non-normative example of an authorization request, using a request_uri
previously issued through a PAR request:
Note that PAR section 4 requires authorization servers should treat request_uri
as a single-use value, but may allow for duplicates to allow for user-agent reloading of the URI. An expired request_uri
must be rejected as invalid.
OIDC metadata
API provider authorization servers must publish the appropriate metadata for PAR, as required by RFC9126 section 9.1.
JWT-Secured Authorization Response Mode (JARM)
FAPI 1.0
FAPI 1.0 Final specifies in section 5.2.2 the use of JARM ("response_mode":"jwt"
) in conjunction with "response_type": "code"
. The use of JARM removes the need for ID token as detached signature in the authorization response.
Signing and encryption
JARM supports both signing and encryption, however this specification requires that only signing is used (similar to ID Token as detached signature). The approved JARM signing algorithms are as per FAPI 1.0.
Example JARM response
The following is a non-normative JARM HTTP success response JWT using the previous PAR request object and subsequent authorization request:
Response Mode "jwt"
FAPI 1.0 requires "response_mode": "jwt"
is used with "response_type": "code"
. JARM specifies response mode "jwt"
in this case to be shorthand for "query.jwt"
, so the response to the authorisation request is in the redirect URI query parameter.
The following shows a non-normative example of the HTTP redirect using the JARM JWT above (line breaks for display only):
The JARM JWT from the response
parameter:
Decoded JARM response JWT body:
JARM response claims
The JARM response is to be processed according to JARM section 4.4.
For the NZ Security Profile, the following enhanced definitions of the JARM response claims from [section 4.1.1 of JARM}(https://openid.net/specs/openid-financial-api-jarm.html#response-type-code ) are used:
Claim | NZ Security Profile | Notes |
---|---|---|
aud | Required | Must be set to the |
code | Required | The authorization code issued by the API Provider authorization server. |
exp | Required | The expiration time of the JARM JWT |
iss | Required | The issuer URL of the API Provider authorization server that created the response |
state | Required | The state value as sent by the client in the authorization request |
Error response
JARM error response is a JWT containing the error response claims defined in Oauth 2.0 RFC6749 section 4.1.2.1:
For the NZ Security Profile, the following enhanced definitions of the JARM response claims from section 4.1.1 of JARM are used:
Claim | NZ Security Profile | Notes |
---|---|---|
error | Required | A OAuth 2.0 error response code |
error_description | Optional | A human readable description of the error |
error_uri | Optional | A URI identifying a human-readable web page with information about the error |
state | Required | The state value as sent by the client in the authorization request |
Token request
The following non-normative example shows the token request:
Note that the code_verifier
is included so the authorization server can verify the code_challenge
PKCE claim supplied in the PAR request.
Decoded client assertion JWT body:
Token response
The client must validate the ID token according to OIDC Core 3.1.3.7
Decoded ID token JWT body:
OIDC metadata
API provider authorization servers must publish the appropriate metadata for supported JARM signing algorithms, as required by JARM Authorisation Server Metadata.
Decoupled Request
This section describes parameters that should be used with a decoupled flow so that a ConsentId can be passed from the Third Party to an API Provider for minimum conformance for the NZ Client Initiated Backchannel Authentication Profile (extending FAPI-CB).
Prior to this step,
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.
The API Provider would have responded with a ConsentId (this is the unique identifier for the consent resource).
Authorization Request
This section describes the bare minimum set of Authorization Request parameters that an API Provider must support. The definitive reference is specified in CIBA Section 7.1 (Authentication Request).
As per FAPI-CB 5.2.2.6 the Authorization Requests shall be signed as per CIBA Section 7.1.1
This is a non-normative example of the Authorization Request:
This is the example Request Object - without Base64 encoding:
Claims
Field | NZ Security Profile | Notes |
---|---|---|
iss | Required | The iss value should be the Client Id of the Third Party, unless it was signed by a different party than the Third Party. |
aud | Required | The aud value should be or include the API Provider's Issuer Identifier URL. |
nbf | Required | The time before which the JWT must not be accepted for processing. The processing of the "nbf" claim requires that the current date/time MUST be after or equal to the not-before date/time listed in the nbf claim. Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519. |
exp | Required | Token expiration date/time. Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519. |
iat | Required | Token issuance date/time. Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519. |
jti | Required | The jti (JWT ID) claim provides a unique identifier for the JWT. |
scope | Required | Third Parties must specify the scopes that are being requested. The scope parameter must contain openid The scopes must be a sub-set of the scopes that were registered during Client Registration with the API Provider. |
ConsentId | Required | Third Parties must provide a ConsentId for which this authorisation is requested. |
client_notification_token | Optional | Third Parties must provide this field if registered to use Ping mode. It is a bearer token provided by the Third Party that will be used by the API Provider to authenticate the callback request to the Third Party. |
login_hint_token | Optional | A token containing information identifying the Customer for whom authentication is being requested. The particular details for the login_hint_token are documented in the NZ Security Profile standard. Third Parties must provide either a login_hint_token or an id_token_hint |
id_token_hint | Optional | An ID Token previously issued to the Third Party by the API Provider being passed back as a hint to identify the Customer for whom authentication is being requested. Third Parties must provide either a login_hint_token or an id_token_hint |
requested_expiry | Optional | A positive integer allowing the client to request the expires_in value for the auth_req_id the server will return. The API Provider may use this value to influence the lifetime of the authentication request and is encouraged to do so where it will improve the user experience, for example by terminating the authentication when as it knows the client is no longer interested in the result. |
Login Hint Token
This is a non-normative example of a Login Hint Token - which is used to identify the Customer.
Claims
The following claims are supported in the login_hint_token
. The RFC7519 registered claims may also be included, and are to be treated in according with that specification.
Field | NZ Security Profile | Notes |
---|---|---|
subject | Required | JSON object containing identification hint information, in the form of:
|
subject_type | Required | Third Parties must specify the type of identification provided in the login_hint_token. This is limited to:
|
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. |
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:
This is the (non-normative) ID Token Hint, after base64 decoding:
Authorization Request Response
The following is a non-normative example of an authentication response:
Claims
Field | NZ Security Profile | Notes |
---|---|---|
auth_req_id | Required | This is a unique identifier to identify the authentication request made by the Client. It MUST contain sufficient entropy (a minimum of 128 bits while 160 bits is recommended) to make brute force guessing or forgery of a valid auth_req_id computationally infeasible - the means of achieving this are implementation specific, with possible approaches including secure pseudorandom number generation or cryptographically secured self-contained tokens. |
expires_in | Required | A JSON number with a positive integer value indicating the expiration time of the "auth_req_id" in seconds since the authentication request was received. A Client calling the token endpoint with an expired auth_req_id will receive an error. |
interval | Optional | A JSON number with a positive integer value indicating the minimum amount of time in seconds that the Client MUST wait between polling requests to the token endpoint. This parameter will only be present if the Client is registered to use the Poll or Ping modes. |
Token Request
The following is a non-normative example of a token request using the auth_req_id in the authorisation request response.
Token Request Response
The following is a non-normative example of a successful token response.
Ping Callback
The following is a non-normative example of a Ping callback request. The API Provider calls POST at the Third Party's registered callback endpoint with the client_notification_token in the original Authorisation Request, and the auth_req_id in the body of the request.
ID Token
This is a non-normative example of an ID Token returned - with the sub being populated with a PPID uniquely identifying the Customer to the Third Party.
Claims
Where appropriate please follow the JWT Best Current Practices Guides [BCP-225] https://www.rfc-editor.org/rfc/rfc8725
Field | NZ Security Profile | Notes |
---|---|---|
aud | Required | Audience that the ID Token is intended for. OpenID Connect protocol mandates this must include the ClientID of the Third Party's OAuth Client. |
iss | Required A JSON string that represents the issuer identifier of the authorization server as defined in RFC7519. When a pure OAuth 2.0 is used, the value is the redirection URI. When OpenID Connect is used, the value is the issuer value of the authorization server. | Issuer of the token. Token issuer will be specific to the business. |
sub | Required
| Token subject identifier. A Pairwise Pseudonymous Identifier (PPID) for the Customer - that uniquely identifies the Customer to the Third Party. This PPID must not be reused for another Third Party. The sub must be the same for an ID Token created by the Authorisation and Token endpoints during the Hybrid flow and Authorisation Code Flow. |
ConsentId | Required | The ConsentId of the originating request. |
exp | Required The validity length will be at the discretion of the Banks provided that it does not impact the functionality of the APIs. For example, an expiry time of 1 second is insufficient for all Resource Requests. | Token expiration date/time. Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519. |
iat | Required | Token issuance date/time. Expressed as an epoch i.e. number of seconds from 1970-01-01T0:0:0Z as measured in UTC. RFC7519. |
jti | Optional | Unique identifier for the ID token |
Implementation Guide
This provides an implementation perspective of the NZ Security Profile aligned to the accepted NZ Banking Data and other specified APIs for:
The Hybrid Flow (illustrated with the Payment Initiation APIs)
The Authorization Code Flow
The Decoupled Flow (illustrated with the Account Information APIs)
Both the Payment Initiation APIs and the Account Information APIs rely on the same underlying consent flow - so either authorisation flow may be used for both Payment Initiation and Account Information.
JSON schemas for messages associated with the security profile can be found here:
https://github.com/PaymentsNZ/API-Security-Profile
Hybrid Flow
The implementation is based on the following known configurations:
Client Types
As per the OAuth 2.0 specification, the Confidential Client Type is illustrated
Grant Types
Client Credentials Grant Type
This is with scope payments
The Client Credentials Grant Type is used when the Third Party requires an Access Token (on behalf of itself) in order to access a consent resource
Only valid API scopes will be accepted when generating an Access Token (i.e.,
payments
)Access tokens generated by a Client Credentials grant may not return any refresh tokens (as per the OAuth 2.0 specification)
Hybrid Flow
This is with response_type "code id_token"
The Payment Initiation APIs illustrate the use of request_type=code id_token for the OIDC Hybrid Flow implementation
The API Provider may optionally choose to return Refresh Tokens for the Hybrid Flow when issuing an Access Token
Access Tokens
For the Payments and Accounts APIs, the Access Token must be obtained within a Secure, Server Side Context between the Third Party and the API Provider
Access Tokens must be validated by the Third Party as outlined within OIDC
Refresh Tokens
API Providers may optionally return a Refresh Token when an Authorization Request is successfully processed at the Token endpoint. The Hybrid flow supports the provisioning of Refresh Tokens.
Refresh Tokens must be validated as outlined in OIDC
ID Tokens
ID Tokens must be validated by the Third Party as outlined within OIDC
Third Parties must use the ConsentId claim to populate and retrieve the ConsentId for any required validation
The full set of claims that can be represented within an ID Token are documented in the Request Object and ID Token sections of the Security Profile
Authorization Codes
Authorization Codes must be validated by the Third Party as outlined within OIDC
Unspecified Behaviour
The implementation guide does not illustrate the following configurations in this section.
Client Types
Public clients - as only confidential clients are allowed in the NZ Security Profile
Grant Types
OIDC Hybrid Flow (response_type=code id_token token)
Forces an Access Token to be returned from the API Provider Authorization endpoint (instead of a token endpoint). This is not illustrated in the Payments and Accounts API Specifications
Client Credentials Grant Type (scope=openid email profile)
Requesting OIDC specific scopes or any unspecified scopes when using the Client Credentials grant
Validity Lengths
These are to be managed in the competitive space - so different validity lengths are not illustrated. Each API Provider's Authorization / Resource Server will be configured independently to comply with internal API Provider Security Policies and Guidelines. The Accounts and Payments API Specifications do not mandate validity lengths.
Authorization Code
OAuth 2.0 Specification suggests an Authorization Code should be short lived to a maximum of 10 minutes. Any codes exceeding this limit to be rejected
ID Token
ID Token claims (exp and iat) determine its validity
Returned with the 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
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.
The Third Party initiates an Authorization request using valid Client Credentials Grant type and scope(s)
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
The Third Party uses the Access Token to create a new Payment resource against the API Provider Resource Server
The API Provider Resource server responds with the ConsentId for the resource it has created
The Client Credentials Grant may optionally be used by the Third Party in Step 5 to retrieve the status of a consent resource
OIDC Hybrid Flow
The Hybrid flow is an optional redirect flow for the NZ Security Profile. The Hybrid flow prevents IDP mixup attacks as documented by Nat Sakimura - Cut and Paste OAuth 2.0 Attack
This is initiated at the end of Step 2 by the Third Party after the ConsentId is generated by the API Provider and returned to the Third Party
This is used in a redirect across the Customer and API Provider in Step 3 in order for the Customer to authorize consent with the API Provider
This is used across the Third Party and API Provider in Step 4 by exchanging the Authorization Code for an Access Token in order to create the domestic-payment resource
Non-Normative HTTP Request and Response Examples
Step 1 - Agree Payment Consent
There are no Requests and Responses against the Payments API in this Step for the Customer, Third Party and API Provider.
Step 2 - Setup Payment-Order Consent
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
Non-Base64 JWT client_assertion
Response : Client Credentials
Third Party uses the Access Token (with
payments
scope) from the API Provider to invoke the payment-order consent API.
Request : domestic-payment-consents
Response : domestic-payment-consents
Step 3 - Authorize Consent
Third Party receives a ConsentId from the API Provider. The Third Party then creates an Authorization request (using a signed JWT Request containing the ConsentId as a claim) for the Customer to consent to the Payment directly with their API Provider. The request is an OIDC Hybrid flow (requesting for code and id_token)
Request : OIDC Hybrid Flow
Sourced from the NZ Security Profile Request Object section
Base64 and URL Encoded Example
Non-Base64 encoded example of the request parameter object
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
Non-Base64 encoded ID token
Note: The default response mode for Hybrid Flow (shown above) is fragment encoding. Third Parties may complete authorisation response processing through one of the following methods:
User Agent parses the response parameters and sends to the Client (Third Party) for processing. See OIDC core 1.0, section 3.3.2.7, and OIDC core 1.0, section 15.5.3
Client may specify
response_mode
asquery
, causing the authorisation response parameters to be encoded in query parameters, making them directly visible to the client (Third Party). If thequery
response mode is supported by the API Provider it will be indicated in authorisation server metadataresponse_modes_supported
The Customer is then redirected to the Third Party. The Third Party will now possess the Authorization Code and ID Token from the API Provider. Note at this point, there is no Access Token. The Third Party will now introspect the ID Token and use it as a detached signature to check:
The hash of the Authorization Code to prove it hasn't been tampered with during redirect (comparing the hash value against the c_hash attribute in ID Token)
The hash of the State to prove it hasn't been tampered with during redirect (comparing the state hash value against the s_hash attribute in the ID Token)
Example: ID Token
Sourced from the NZ Security Profile Request Object section
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
Non-Base64 JWT client_assertion
Response : Access Token
Step 4 - Create Payment-Order
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.
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
Response : domestic-payments
Step 5 - Get Domestic-Payment Status
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}
Response: domestic-payments
A Third Party can also optionally query for the status of a domestic-payment-consent resource by invoking /domestic-payment-consents/{ConsentId}. This can use an existing access token with
payments
scope or the Third Party can obtain a fresh access token by replaying the client credentials grant request as per Step 2.
Authorization Code Flow
The implementation is based on the following known configurations:
Client types
As per the OAuth 2.0 specification, the Confidential Client Type is illustrated
Grant types
Client Credentials grant type
This is with scope payments
The Client Credentials Grant Type is used when the Third Party requires an Access Token (on behalf of itself) in order to access a consent resource
Only valid API scopes will be accepted when generating an Access Token (i.e.,
payments
)Access tokens generated by a Client Credentials grant may not return any refresh tokens (as per the OAuth 2.0 specification)
Authorization Code Flow
This is with response_type
"code"
The Payment Initiation APIs illustrate the use of
"response_type": "code"
for the OIDC Authorization Code Flow implementationThe API Provider may optionally choose to return Refresh Tokens for the Authorization Code Flow when issuing an Access Token
Access Tokens
For the Payments and Accounts APIs, the Access Token must be obtained within a Secure, Server Side Context between the Third Party and the API Provider
Access Tokens must be validated by the Third Party as outlined within OIDC
Refresh Tokens
API Providers may optionally return a Refresh Token when an Authorization Request is successfully processed at the Token endpoint. The Hybrid flow supports the provisioning of Refresh Tokens.
Refresh Tokens must be validated as outlined in OIDC
ID Tokens
ID Tokens must be validated by the Third Party as outlined within OIDC
Third Parties must use the
ConsentId
claim to populate and retrieve the ConsentId for any required validationThe full set of claims that can be represented within an ID Token are documented in the Request Object and ID Token sections of the Security Profile
Authorization Codes
Authorization Codes are returned within a JARM response JWT
Only signed JARM responses are supported (no encryption)
Authorization Codes must be validated by the Third Party as outlined within JARM
Pushed Authorization Requests
As per FAPI 1.0:
Pushed Authorization Requests (PAR) may be used to send Request Object from Third Party to API Provider.
JWT-Secured Authorization Request (JAR) is used to deliver Request Object.
This Security Profile requires PAR is used with Authorization Code Flow.
Proof Key for Code Exchange
FAPI 1.0 requires PKCE is used with PAR.
Only
S256
is supported forcode_challenge_method
Section 7.1 of PKCE specifies the
code_verifier
should be a minimum of 256 bits, or 32 ASCII characters encoded using URL-safe base64 (total 43 characters). The authorisation server may reject lower-entropycode_verifier
values.
FAPI JWT-Secured Authorization Response Mode (JARM)
FAPI 1.0 requires JARM ("response_mode":"jwt"
) when using Authorization Code Flow ("response_type": "code"
)
Unspecified Behaviour
The implementation guide does not illustrate the following configurations in this section.
Client Types
Public clients - as only confidential clients are allowed in the NZ Security Profile
Grant Types
OIDC Hybrid Flow (specified in Hybrid Flow section of Security Profile)
OIDC Implicit Flow (
response_type
= "id_token" or "id_token token")"id_token" does not allow for access token issuing
"id_token token" forces exposure of access token to user agent
Client Credentials Grant Type (
scope
= "openid email profile")Requesting OIDC specific scopes or any unspecified scopes when using the Client Credentials grant
Validity Lengths
These are to be managed in the competitive space - so different validity lengths are not illustrated. Each API Provider's Authorization / Resource Server will be configured independently to comply with internal API Provider Security Policies and Guidelines. The Accounts and Payments API Specifications do not mandate validity lengths.
Authorization Code
OAuth 2.0 Specification suggests an Authorization Code should be short lived to a maximum of 10 minutes. Any codes exceeding this limit to be rejected
ID Token
ID Token claims (
exp
andiat
) determine its validityReturned with the token response when the Authorization Code flow is used
Access Token
The
expires_in
attribute returned by the Authorization Server when an Access Token is generated determines its validityAccess Tokens are generally short lived, and where they expire, are then exchanged for another using a longer lived Refresh Token
Refer to Section 16.18 of OIDC - Lifetimes of Access Tokens and Refresh Tokens.
Refresh Token
Refresh Tokens are generally longer lived in comparison to Access Tokens
Refresh Token Introspection may be used to retrieve the Refresh Token expiry
Refer to Section 16.18 of OIDC - Lifetimes of Access Tokens and Refresh Tokens
Success Flows
The sequence diagram below highlights the OAuth 2.0 Client Credentials Grant and OIDC Authorization Code Flow that are used by the Payments API.
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.
The Third Party initiates an Authorization request using valid Client Credentials Grant type and scope(s)
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
The Third Party uses the Access Token to create a new Payment resource against the API Provider Resource Server
The API Provider Resource server responds with the ConsentId for the resource it has created
The Client Credentials Grant may optionally be used by the Third Party in Step 5 to retrieve the status of a consent resource
Authorization Code Flow
The Authorization Code flow is mandated as the redirect flow for the NZ Security Profile.
FAPI 1.0 Final advanced required JARM responses
This Security Profile requires Pushed Authorization Requests (PAR), using signed Authentication Request objects (JAR) with Proof-Key for Code Exchange (PKCE)
This is initiated at the end of Step 2 by the Third Party after the ConsentId is generated by the API Provider and returned to the Third Party
This is used in a redirect across the Customer and API Provider in Step 3 in order for the Customer to authorize consent with the API Provider
This is used across the Third Party and API Provider in Step 4 by exchanging the Authorization Code for an Access Token in order to create the domestic-payment resource
Non-Normative HTTP Request and Response Examples
Step 1 - Agree Payment Consent
There are no Requests and Responses against the Payments API in this Step for the Customer, Third Party and API Provider.
Step 2 - Setup Payment-Order Consent
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
Decoded JWT client_assertion
Response: Client Credentials
Third Party uses the Access Token (with
payments
scope) from the API Provider to invoke the payment-order consent API.
Request: domestic-payments-consents
Response: domestic-payments-consents
The Third Party as received a ConsentId to use in customer consent.
Step 3 - Pushed Authorization Request (PAR)
Third Party creates and submits Authorization Request JWT to directly to API Provider PAR endpoint.
PAR request includes PKCE claims and ConsentId for the consent the customer should authorise
The request is a PAR request, requiring a JARM response (
"response_mode": "jwt"
)Third Party receives a
request_uri
from the API Provider which is used as part of customer redirection
Request: OIDC Authorization Code Flow using PAR
Sourced from the NZ Security Profile
Decoded request object JWT:
Response: OIDC Authorization Code Flow using PAR
Step 4 - Authorise Consent with JARM response
Customer is redirected by Third Party to API Provider to grant consent.
Request: Redirect customer using request_uri
Once the customer has granted consent, they are redirected to the Third Party and a JARM response is provided. Because the JARM response is signed, there is no requirement for the ID Token as detached signature.
Response: JARM response in customer redirect
Decoded JARM response:
The Third Party must process the JARM response JWT according to section 4.4 of JARM
Additionally, the Third Party must validate the ConsentId
claim and refuse further processing if it does not match the expected value.
Step 5 - Retrieve Tokens
The Third Party will now possess the Authorization Code from the API Provider. The Third Party can now obtain tokens from the token endpoint using the authorization code and private_key_jwt
for authentication.
The Third Party will present its Authorization Code together with the private_key_jwt
. The Access Token is required by the Third Party in order to submit the Payment on behalf of the Customer. The payments
scope should already be associated with the Authorization Code generated in the previous step.
Request: Access Token request using Authorization Code and private_key_jwt
Decoded client assertion:
Response: Access Token
Decoded ID Token:
The Third Party may now introspect the ID Token and use it as a detached signature to check:
The hash of the Authorization Code to prove it hasn't been tampered with during redirect (comparing the hash value against the c_hash attribute in ID Token)
The hash of the State to prove it hasn't been tampered with during redirect (comparing the state hash value against the s_hash attribute in the ID Token)
Note: the s_hash
and c_hash
may be omitted since state
and auth_code
are protected from tampering in JARM JWT
Step 6 - Create Payment Order
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.
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
Response: domestic-payments
Step 7 Get Domestic-Payment Status
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}
Response: domestic-payments
Decoupled Flow
The implementation is based on the following known configurations:
Client Types
The Confidential Client Type is illustrated as per the FAPI-CB profile
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
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.
The Third Party initiates an Authorization request using valid Client Credentials Grant type and scope(s)
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
The Third Party uses the Access Token to create a new Account Access Consent resource against the API Provider Resource Server
The API Provider Resource server responds with the ConsentId representing the resource it has created
CIBA Flow
This is initiated at the end of Step 2 by the Third Party after the ConsentId is generated by the API Provider and returned to the Third Party
Non-Normative HTTP Request and Response Examples
Step 1 - Agree Account Access Consent
There are no Requests and Responses against the Account Information API in this Step for the Customer, Third Party and API Provider
Step 2 - Setup Account Access Consent
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
Non-Base64 JWT client_assertion
Response : Client Credentials
Third Party uses the Access Token (with
accounts
scope) from the API Provider to create an account-access-consent resource.
Request: Accounts API
Response: Accounts API
Step 3 - Authorize Consent
Third Party receives a ConsentId from the API Provider. The Third Party then creates an Authorization request (using a signed JWT Request containing the ConsentId as a claim) for the Customer to consent to the account-access-consent directly with their API Provider. The request is a CIBA flow. In this example, the Third Party has pre-registered for a Ping notification response, and included a client_notification_token in the signed Authorization Request.
Request : CIBA Authorization Request
Sourced from the NZ Security Profile Authorisation Request section
Base 64 Encoded Example
Non-Base64 encoded example of the request object
Non-Base64 encoded example of the login hint token
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.
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
Response : No Content
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
Non-Base64 encoded example of the client assertion:
Response : Access Token (with Optional Refresh Token)
ID Token - Non-Base 64 Encoded
Step 4 - Request Account Data
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
Response: Bulk accounts resource
Request : Specific Account Id
Response: Specific Account Id
Request: Refresh Token Request using private_key_jwt
Response: Refresh Token
A new Access Token and Refresh Token will be returned to the Third Party for them to query /accounts resources
Refresh token introspection
Overview
Refresh tokens are required for the utility of long-lived consents. The lifetimes of refresh tokens are determined by the API Provider, and retrieved through an RFC7662 OAuth 2.0 token introspection interaction. This requires the API Provider to return the token expiry time in the exp
claim in the introspection response. The API Provider may also include other optional standard and extension claims, but must not return any PII information.
Only introspection of refresh tokens is supported.
Steps
Pre-requisites:
TPP and customer agree on a long-lived consent
TPP and customer successfully follow Hybrid or Decoupled flow
TPP successfully retrieves tokens, including refresh token
Step 1 - introspect token
Establish MTLS from TPP to API Provider
TPP creates a client assertion JWT
Client makes an introspection request to API provider introspection endpoint
API provider validates the TPP client assertion JWT authentication credential
API provider verifies that the supplied token belongs to the TPP
API provider responds with an introspection response
Endpoints
The OAuth 2.0 Introspection endpoint and mandatory/conditional/optional status are given below.
Resource | Endpoints | Mandatory? |
---|---|---|
introspection | POST /introspect | Mandatory |
POST /introspect
The Introspection endpoint allows the TPP to ask an API Provider for information on a previously issued refresh token.
Sequence diagram
Data model
This section contains the schemas for the token introspection request and response.
Introspection request
The IntrospectionRequest object will be used for the call to:
POST /introspect
UML diagram
Data Dictionary
Name | Occurrence | XPath | EnhancedDefinition | Class | Codes | Pattern |
---|---|---|---|---|---|---|
client_assertion | 1..1 | client_assertion | A RFC7523 client authentication assertion as per OIDC Core section 9 | xs:string |
|
|
client_assertion_type | 1..1 | client_assertion_type | The type of client assertion used | xs:Max64Text |
|
|
client_id | 0..1 | client_id | The ID assigned to the Third Party software by the API Proivder. Must match the | xs:string |
|
|
token | 1..1 | token | The refresh token issued to the TPP | xs:string |
|
|
token_type_hint | 0..1 | token_type_hint | Version for the event notification. | Max32Text |
|
|
Introspection response
The IntrospectionResponse object will be used for a response to a call to:
POST /introspect
UML diagram
Data Dictionary
Name | Occurrence | XPath | EnhancedDefinition | Class | Codes | Pattern |
---|---|---|---|---|---|---|
active | 1..1 | active | Boolean indicator of whether or not the presented token is currently active | xs:boolean | true |
|
scope | 0..1 | scope | Scopes associated to the token | Max128Text |
|
|
client_id | 0..1 | client_id | ID assigned to the third party | Max128Text |
|
|
username | 0..1 | username | Human readable identifier for the resource owner | Max128Text |
|
|
token_type | 0..1 | token_type | Type of the token as defined in Section 5.1 of OAuth 2.0 | Max128Text |
|
|
exp | 1..1 | exp | The timestamp at which the token will expire, as per RFC7519 | xs:int |
|
|
iat | 0..1 | iat | The timestamp at which the token was issued, as per RFC7519 | xs:int |
|
|
nbf | 0..1 | nbf | The timestamp before which the token is not considered valid, as per RFC7519 | xs:int |
|
|
sub | 0..1 | sub | Subject of the token, as defined in JWT RFC7519. The ID assigned to the Third Party Software by the API Provider See RFC7523 | Max128Text |
|
|
aud | 0..1 | aud | Service-specific string identifier or list of string identifiers representing the intended audience for this token, as defined in JWT RFC7519 | xs:any |
|
|
iss | 0..1 | iss | String representing the issuer of this token, as defined in RFC7519 | Max128Text |
|
|
jti | 0..1 | jti | String identifier for the token, as defined in | Max128Text |
|
|
Endpoint Authentication
The token introspection endpoint will require private_key_jwt
authentication. The TPP must provide a signed JWT as part of the authentication request, otherwise introspection will be rejected.
Metadata
An API provider must include introspection metadata values in their OIDC Discovery metadata, as per RFC8414, section 2
For example:
Usage Examples
The following non-normative examples are used to illustrate the introspection flow.
POST Introspection request
POST Introspection response
Errors
If the private_key_jwt
authentication supplied by the Third Party in the introspection request is invalid, the authorisation server responds with a 401 Unauthorized
response, as required by RFC7662, section 2.3. The client may try again with a different credential.
As per RFC7662, introspection of a token that has expired or is otherwise invalid is not considered an error.
Edge Cases
This section provides further information on potential edge cases that may arise via the implementation of Accounts and Payments API Specifications.
Scenario | Workflow Step | Impact | Solution Options |
---|---|---|---|
Due to an interruption, the Customer does not complete the Authorization of a Consent resource with the API Provider when redirected by the Third Party (after creating a ConsentId) | Step 3: Authorize Consent | Consent Status remains as AwaitingAuthorisation | The Third Party may choose to implement a separate follow up process which reminds the Customer to complete their Authorization consent steps with the API Provider. This would imply re-using the ConsentId that has a status of AwaitingAuthorisation and re-issuing another Hybrid Flow request. Authorisation Code Flow request or CIBA Flow request to the API Provider. The implementation of how the follow up process is initiated is in the competitive space for the Third Parties to decide. |
JSON Security Suite
JWT Best Current Practices Guides to be followed where appropriate: [BCP-225] https://www.rfc-editor.org/rfc/rfc8725
Creating a JWS
Step 1: Select the Certificate and Private Key that will be used for Signing the JWS
As the JWS is used for non-repudiation, it must be signed using one of the JWS issuer's private keys.
The signing certificate must be valid at the time of creating the JWS.
Step 2: Form the JOSE Header
All participants should include "kid" and "jku" of the key that was used to sign the payloads.
The jku should be considered a hint only and parties should derive and then validate wherever possible the appropriate JWKS endpoint for the message signer.
https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1
The JOSE header is a JSON object consisting of at least two mandatory fields (claims):
Claim | RFC 7515 Standard ? | Required ? | Description |
---|---|---|---|
alg | Yes | Mandatory | The algorithm that will be used for signing the JWS. This is defined in https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
The list of allowed algorithms:
|
| Yes (optional) | Mandatory | The |
Step 3: Form the Payload to be Signed
The JSON payload to be signed must have the following claims:
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:
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:
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:
Where:
payload: is the payload computed in Step 3
signedAndEncodedPayload: is the signed element computed in Step 5.
Prerequisites
This section outlines the prerequisites for the NZ Security Profile.
Certificates
There are network endpoint certificates used for mutual TLS communication and message signing public/private key pairs used for signing and validating signed requests.
API Providers and Third Parties must obtain their own certificates from one of the approved Certificate Authority Issuers, and:
must have different public/private key pairs for network establishment and message signing
message signing public keys must be in the form of certificates.
Network Endpoint Certificates
The requirements for certificates used in production are:
must use X.509 v3 format
must use an RSA public key or an elliptic curve public key
should include certificate chain in the PEM file
RSA keys must have a key length of at least 4096 bits
EC keys must have a key length of at least 384[1] bits
must have a validity period of at most 2 years (between the NotBefore date and NotAfter date), and not more than 398 days for those that will be accessible via browser
must be an end-entity certificate (i.e., not a CA cert)
must be from one of these Certificate Authority issuers:
DigiCert
Entrust
Sectigo (formerly Comodo)
must be an OV (organisation validation) certificate
must have different certificates for network establishment and message signing
Message Signing Keys
The public/private key pairs used for message signing will meet the following requirements:
must be either an RSA or elliptic curve (EC) key pair
must be in X.509 V3 certificate format
Public keys must be published in RFC7517 JWK format
must populate the
x5c
claim with the certificate containing the public keymust include the
kid
claim to uniquely identify the public key
For RSA key pairs:
must use as a minimum RS512 as a signing algorithm, should use as a minimum PS512 as a signing algorithm
must use a key length of at least 4096 bits
For EC key pairs:
must have a key length of at least 384 bits, should have a key length of at least 521 bits
must use as a minimum ES384 as a signing algorithm, should use ES512 as a signing algorithm
must have a validity period of at most 2 years (between the NotBefore date and NotAfter date)
must have at least one key usage policy for signing:
digitalSignature (0)
nonRepudiation (1) -- recent editions of X.509 have renamed this bit to contentCommitment
keyEncipherment (2)
keyAgreement (4)
must not have any key usage policies for network
must be signed by one of the approved issuing certificate authorities
DigiCert
Entrust
Sectigo (formerly Comodo)
API Centre Register
Organisations
Once an organisation is verified with the Payments NZ API Centre as an API service user, an organisation record will be created for the API service user in the API Centre Register.
The Payments NZ API Centre will maintain the status of the API service user in the API Centre Register.
Keys
Once an organisation record has been created on the API Centre Register, an organisation will be able to upload their certificates (public keys) into the API Centre Register.
The API Centre Register service will only store message signing certificates.
The API Centre Register service will check that all signing certificates used in the API ecosystem in a production environment meet the requirements of Message Signing Keys
API service users (i.e., both API Providers and Third Parties):
must check that the specific certificate in use has not been revoked with the CA issuer (OCSP or CRL);
If the CA issuer is unavailable - the API service user must assume that the certificate is still “Active” with the CA for at least 24 hours. After 24 hours of unavailability it is at the API service user’s discretion to decide on treatment.
must check that the specific certificate in use is in an “Active” status in the API Centre Register;
If the API Centre Register is unavailable - the API service user must assume that the certificate is still “Active” with the API Centre Register for at least 24 hours. After 24 hours of unavailability it is at the API service user’s discretion to decide on treatment.
may override the status of the CA or API Centre Register - e.g., if an API Provider is told directly by a Third Party that the Third Party’s certificates are revoked prior to removal from the API Centre Register;
should check the status of certificates in the API Centre Register every hour, and should cache results;
must not use the API Centre Register as a transactional service (i.e., must not check the central public key store for each interaction between an API Provider and Third Party);
may perform other checks that are deemed necessary; and
must load replacement certificates at least 30 days before certificate expiry
Authorisation Servers
Once an organisation record has been created on the API Centre Register, an API Provider will be able to create records for their authorisation servers into the API Centre Register.
Third Parties will be able to retrieve authorisation server records from the API Centre Register.
Swagger
https://github.com/PaymentsNZ/API-Centre-Register
Keys used in examples
The following public keys may be used to verify the signatures of example JWT tokens. Certificates included in x5c
claim are non-normative examples and are self-signed.
API provider:
Third Party: