Thursday, 1 August 2019

Implementing app-to-app authorisation in OAuth2/OpenID Connect

What is app2app?

App2app is a mechanism that allows mobile apps performing OAuth2 or OpenID Connect based authentication to offer a much simpler faster flow if the user already has an app provided by the authorization server owner installed on their mobile device. Here's how it actually looks when I grant the moneyhub app on my iPhone access to my Nationwide current account:


It will be familiar to some in the UK - it is already in use by some challenger banks, and the largest 9 banks in the UK (the ‘CMA9’) are required to implement ‘app2app’ as a consequence of an order from the Competitions & Market’s Authority (a partially successful attempt to rectify the dysfunctional banking market we have had in the UK for a long time).

It's also noteworthy that the experience from the UK rollout of app2app is that drop off rates (where the user starts the process of giving a third party provider access to their bank account, but does not complete the process) massively dropped when app2app was used - i.e. far more users were successfully completing the process with app2app, compared to standard redirection. (This was not a surprise to most people - I'm sure I'm not alone in having no idea what the username, password or other security details are for the majority of my bank accounts.)

However, the ‘app2app’ model is not familiar to many outside the UK ecosystem, and there are few if any explanations of how it works at the protocol level - something I will attempt to address in this post.

Interestingly, relying parties have been doing 'app2web' for years in their own apps as described in IETF BCP212 - OAuth 2.0 for Native Apps - with app2app we're taking that exact same pattern that was applied to OAuth clients and instead applying it to the OAuth server.

I'm happy to explain this in more detail to anyone and to assist with decisions in this area, please drop me an email at joseph@emobix.co.uk if you'd like to know more.

How app2app works

App2app uses a standard OAuth or OpenID Connect flow. At the technical level, it looks something like this:


It makes use of the “claimed https url” feature of iOS and Android (as recommended by BCP 212 - OAuth 2.0 for Native Apps - also known as 'Deep linking', 'Universal links' on iOS or 'App Links' on Android). “Claimed urls” are a secure way for mobile apps to indicate that if a user attempts to view a url on their associated website, the app should be launched instead to provide a superior user experience. The TPP's app (acting on behalf of the OAuth client) needs to claim their registered redirect url.

For the third parties it generally requires only a handful of new lines of code if they already support the redirect flow. Normally they would just open an in-app “browser tab”, the only change is that they now need to check if there is an app on the system can open the url first, and if there is launch the app instead. On iOS using Swift this looks something like:

    // if bank's app is present & supports app2app, open it
    UIApplication.shared.open(authorizationEndpointUrl, options: [.universalLinksOnly: true]) { (success) in
    if !success {
        // launching bank app failed: app does not support universal links or
        // bank's app is not installed - open an in app browser tab instead
        <...continue as app did before app2app...>
    }

or in ObjC:

       [UIApplication.sharedApplication openURL: authorizationEndpointUrl options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @YES} completionHandler:^(BOOL success) {
            if (!success) {
                // launching bank app failed... continue as before
            }
        }];


Note how this automatically drops back to the 'old' way if the bank's app is not installed. Equally the bank's app should be implemented so that it does not care whether the TPP app is an app or a website. This means all 4 combinations (app2app, web2app, app2web, web2web) will automatically work;  an app will be used if available and it will fallback to the web experience if there's no app.

For banks, their mobile apps need to claim the relevant authorisation endpoints (which can be harder than it sounds, as some banks have multiple brands or segments of their customer base that are currently hosted on the same Authorization Endpoint but have different mobile apps). This generally means that banks will also need multiple discovery endpoints and hence multiple ‘issuer’ values. (There are other possible approaches, but they unfortunately increase the chances of successful phishing attacks targeted at the third parties so cannot be recommended.)

The bank’s app then needs to authenticate the user and obtain an OAuth 2,0 ‘authorization code’ (and, in Financial-grade API compliant systems, the associated id_token used as a detached signature for that code). Generally this is done by securely generating a private key protected by the user’s biometric. The key is registered with the authorization server during an initial pairing process, and then used by the app to prove to the server that the same user has completed a biometric authentication - properly implemented this satisfies the SCA (Strong Customer Authentication) requirement in PSD2, whilst still being an very easy process for the user.

As app2app is still relatively new, in most cases it will involve the bank adding a (relatively simple) custom plugin to a new authorization flow in their authorization server (there is no standard protocol for API used between the bank’s app and the bank’s authorization server). There is no standard that defines the details how how this is done, there are generally two choices:

  1. Entirely native user experience, and the banks authorization server has an API that the native mobile app can use to complete the consent process and obtain the authorization code given the biometric proof
  2. Partially native user experience, the app collects the biometric then sends the proof as an additional parameter to the authorization endpoint url, which is then presented in a web view to complete the consent process
