@cds-au/holder-sdk v2.0.3
JS Holder SDK
Disclaimer
The artefacts in this repo are offered without warranty or liability, in accordance with the MIT licence.
The Data Standards Body (DSB) develops these artefacts in the course of its work, in order to perform quality assurance on the Australian Consumer Data Right Standards (Data Standards).
The DSB makes this repo, and its artefacts, public on a non-commercial basis in the interest of supporting the participants in the CDR eco-system.
The resources of the DSB are primarily directed towards assisting the Data Standards Chair for developing the Data Standards.
Consequently, the development work provided on the artefacts in this repo is on a best-effort basis, and the DSB acknowledges the use of these tools alone is not sufficient for, nor should they be relied upon with respect to accreditation, conformance, or compliance purposes.
The Problem
In line with the Australian Consumer Data Rights legislation the Data Standards Body defines a number of technical requirements on API endpoints for various industry sector. In particular the standard defines error payloads to be a specific format, containing specific error codes, etc. Because these error handling requirements across a large number of endpoints, coding these can be repetitive and therefore error prone.
The Solution
This packages is a boilerplate implementation of these common requirements and it can be used in any NodeJS / ExpressJS application as middleware.
The key functions exported by this package are cdrHeaderValidator, cdrResourceValidator, cdrScopeValidator and cdrEndpointValidator
.
The available middleware functions are intended for use in the application layer.
cdrHeaderValidator
This middleware function will handle some basic header checks and construct a CDR compliant ErrorList object where this required and return an appropriate Http status code.
A configuration object can
Scenario | Description |
---|---|
No x-v header is provided in the request | - Http status code 400 - An ErrorList is returned with Header/Missing. |
Invalid x-v header is provided with the request, eg alpha character | - Http status code 400 - An ErrorList is returned with Header/Invalid. |
Invalid x-min-v header is provided with the request | Http status code 400 - An ErrorList is returned with Header/Invalid. |
A requested version is not supported | - Http status code 406 - An ErrorList is returned with Header/UnsupportedVersion. |
No x-fapi-interaction-id in the request | An x-fapi-interaction-id header is set in the response header |
Request has x-fapi-interaction-id header | The x-fapi-interaction-id from the request is returned with the response header |
Invalid x-fapi-interaction-id header is provided with the request | - Http status code 400 - An ErrorList is returned with Header/Invalid. |
cdrEndpointValidator
This middleware function will examine the requst url and determine if it is a CDR endpoint. It construct a CDR compliant ErrorList object where this required and return an appropriate Http status code.
Scenario | Description |
---|---|
Endpoint not implemented | - Http status code 404 - An ErrorList is returned with Resource/NotImplemented. |
Endpoint not is not a CDR endpoint | - Http status code 404 - An ErrorList is returned with Resource/NotFound. |
cdrScopeValidator
This middleware function will perform a scope validation. It will check the user assigned scope against the scope required for the API endpoint. The function will construct a CDR compliant ErrorList object where this required and return the appropriate Http status code.
Note that this functionality requires access to the scopes contained from access token generated by the IdAM (Identity and Access Management System). To achive this an implementation of IUserService is required to be passed in by the consumer of this middleware.
Refer to the example project in js-holder-sdk-demo project
Scenario | Description |
---|---|
Invalid scope in access token | - Http status code 403 - An ErrorList is returned with Authorisation/InvalidScope |
cdrResourceValidator
This middleware function will validate resource specific identifiers (eg accountId) and ensure that consent to access these resources has been given. This function is only relevant to API calls where a resource identifier forms part of the request url (eg /banking/accounts/{accountId})
Note that this functionality requires knowledge of the consented accounts. This information can be obtained from access token generated by the IdAM (Identity and Access Management System). To achive this an implementation of IUserService is required to be passed in by the consumer of this middleware.
Scenario | Description |
---|---|
Access to the resource url has not been consented to | Http status code 404 |
Example Request Pipeline
The diagram illustrates one possible request pipeline and how the middleare functions can be used in a data holder implementation.
Other implementations using a different order, of only some of of the exposed functions are entirely possible.
Alternative Scope Validation
The combination of cdrJwtScopes and cdrTokenValidator functions can be used to validate scopes, and therefore performs a function similar to the cdrScopeValidator. It does however make assumptions on the Identity Provider implementation. Nevertheless, depending on the precise data holder implementation this may be more suitable than the IUsserInterface.
cdrTokenValidator
This middleware function will handle some basic authorisation checks and construct a CDR compliant ErrorList object where this required and return an appropriate Http status code.
Note that the functionality here requires access to the scopes contained from access token generated by the IdAM (Identity and Access Management System). For a common scenario where the access token is being issued as a JWT, the cdrJwtScopes middleware can be utilised to extend the Request object accordingly.
Scenario | Description |
---|---|
No authorisation header present in Request | Http status code 401 |
Authorisation header is present, invalid scope in access token | - Http status code 403 - An ErrorList is returned with Authorisation/InvalidScope |
cdrJwtScopes
This middleware function will extend the Request object and make the scopes contained in the access token accessible from the Request object.
This can be used for any IdAM which returns the access token as an JWT and the scopes property is either an array of strings or a space separated string. The middleware will expect a configuration object.
Scenario | Description |
---|---|
The access token from the IdAM is a JWT and scopes are an array of strings | The request object will be extended |
The access token from the IdAM is a JWT and scopes are a space separated string | The request object will be extended |
Possible implementation
How to use
Install the library with npm or yarn
npm i @cds-au/holder-sdk
Import the library
import { cdrHeaderValidator } from '@cds-au/holder-sdk';
then inject in http pipeline where this is appropriate
app.use(cdrHeaderValidator(dsbOptions));
Configuration Object
The middleware functions cdrEndpointValidator, cdrHeaderValidator, cdrTokenValidator
and cdrJwtScopes
will accept a configuration object (CdrConfig). This object should define each endpoint implemented by the application.
Each endpoint must be defined by the request type (GET/POST/DELETE) and the path as defined in the published standard
The config parameter may be ommitted, in which case the implemented endpoints are assumed to be the DefaultEnergyEndpoints, DefaultBankingEndpoints, and DefaultCommonEndpoints as declared in this repository.
The middleware functions cdrResourceValidator
and cdrScopeValidator
require an mandatory implementation of IUserInterface as a parameter.
const implementedEndpoints = [
{
"requestType":
"GET",
"requestPath": "/banking/payments/scheduled",
"minSupportedVersion": 1,
"maxSupportedVersion": 1
},
{
"requestType": "GET",
"requestPath": "/banking/accounts/{accountId}/balance",
"minSupportedVersion": 1,
"maxSupportedVersion": 1
},
…etc
const config: CdrConfig = {
endpoints: implementedEndpoints
}
app.use(cdrHeaderValidator(config))
Demo Project
Note: The demo project with this library was tested with NodeJS v18.7.0
The js-holder-sdk-demo project provides a basic implementation illustrating how the middleware can be used in a NodeJS/ ExpressJS application