Today I’d like to tell you about how we went about implementing Open Banking at Kroo. Specifically how we went about allowing users to consent to Third Party Providers having access to their data.
A quick aside; Open Banking is an initiative to enable opening up of data at banks and financial institutes so that TTPs or other developers can access it. It was introduced by PSD2 which is a European regulation for electronic payment services.
If you don’t mind we will start off with a few key terms
- PSD2 — Payment Services Directive 2
- TPP — Third Party Provider (An AISP, PISP or CBPII)
- ASPSP — Account Services Payment Services Provider
- AISP — Account Information Service Provider (think Yolt or Emma)
- PISP — Payment Initiation Service Provider
- CBPII — Card-Based Payment Instrument Issuer
- PSU — Payment Service User (our customer)
Now let’s get into it, shall we?
So what is the consent journey?
The journey goes through a number of different steps which take place in both the TPP and the ASPSP.
- One of our customers will sign up to an AISP and ask them to connect to their accounts with us.
- The AISP will show the customer exactly what permissions that it will be requesting access for and whether they consent to those permissions.
- The AISP will tell us these are the permissions that I’m requesting and tell us which of our customers these permissions are for.
- We then ask our customer ‘did you consent to let this AISP have access with these permissions?’
- If the customers agree we give the AISP access to the customer’s data.
Which sounds pretty simple right? So it’s probably key to mention two things.
Firstly the security specification for PSD2 is based on the Financial API specification by the OpenId foundation which defines a security model built on-top of OpenId Connect and OAuth 2.
Secondly that we are operating under strict customer experience guidelines about what the journey looks like;
Parity of Experience: The experience available to a PSU when authenticating a journey via a TPP should involve no more steps, delay or friction in the customer journey than the equivalent experience they have when interacting directly with their ASPSP
Key to that is that here at Kroo we only provide a mobile app yet a TPP could be browser-based, app-based or as they like to say in the customer experience guidelines a ‘kiosk’; and we need to be able to let one of our customers consent from any of those.
Next, we’ll have a look at what we did.
Building the Kroo journey
Here at Kroo, we pride ourselves on being a tech company, we want to provide the best experience to our customers, the easiest journey, the best practices and using the best technology for the job.
So we wanted our customers to have the same experience no matter where they came from, that they only have to open the Kroo app on their device and just consent.
Fortunately, the folks over at OpenId had already thought about a great solution to this; Customer Initiated Backchannel Authentication (CIBA), also known as the Decoupled flow.
I’m not going to do a deep dive of what CIBA is, the people over at Authlete have already done it justice. It does come with a few different methods of how to implement it and we’ve gone with what’s called Poll Mode.
Let’s go through what’s happening here.
- The customer has consented on their TPP UI and provided an identifiable piece of information we can identify them with; which the TPP then sends to us.
- We do some validation, find the customer and then send back an Auth Request to the TPP. This is used to track the state of consent and can be exchanged for an Access Token.
- Then the TPP starts to Poll us to ask whether they can have an Access Token yet for the Auth Request. Once we have the customers decision we either return them a token or return them a 403 Forbidden.
- While 3 is happening we send a push notification to our customer’s devices where they have Kroo installed asking them to confirm or deny whether they consent. This then updates Auth Request we previously issued to the TPP.
I’ll show you what 4. looks like for a customer.
The Tech Behind It
When we built this back at the at the start of 2020, CIBA was the new kid in the cul-de-sac and to get it to work with our cloud native infrastructure we decided (maybe a bit naively), you know what we’re going to build this ourselves.
We use a number of technologies here at Kroo, Clojure as our main programming language, Kafka as our messaging technology, AWS as our cloud provider and event sourcing along with CQRS as the method to store and manage our data.
This is a snapshot of how we architected the system to be able to respond to a CIBA consent journey. Separate microservices* which handle the Open Banking and the Notification domains deployed on AWS ECS backed by an AWS RDS PostgresDB instance for the persistence layer and utilising AWS Simple Notification Service to push notifications to the customer devices either via Apple Push Notification service for iOS or Firebase Cloud Messaging for Android.
This gives us the resiliency to horizontally scale as much as we need to be able to handle increasing demand as more of our customers start using PSD2 to access their accounts at Kroo.
While the problem is complex (I never want to read an RFC again), the solution doesn’t need to be.
This was an extremely fun challenge and you learn an awful lot about OAuth and OpenId Connect when writing an Authorisation Server from scratch and when you get the green light from the OpenId certification suite that what you’ve done works and passes all the requirement… That is a good day.
* For a look at how we build our Clojure services and the restful standards behind them take a look at this great blog series from some of my colleagues (Part 1, Part 2).