The exact solution used is likely to be dictated by the capabilities available in the IdP software in use on the authorization server.


Once the banks app has the code (and maybe an id_token) it will pass them back to the third party app by appending them to the client’s preregistered redirect url as usual.

The flow then proceeds as per the normal redirection flow; the third party app passes the authorization code to it’s backend, which exchanges the authorization code for an access token (etc) by calling the bank authorization server’s token endpoint and can then access the bank APIs.

App2app, web2app, app2web, web2web

It's worth saying a little more about the possible combinations, as some of them require a little care - in particular in 'web2app' (where a mobile website being viewed in the web browser on a mobile device can use a native app to authenticate) - the redirect back to the relying party needs to go to the same web browser the user started in (so that their session cookies are still there). In some cases that may require a little care, and it's worth testing all four scenarios and making sure you're aware of any limitations your implementation has.

How does this relate to CIBA?

Many people will be aware of the relatively new CIBA and FAPI-CIBA specifications from the OpenID Foundation. Here's a quick summary:

CIBA

  • Can authenticate across devices; authentication process can be triggered from a petrol pump, call centre, point of sale terminal and so on
  • Relatively new protocol; some vendor's IAM products do not yet support it
  • Requires more actions from the user

App2app

  • Same device only
  • Does not require any changes to your iDP product, it can be deployed today
  • Faster/easier for user than CIBA
  • Very easy for relying parties to use if they are already using standard OAuth2/OpenID Connect flows
When doing authentication between two apps that are on the same device, I cannot think of a use case where it would be better to use CIBA.

PSD2: Why is app2app suddenly a hot topic?

The EBA recently (29th July 2019) issued a new set of clarifications on their interpretation of PSD2, containing the statement:

This means that, ASPSPs that have implemented a redirection approach and that enable their own PSUs to authenticate via the ASPSP's mobile app when the PSU directly accesses his/her account should also support app-to- app redirect when the customer uses a TPP

What this means is that all banks that implement “redirection” (i.e. the standard OAuth2 flow where the TPP sends the user's browser to the bank's login page) for authorising third parties to a user’s bank account will now need to support ‘app-to-app’ redirection flow (so long as the bank has a mobile app). This isn't the only reason you might need to implement 'app-to-app'; for example if you avoid the 'redirection' flow in favour of a decoupled flow, you will have to convince your National Competent Authority that doing a decoupled flow between apps/websites both being consumed on the same device does not present an "impediment" - which in my opinion would be a hard argument to win. If you're not sure if it's an impediment, I suggest you draw out the UX for 3 flows:

  1. The user authenticating to your ASPSP app to view transactions (or make a transaction)
  2. The user authenticating from a TPP app to your ASPSP app using app2app for the same scenarios
  3. The user authenticating from a TPP app to your ASPSP app (on the same device) using decoupled

If '3' has significantly more steps or delays for the user than '1' and '2' then you need to consider how extra steps may negatively affect the experience of your customers when using third parties and how you will justify those extra steps your National Competent Authority.

For consumers, the EBA clarification is a very good thing - if you’re using a third party service on your mobile device (for example the numerous apps that let you view all your bank accounts in a single place) your life has just been made a lot easier. Now when you want to add a new bank account, the third party app will open the relevant banking app, and the banking app will authenticate you in the normal way (often FaceID/TouchID or other very easy biometric based flow), confirm the access, and redirect you back to the third party app. (There’s also a ‘web-to-app’ variant of this if you’re using a third party website on a mobile device - it is really no different to 'app-to-app' and if a bank supports app2app web2app should 'just work'.)

The EBA opinion also shouldn’t be a surprise to anyone: PSD2 already required banks to authorise third party access using the same mechanisms the user would normally use - and for a large number of users (myself included) mobile banking apps protected by biometrics is my primary way of accessing my bank accounts. App2app is the only sensible way I have seen of allowing a user to authenticate with a biometric in a redirection based OAuth2 flow.

More on app2app


Please see my collection of app2app articles/presentations blog for further details.


I also run training courses on app2app that go into more detail on the implementation, best practices, common patterns (and anti-patterns) and potential problems - an initial 90 minute training session plus workshops as necessary, particularly useful for banks that plan to implement app2app in their apps/authorization servers. Please drop me an email if you're interested.