This quickstart is written specifically for native Android apps that are written in Kotlin and use OkHttp
for making the API calls that you wish to protect with Approov. This quickstart provides a detailed step-by-step example of integrating Approov into an app using a simple Shapes
example that shows a geometric shape based on a request to an API backend that can be protected with Approov.
- Access to a trial or paid Approov account
- The
approov
command line tool installed with access to your account - Android Studio installed (Android Studio Bumblebee 2021.1.1 is used in this guide)
- The contents of this repo
Open the project in the shapes-app
folder using File->Open
in Android Studio. Run the app as follows:
You will see two buttons:
Click on the Say Hello
button and you should see this:
This checks the connectivity by connecting to the endpoint https://shapes.approov.io/v1/hello
. Now press the Get Shape
button and you will see this (or a different shape):
This contacts https://shapes.approov.io/v1/shapes
to get the name of a random shape. This endpoint is protected with an API key that is built into the code, and therefore can be easily extracted from the app.
The subsequent steps of this guide show you how to provide better protection, either using an Approov Token or by migrating the API key to become an Approov managed secret.
The Approov integration is available via Maven
. This allows inclusion into the project by simply specifying a dependency in the gradle
files for the app.
The approov-service-okhttp
dependency needs to be added as follows to the app/build.gradle
at the app level:
The Maven
dependency reference is:
implementation("io.approov:service.okhttp:3.3.1")
Make sure you do a Gradle sync (by selecting Sync Now
in the banner at the top of the modified .gradle
file) after making these changes.
Note that approov-service-okhttp
is actually an open source wrapper layer that allows you to easily use Approov with OkHttp
. This has a further dependency to the closed source Approov SDK itself.
In order for Approov tokens to be generated or secrets managed for the shapes endpoint, it is necessary to inform Approov about it. Execute the following command:
approov api -add shapes.approov.io
Note that any Approov tokens for this domain will be automatically signed with the specific secret for this domain, rather than the normal one for your account.
Uncomment the three lines of Approov initialization code in io/approov/shapes/ShapesApp.kt
:
The Approov SDK needs a configuration string to identify the account associated with the app. It will have been provided in the Approov onboarding email (it will be something like #123456#K/XPlLtfcwnWkzv99Wj5VmAxo4CrU267J1KlQyoz8Qo=
). Copy this into io/approov/shapes/ShapesApp.kt
, replacing the text <enter-your-config-string-here>
.
Next we need to use Approov when we make request for the shapes. Change the code inio/approov/shapes/MainActivity.kt
:
NOTE: Don't forget to comment out the previous line, the one using the standard
OkHttpClient()
.
Note that it is also necessary to uncomment the ApproovService
import near the start of the file.
Instead of using a default OkHttpClient
we instead make the call using a client provided by the ApproovService
. This automatically fetches an Approov token and adds it as a header to the request. It also pins the connection to the endpoint to ensure that no Man-in-the-Middle can eavesdrop on any communication being made.
You should also edit the res/values/strings.xml
file to change to using the shapes https://shapes.approov.io/v3/shapes/
endpoint that checks Approov tokens (as well as the API key built into the app):
In order for Approov to recognize the app as being valid, the local certificate used to sign the app needs to be added to Approov. The following assumes it is in PKCS12 format:
approov appsigncert -add ~/.android/debug.keystore -storePassword android -autoReg
This ensures that any app signed with the certificate used on your development machine will be recognized by Approov. See Android App Signing Certificates if your keystore format is not recognized or if you have any issues adding the certificate.
IMPORTANT: The addition takes up to 30 seconds to propagate across the Approov Cloud Infrastructure so don't try to run the app again before this time has elapsed.
Run the app and press the Get Shape
button. You should now see this (or another shape):
This means that the app is obtaining a validly signed Approov token to present to the shapes endpoint.
NOTE: Running the app on an emulator will not provide valid Approov tokens. You will need to ensure it always passes on your the device (see below).
If you don't get a valid shape then there are some things you can try. Remember this may be because the device you are using has some characteristics that cause rejection for the currently set Security Policy on your account:
- Ensure that the version of the app you are running is signed with the correct certificate.
- Look at the
logcat
output from the device. Information about any Approov token fetched or an error is output at theDEBUG
level. You can easily check the validity and find out any reason for a failure. - Use
approov metrics
to see Live Metrics of the cause of failure. - You can use a debugger or emulator and get valid Approov tokens on a specific device by ensuring you are forcing a device ID to pass. As a shortcut, you can use the
latest
as discussed so that thedevice ID
doesn't need to be extracted from the logs or an Approov token. - Also, you can use a debugger or Android emulator and get valid Approov tokens on any device if you mark the signing certificate as being for development.
This section provides an illustration of an alternative option for Approov protection if you are not able to modify the backend to add an Approov Token check. Firstly, revert any previous change to res/values/strings.xml
to using https://shapes.approov.io/v1/shapes/
that simply checks for an API key. The shapes_api_key
should also be changed to shapes_api_key_placeholder
, removing the actual API key out of the code:
You must inform Approov that it should map shapes_api_key_placeholder
to yXClypapWNHIifHUWmBIyPFAm
(the actual API key) in requests as follows:
approov secstrings -addKey shapes_api_key_placeholder -predefinedValue yXClypapWNHIifHUWmBIyPFAm
Note that this command requires an admin role.
Next we need to inform Approov that it needs to substitute the placeholder value for the real API key on the Api-Key
header. Only a single line of code needs to be changed at io/approov/shapes/MainActivity.kt
:
Build and run the app again and press the Get Shape
button. You should now see this (or another shape):
This means that the app is able to access the API key, even though it is no longer embedded in the app configuration, and provide it to the shapes request.