How to Integrate Approov Secrets Protection with Azure Key Vault - Step by Step Guide

See this blog for an overview of Secret Vault and Approov Integration.

Why Integrate Approov with Azure Key Vault?

Risk

Without Approov

With Approov + Azure Key Vault

API key exposure

Keys are hardcoded in app and easily extracted

Keys are never in the app; only injected after verification

App impersonation

Bots and scripts can access protected APIs

Requests without verified apps are denied secrets

Centralized key control

Inconsistent storage across mobile builds

Secrets are managed securely in one place (Azure KV)

Compromised environments

Malicious apps on rooted devices leak secrets

Secrets only delivered to attested apps on trusted devices


Integrating Azure Key Vault with Approov to fetch API keys only when app and device are validated requires a secure workflow that ensures:

  1. API keys are not stored in the app code.
  2. API key retrieval is attested and conditional (based on app and device integrity),
  3. Approov acts as a trusted mediator between the mobile app and the key management system (e.g., Azure Key Vault).

Here are three ways to inject Approov device and app attestation before API key delivery:

  • Option 1: On demand delivery of secrets: Each time the app needs to retrieve and substitute an API Key the Approov service runs the attestation check and then requests the API Key directly from Azure Key Vault and delivers it to the app. This has the disadvantage that secrets can be exposed in app memory and means that there is runtime dependency on the availability and latency of Azure Key Vault requests.
  • Option 2: Use Approov as a proxy to Azure Key Vault, provisioned regularly with secrets from the Vault, and use Approov Secrets Management Via Secure Strings: This takes advantage of the ability of the Approov SDK to directly retrieve and substitute API Keys when app and device are validated. API Keys can be synched  from the vault  to the Approov service automatically so that there is no dependency on vault availability. This will work well for non-dynamic keys, and is the required approach for when you don't control the backend - eg for third-party APIs.   
  • There is a recommended variant of Option 1 or 2 If you want to avoid backend mediation (Option 3) but still minimize latency: this involves fetching the API key once at app startup after attestation. It is then cached securely in memory for  subsequent API calls during the session with forced  re-attestation on app restart or session expiry.
  • Option 3: Backend Mediator: This scenario uses the request-by-request attestation carried out by Approov but keeps access to API keys in the backend. The mobile app calls the API including the Approov token which, if validated, tells the backend to fetch secrets from Azure Key Vault to be used. This needs a little more work at the backend but means there are never secrets in the app or device and provides more centralized control.  

Summary Table of Integration Options

Option

Summary

✔ Comment

Option 1

On-demand secrets from Approov → Attestation → Approov fetches from Azure KV → delivers to app.

✔ Correct. Risk: runtime dependency & secrets in memory.

Option 2

Approov Secure Strings → Synced with Azure KV regularly → App fetches from Approov post-attestation.

✔ Correct. Perfect for 3rd-party APIs or static keys.

Variant

Fetch at app startup → Cache in memory → Force re-attestation on restart/expiry.

✔ Good addition. Reduces latency but keys in memory.

Option 3

Backend Mediator → App sends Approov token → Backend validates → Backend fetches API keys from Azure KV.

 

Depending on the use-case, Options 2 and 3 are the best approaches. Either will keep your critical API secrets away from dangerous devices, compromised apps and…  hackers. It also means you can manage and update them easily and quickly whenever you need to. 

The rest of the article shows the step-by-step implementation process for Option 2 and Option 3 - we don't show the implementation steps for Option 1 since it is not recommended. 

Option 2 - Approov Secrets Management Via Secure Strings with Automated Approov API Key Substitution - Step By Step Guide

Overview

In this model:

  • API keys are stored securely in Azure Key Vault.
  • A scheduled process syncs keys from Azure Key Vault into Approov Secure Strings.
  • The Approov SDK in your mobile app dynamically injects API keys at runtime, but only after successful attestation.
  • Mobile apps never see hardcoded API keys, and no direct access to Azure Key Vault is required at runtime.

Prerequisites

  • An Azure subscription with Key Vault enabled.
  • Approov account with admin access.
  • Approov CLI installed.
  • Approov SDK integrated into your mobile app.

Step 1: Setup Azure Key Vault

  1. Create a Key Vault (if not done):

    bash
    az keyvault create \

    --name MyKeyVault \

    --resource-group MyResourceGroup \

    --location westus

  1. Store an API key:

    bash
    az keyvault secret set \

    --vault-name MyKeyVault \

    --name API_KEY \

    --value "sk_live_1234567890abcdef"

  1. Grant read access to a service principal (for sync process):

    bash
    az ad sp create-for-rbac --name approov-sync --role Reader

Step 2: Sync Azure KV Secrets to Approov

This ensures Approov is preloaded with the latest secrets.

2.1 Install Approov CLI

