This quickstart is for developers familiar with Mulesoft API Gateway who want to learn how they can protect an existing API project in the Mulesoft API Gateway by applying a JWT validation policy to check the Approov token validity.
- Why?
- How it Works?
- Requirements
- Approov Setup
- Approov Token Check
- Test your Approov Integration
- Troubleshooting
To lock down your API server to your mobile app. Please read the brief summary in the Approov Overview at the root of this repo or visit our website for more details.
For more background, see the Approov Overview at the root of this repo.
To complete this quickstart you will need to have an existing API created in the Mulesoft API Gateway, and also have the Approov CLI installed.
- Mulesoft API Gateway Project - If you don't have one yet you may want to follow instead the Mulesoft API Gateway Approov Example.
- Mulesoft Anypoint CLI - Will be used to create all the necessary resources in the Mulesoft platform.
- Approov CLI - Will be used to setup your Approov secrets and to configure the API you want to protect.
This quickstart was tested with the following Operating Systems:
- Ubuntu 20.04
- MacOS Big Sur
- Windows 10 WSL2 - Ubuntu 20.04
To use Approov with Mulesoft API Gateway you need a small amount of configuration. First, Approov needs to know the API domain that will be protected. Second, Mulesoft API Gateway needs to know the public key to use in order to verify the JWT tokens generated by the Approov cloud service.
To use the Approov CLI in the next steps you need to enable the role under which you will run the commands. While the approov api
command can be executed with the basic dev
role, other commands will require an admin
role, see account access roles documentation.
Enable your Approov admin
role with:
eval `approov role admin`
For the Windows powershell:
set APPROOV_ROLE=admin:___YOUR_APPROOV_ACCOUNT_NAME_HERE___
NOTE: First time that you will execute an Approov command you will be prompted for your password, authenticate your selected Approov role with your password. This will create an authenticated session that will expire in 1 hour, after which you will again be prompted for your password.
To sign the Approov token a private/public key pair will be used and auto generated by the Approov service, and stored under a Keyset ID on your account.
Let's export to the environment the Keyset ID, that will be used through several commands in the next steps:
# export KEYSET_ID=mule
export KEYSET_ID=___YOUR_KEYSET_ID_HERE___
Let's create one with:
# approov keyset -add RS256 -keyLength 2048 -kid mule
approov keyset -add RS256 -keyLength 2048 -kid ${KEYSET_ID}
NOTE: The
-kid
is optional and if not provided an incremental numeric ID will be used.
Approov needs to know the domain name of the API for which it will issue tokens.
Let's export to the environment the Mulesoft API domain, that you will use on several commands in the next steps:
# export API_DOMAIN=api.example.com
export API_DOMAIN=___YOUR_MULESOFT_API_DOMAIN_HERE___
Add the Mulesoft API domain with:
# approov api -keySetKID mule -add shapes.us-e2.cloudhub.io
approov api -keySetKID ${KEYSET_ID} -add ${API_DOMAIN}
Adding the API domain also configures dynamic certificate pinning for the API, the apps using your API need to be modified to take advantage of this.
NOTE: By default the pin is extracted from the public key of the leaf certificate served by the domain, as visible to both the box issuing the Approov CLI command and the Approov servers. Other
approov
commands can modify this default.
Approov tokens are standard JSON Web Tokens(JWTs), thus to check it in any existing Mulesoft API Gateway project you just need to apply the JWT policy with the Approov public key from the certificate used to sign the JWT.
First, get the public key from the Approov keyset configured for your API:
# approov keyset -kid mule -getPEM public-key.pem
approov keyset -kid ${KEYSET_ID} -getPEM public-key.pem
Next, create one line string for the public key with:
awk 'NR>2 { sub(/\r/, ""); printf "%s\\n",last} { last=$0 }' public-key.pem > public-key-string.pem
NOTE: - Removes the first and last line from the certificate and preserves new lines with
\n
to allow to use the certificate as 1 line string in the JSON we need to pass in the--config
parameter.
Now, apply the policy with:
anypoint-cli api-mgr policy apply \
--policyVersion 1.2.0 \
--config "{\"jwtOrigin\":\"customExpression\", \"jwtKeyOrigin\":\"text\", \"textKey\":\"$(cat public-key-string.pem)\", \"jwtExpression\":\"#[attributes.headers[\\\"Approov-Token\\\"]]\", \"signingMethod\":\"rsa\", \"signingKeyLength\":\"256\", \"jwksUrl\":\"example.com\", \"skipClientIdValidation\":true, \"clientIdExpression\":\"#[vars.claimSet.client_id]\", \"validateAudClaim\":false, \"mandatoryAudClaim\":false, \"supportedAudiences\":\"aud.example.com\", \"mandatoryExpClaim\":true, \"mandatoryNbfClaim\":false, \"validateCustomClaim\":false}" \
___YOUR_API_INSTANCE_ID___ jwt-validation
NOTE: Some of the config keys have placeholder values because they are required to be presented when applying the policy, but aren't used at runtime.
The Mulesoft platform may take more then one minute to effectively apply the policy to your API, therefore wait for one minute or two before you proceed to the next step of testing your Approov integration.
The examples below use cURL to perform a request adding valid, invalid and no Approov token. You will need to expand these requests to include all the properties expected by the protected API. If you have an existing test setup using Postman, or some other mechanism/tool, then it should be easy to adjust that to add the different tests listed here.
Make a cURL request using one of the routes to which you added the Approov authorizer:
curl -iX GET "https://${API_DOMAIN}" \
--header "Approov-Token: $(approov token -type invalid -genExample ${API_DOMAIN})"
NOTE: If this command fails to complete, then it's probably because your Approov CLI authenticated session has expired and it is waiting for your password input. Kill the command and authenticate again as instructed in the Troubleshooting section.
The above request should fail with an Unauthorized error. For example:
{
"error": "Invalid token."
}
NOTE: If you see a
200
response instead of the expected401
then it means that the Mulesoft API has not finished to apply the JWT policy for checking the Approov token, therefore you need to retry again in a few seconds, otherwise you may have failed to properly follow some of the previous steps.
Make a cURL request using one of the routes to which you added the Approov authorizer:
curl -iX GET "https://${API_DOMAIN}"
Output:
{
"error": "JWT Token is required."
}
Make a cURL request using one of the routes to which you added the Approov authorizer:
curl -iX GET "https://${API_DOMAIN}" \
--header "Approov-Token: $(approov token -type valid -genExample ${API_DOMAIN})"
The result of the cURL request should successful as defined by the protected API.
The Approov CLI prompts for a password when the first approov command is issued after selecting an admin
role and every hour after that. If you execute an Approov CLI command in a sub-shell, then the password prompt and opportunity for input may be lost. If a command sequence fails then it may be because your session has expired. Run a simple Approov CLI command to see if you need to renew your session, most commands will require a password to complete, even if the command just displays a help message::
approov api
Note that approov role .
can be used to extend an active session. See approov role documentation.
If you find any issue while following our instructions then just report it here, with the steps to reproduce it, and we will sort it out and/or guide you to the correct path.
If you wish to explore the Approov solution in more depth, then why not try one of the following links as a jumping off point: