Authentication overview

Application Environment Verification, through services like Approov, implements an authentication model designed to ensure that API requests originate from a legitimate, untampered mobile application instance, rather than a bot, modified client, or compromised environment. This approach extends beyond traditional user or device authentication by focusing on the integrity of the application itself. The core mechanism involves a challenge-response protocol where the mobile SDK embedded within the application communicates with the Application Environment Verification cloud service to generate a short-lived cryptographic token. This token, known as an Approov token, is then sent with subsequent API requests to the backend server.

The backend server, integrated with an Application Environment Verification SDK or a custom validator, intercepts the incoming API request. It then verifies the authenticity and validity of the Approov token by communicating with the Application Environment Verification cloud service. If the token is valid, indicating a legitimate application environment, the backend processes the request. If the token is invalid or missing, the request is denied, thereby protecting the API from unauthorized access, automated attacks, and attempts to circumvent application logic. This method complements existing user authentication (e.g., OAuth 2.0, API keys) by adding an additional layer of assurance regarding the client's integrity, as detailed in the Approov API reference.

Supported authentication methods

Application Environment Verification's authentication mechanism is built around the concept of application attestation. While it doesn't directly replace user authentication methods, it provides a critical prerequisite by verifying the application's integrity before any user-specific or API-key-based authentication proceeds. The primary method involves the generation and validation of an Approov token. The following table outlines the core method:

Method When to Use Security Level
Approov Token (Cryptographic Attestation) For all API requests originating from mobile applications to verify the app's integrity and environment. Essential for protecting against bots, reverse engineering, and credential stuffing. High: Verifies the authenticity and integrity of the calling application instance. Complements, rather than replaces, user and API key authentication.

This token-based approach is integrated into the client application via an SDK and validated on the backend. The token itself is a JSON Web Token (JWT) that contains claims about the application's integrity. The validation ensures that the token has not been tampered with and was issued to a genuine application instance. For a deeper understanding of JWTs and their role in authentication, refer to the IETF RFC 7519 on JSON Web Token (JWT).

Getting your credentials

To implement Application Environment Verification, you typically need to obtain specific credentials from the service provider, such as Approov. This process generally involves:

  1. Account Creation and Setup: Register for an account with the Application Environment Verification service. During setup, you'll configure your mobile applications and backend APIs within their platform. This often involves specifying your application's package name (Android) or bundle ID (iOS) and associating it with a unique Application Environment Verification app ID.
  2. SDK Integration: Download and integrate the appropriate Application Environment Verification SDK into your mobile application. SDKs are available for various platforms, including iOS, Android, React Native, and Flutter. The SDK handles the generation of the Approov token.
  3. Backend Integration: Implement the Application Environment Verification token validation logic on your backend API. This typically involves using a server-side SDK or a custom library to verify the Approov token sent with each API request. The backend needs to be configured with a shared secret or a public key provided by the Application Environment Verification service to perform this validation securely. Instructions for various backend technologies are provided in the Approov server integration documentation.
  4. Policy Configuration: Define policies within the Application Environment Verification service console to control how tokens are issued and validated. This includes setting up API protection rules, defining expected application states, and configuring responses to detected threats.

The specific credentials, such as API keys or secrets for backend validation, are typically provided within your Application Environment Verification account dashboard after you've set up your applications. Always refer to the official Approov documentation for the most accurate and up-to-date instructions on obtaining and managing your credentials.

Authenticated request example

An authenticated request using Application Environment Verification involves two main parts: the client-side generation of an Approov token and the server-side validation of that token. Below is a conceptual example demonstrating this flow. This example uses pseudocode to illustrate the steps; actual implementation will vary based on the specific mobile platform and backend language.

Client-side (Mobile Application - e.g., Swift for iOS)

import ApproovSDK

// 1. Initialize Approov SDK (typically once at app startup)
Approov.initialize(config: "YOUR_APPROOV_CONFIG_STRING") {
    // Handle initialization completion or errors
}

