4
votes

We are building a mobile application and its API server with architecture as in the picture below.

enter image description here

We have WSO2 as the API gateway in front of the Spring Boot API Server. We use WSO2 API Manager to restrict who can call the APIs. Only clients that have registered with our WSO2 and have the correct consumer key and secret can call an API through WSO2, by which the client first call to WSO2's token endpoint to exchange the consumer key and secret with an access token, then call the desired API with the access token in header Authorization: Bearer <access token>

We have a problem that we don't know how to keep the consumer secret since security audits prohibit us to store the secret in mobile app installer package.

There were some questions already asked such as

WSO2 API Manager - How does mobile app connect to API Manager?

WSO2 Api Manager OAuth2 DCR security in public native mobile app

But no answers correctly point to the problem. Most of them was mislead by the complexity of oauth2 flow.

To make the problem specific and clear, please assume that our mobile don't have users to login. The goal of this problem is to allow only trusted mobile application to call the API through WSO2.

Please help suggest if this is possible or not. Or we have no choice but to allow anyone to call the API. Or WSO2' consumer subscribtion feature is not designed to be used directly from mobile app at all?

2
The short answer is you can't. You can obfuscate the tokens/keys to make it harder for an attacker, but essentially you cannot trust the device as you don't physically control it.Paulw11

2 Answers

1
votes

After doing some research, I found 2 options people usually do.

  1. Separate APIs into 2 groups. First group contains APIs that need to be used without user login, such as API to get initialization data or to get data for landing page of the app. Thease APIs are set as public, allow anyone to call without clientId and secret. The seconds group contains secured APIs that required the token. Mobile app can use Oauth2 PKCE flow to exchange the token with user identity proof.

  2. Obfuscate clientId and secret and keep them in mobile app installer package. The APIs are still be separated into 2 groups as before. But the first group requires client-level token (oauth2 client credential type) and the second group requires user-level token (resource owner password or authorization code type)

I prefer option 2. In my opinion, I think the first option does not really make sense. People choosing this option, maybe, just do it to bypass the security audit check list, to not store the secret in public client, without really concern about security problem. It's like when you cannot trust your kids to keep a key to your house safely, so you decided to remove the lock from the door.

Having every APIs protected and keep the key in the client. Even though some hacker can manage to find the secret, he can only hack APIs of the first group and you can track the clientId he used. You know the expect behavior of the client so it is easy to setup an alarm that detect malicious activities from the client and revoke the token, reset the secret and rollout more complex obfuscation algorithm.

0
votes

You may want to read OAuth 2.0 for Native Apps [RFC7636] spec. It states:

Public native app clients MUST implement the Proof Key for Code Exchange (PKCE [RFC7636]) extension to OAuth, and authorization servers MUST support PKCE for such clients, for the reasons detailed in Section 8.1.

Check the below answer too.

How to implement Oauth2 without sending client_secret in WSO2 APIM