Follow Approov CLI installation guide:

bash

curl -O https://approov.io/docs/latest/approov-cli-install.sh

bash approov-cli-install.sh

2.2 Authenticate with Approov

bash

approov login


You will be prompted for your Approov admin credentials.

2.3 Write a Sync Script

Create a simple Python script to pull from Azure and push to Approov:

python

from azure.identity import DefaultAzureCredential

from azure.keyvault.secrets import SecretClient

import subprocess


# Azure Key Vault setup

vault_url = "https://MyKeyVault.vault.azure.net"

credential = DefaultAzureCredential()

client = SecretClient(vault_url=vault_url, credential=credential)


# Retrieve secret from Key Vault

secret_name = "API_KEY"

retrieved_secret = client.get_secret(secret_name).value


# Push to Approov Secure Strings

approov_command = [

    "approov", "secret", "add", secret_name, retrieved_secret, "--env", "prod"

]

subprocess.run(approov_command, check=True)


print(f"Synced {secret_name} to Approov Secure Strings.")

2.4 Automate Sync

Option A: Cron job for periodic sync:

bash
crontab -e

 Add:

bash
0 * * * * /usr/bin/python3 /path/to/sync_script.py

Option B: CI/CD pipeline step (GitHub Actions, Jenkins, etc.)

Step 3: Integrate Approov SDK in Mobile App

3.1 Add Approov SDK

  • For Android:
    Add the Approov AAR to your build.gradle

  • For iOS:
    Add the XCFramework via CocoaPods or Swift Package Manager.

3.2 Replace Hardcoded API Keys

In your API request code, use a placeholder:

swift

let apiKey = "API_KEY_PLACEHOLDER"


Approov will replace this placeholder at runtime.

3.3 Configure Placeholder Substitution

Ensure placeholder mapping is configured in Approov:

bash

approov config add-substitution API_KEY_PLACEHOLDER API_KEY

3.4 Fetch Secure String Dynamically (Optional)

If you prefer explicit retrieval:

kotlin

val apiKey = ApproovService.fetchSecureString("API_KEY", null)

if (apiKey != null) {

    // Use apiKey for API calls

}

Step 4: Test the Flow

  1. Deploy a test build of the app.
  2. Confirm attestation passes and API key is injected dynamically.
  3. Rotate API key in Azure Key Vault → run sync script → confirm new key is served.

Benefits of This Approach

  • No runtime dependency on Azure Key Vault
  • Keys only delivered to verified apps and devices
  • Works even for 3rd-party APIs (no backend control required)
  • Easy to rotate secrets via Azure → Approov sync

Option 3 – Backend Mediator (Approov Token → Backend → Azure KV)

Overview

Secrets never leave backend. Backend validates Approov token before fetching from Azure Key Vault.

Step 1: Setup Azure Key Vault (Same as Option 2)

Step 2: Setup Backend to Verify Approov Tokens

  1. Install Approov backend library:

Node.js:

bash
npm install approov-service-node

  1. Validate token in API middleware:

    javascript
    CopyEdit
    const ApproovService = require('approov-service-node');

app.use(async (req, res, next) => {

    const token = req.headers['Approov-Token'];

    const result = await ApproovService.checkToken(token);

    if (!result.isValid) return res.status(401).send("Unauthorized");

    next();

});

Step 3: Backend Fetches Secrets from Azure Key Vault

  1. Fetch API keys from Key Vault after successful attestation:

    python
    from azure.identity import DefaultAzureCredential

from azure.keyvault.secrets import SecretClient


credential = DefaultAzureCredential()

client = SecretClient(vault_url="https://MyKeyVault.vault.azure.net", credential=credential)

api_key = client.get_secret("API-KEY").value

  1. Use api_key to call downstream APIs or include in proxied responses.

Step 4: Mobile App

  1. Integrate Approov SDK to fetch tokens.

  2. Add token to API requests:

    kotlin
    request.addHeader("Approov-Token", approovToken)

Summary Comparison of Implementation Effort

Step

Option 2 (Approov Secrets)

Option 3 (Backend Mediator)

Sync Secrets

Azure → Approov (cron job)

Backend fetches at runtime

Mobile App Changes

Placeholder replacement

Add Approov token header

Backend Changes

None

Validate token + fetch KV

Secrets Exposure in App

✅ Runtime memory

❌ Never

Last Word

Integrating Approov Secrets Protection with Microsoft Azure Key Vault enables a powerful combination of:

  • Zero-trust secrets management for mobile apps
  • Centralized cloud-native key and secret storage
  • Runtime access control based on app attestation

This general approach works for integration with any Secret Vault: eg Azure Key Vault (Microsoft), AWS Secrets Manager (Amazon), Google Cloud Secret Manager, HashiCorp Vault, CyberArk Conjur, Akeyless Vault.