// 2. Intercept outgoing API request and add Approov Token
func makeAuthenticatedAPIRequest() {
    // Assume 'request' is your URLRequest object
    var request = URLRequest(url: URL(string: "https://api.example.com/data")!)
    request.httpMethod = "GET"

    Approov.fetchToken { (approovResult: ApproovTokenFetchResult) in
        switch approovResult.status {
        case .success:
            if let token = approovResult.token {
                request.addValue(token, forHTTPHeaderField: "Approov-Token")
                // Proceed with network request
                URLSession.shared.dataTask(with: request) { data, response, error in
                    // Handle response
                }.resume()
            }
        case .prodDetection:
            // Handle production detection (e.g., app tampered, rooted device)
            print("Approov Production Detection: \(approovResult.log!)")
        case .networkError, .clientError, .configError, .initialisationError, .unknownError:
            // Handle errors (e.g., network issues, SDK misconfiguration)
            print("Approov Error: \(approovResult.log!) - Status: \(approovResult.status)")
        @unknown default:
             print("Approov Unknown Status: \(approovResult.status)")
        }
    }
}

Server-side (Backend API - e.g., Node.js with Express)

const express = require('express');
const { ApproovService } = require('@approov/approov-nodejs-sdk'); // Example SDK
const app = express();

// Initialize Approov Service with your secret
const approovService = new ApproovService({
    secret: 'YOUR_APPROOV_SECRET' // This secret is obtained from your Approov account
});

// Middleware to validate Approov Token
app.use('/api/data', async (req, res, next) => {
    const approovToken = req.headers['approov-token'];

    if (!approovToken) {
        return res.status(401).send('Approov Token missing.');
    }

    try {
        const result = await approovService.verifyToken(approovToken);
        if (result.isValid) {
            // Token is valid, proceed to next middleware or route handler
            next();
        } else {
            // Token invalid or other issues detected by Approov
            console.error('Approov Token validation failed:', result.details);
            return res.status(403).send('Invalid Approov Token.');
        }
    } catch (error) {
        console.error('Approov Token verification error:', error);
        return res.status(500).send('Internal server error during token verification.');
    }
});

// Protected API endpoint
app.get('/api/data', (req, res) => {
    res.json({ message: 'Welcome, legitimate app user!' });
});

app.listen(3000, () => {
    console.log('Server listening on port 3000');
});

This example demonstrates how the client obtains an Approov-Token and includes it in the request header, which the backend then validates before processing the API call. This ensures that only requests from verified application environments are granted access to the protected resources.

Security best practices

Implementing Application Environment Verification effectively requires adherence to several security best practices to maximize its protective capabilities:

  • Always Validate Tokens on the Backend: Never rely solely on client-side checks for the presence or validity of an Approov token. All token validation must occur on your backend API servers, where secrets and validation logic are protected from client-side tampering. This is a fundamental principle of API security, as highlighted in Google's OAuth 2.0 documentation, emphasizing server-side validation for access tokens.
  • Use Short-Lived Tokens: Approov tokens are designed to be short-lived to minimize the window of opportunity for token replay attacks. Ensure your backend validation logic respects the token's expiry time.
  • Secure Your Approov Secret/Key: The secret or public key used by your backend to validate Approov tokens must be stored securely. Avoid hardcoding it directly into your application code. Instead, use environment variables, secure configuration management systems, or a secrets manager like AWS Secrets Manager.
  • Implement Strong Error Handling: On both the client and server sides, implement robust error handling for Approov token operations. On the client, gracefully handle cases where a token cannot be fetched (e.g., network issues, device compromise) and provide appropriate user feedback without exposing sensitive information. On the server, treat missing or invalid tokens as unauthorized access attempts and respond with appropriate HTTP status codes (e.g., 401 Unauthorized, 403 Forbidden).
  • Combine with User Authentication: Application Environment Verification is a layer of defense for the application itself. It should be used in conjunction with, not as a replacement for, robust user authentication (e.g., OAuth 2.0, OpenID Connect) and authorization mechanisms to control access to specific user data and functionalities.
  • Regularly Review Approov Policies: Periodically review and update your Application Environment Verification policies within the service console. This includes adjusting threat detection thresholds, adding new API protection rules, and adapting to new attack vectors or changes in your application's architecture.
  • Monitor and Alert: Integrate Application Environment Verification's logs and alerts into your existing security monitoring systems. Promptly investigate any anomalies, such as a sudden increase in token validation failures or production detection events, which could indicate an ongoing attack or a compromised application.
  • Keep SDKs Updated: Ensure that both your client-side and server-side Application Environment Verification SDKs are kept up to date. Updates often include security patches, performance improvements, and support for new mobile OS versions or threat detection capabilities.