---
title: Inject and Auto-Refresh Auth Tokens in Mobile Application Tests
description: >-
  Pass a live, auto-refreshing authentication token into a mobile application
  test to bypass the login flow.
breadcrumbs: >-
  Docs > Synthetic Testing and Monitoring > Synthetic Monitoring Guides > Inject
  and Auto-Refresh Auth Tokens in Mobile Application Tests
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# Inject and Auto-Refresh Auth Tokens in Mobile Application Tests

## Overview{% #overview %}

Logging in through your app UI at the start of every [mobile application test](https://docs.datadoghq.com/synthetics/mobile_app_testing.md) adds duration and flakiness unrelated to the test. This guide shows how to skip that login step by injecting a live authentication token so the test starts already authenticated.

The flow has three parts:

1. An [API test](https://docs.datadoghq.com/synthetics/api_tests/http_tests.md) logs in to your authentication provider on a schedule and extracts an access token.
1. A [global variable](https://docs.datadoghq.com/synthetics/platform/settings.md#global-variables) sourced from that test holds the token's value.
1. Your mobile app test passes the global variable into the app as a launch argument or intent extra. Your app reads it at startup and skips its normal login flow.

Because the API test refreshes the token on a schedule, the global variable's value updates on its own, without any manual work or Datadog API calls.

## Step 1: Create the token-fetch API test{% #step-1-create-the-token-fetch-api-test %}

If your authentication provider requires a client secret, store it as a secure [global variable](https://docs.datadoghq.com/synthetics/platform/settings.md#global-variables) first, instead of hardcoding it in the request. Enter a name such as `AUTH_CLIENT_SECRET` and select Hide and obfuscate variable value when you create it.

Create an [HTTP test](https://docs.datadoghq.com/synthetics/api_tests/http_tests.md) that requests a token from your provider's token endpoint:

- **Request**: `POST` to your token endpoint, such as `https://auth.yourdomain.com/oauth/token`.
- **Header**: `Content-Type: application/json`.
- **Body**: a JSON payload with your client credentials, referencing the `AUTH_CLIENT_SECRET` global variable:

```json
{
  "client_id": "synthetic_bot",
  "client_secret": "{{ AUTH_CLIENT_SECRET }}",
  "grant_type": "client_credentials"
}
```

- **Assertion**: status code is `200`.
- **Extracted variable**: [extract a variable](https://docs.datadoghq.com/synthetics/api_tests/http_tests.md#define-assertions) named `EXTRACTED_TOKEN` from the response body, using a `jsonpath` expression that matches your token field, such as `$.access_token`. Select Hide and obfuscate variable value so the token doesn't appear in test results.

Set the test [frequency](https://docs.datadoghq.com/synthetics/api_tests/http_tests.md#specify-test-frequency) shorter than your token's expiration window, so the token doesn't go stale between runs. For example, run the test every 30 minutes for a token that expires after an hour. You can also attach a failure alert to the test to know if it stops refreshing the token.

## Step 2: Create a global variable from the test{% #step-2-create-a-global-variable-from-the-test %}

[Create a global variable](https://docs.datadoghq.com/synthetics/platform/settings.md#global-variables) from the token-fetch test so your mobile app test can reference its value:

1. Navigate to the Global Variables tab on the [Settings page](https://app.datadoghq.com/synthetics/settings). Click + New Global Variable.
1. Select the Create From Test tab, and select your token-fetch test.
1. Enter a Variable Name, such as `MOBILE_AUTH_TOKEN`.
1. Select Hide and obfuscate variable value so the token doesn't appear in test results.
1. Select where to source the value from:
   - If your token-fetch test is a single HTTP request, select Response Body and reuse the `jsonpath` expression from your test assertion, for example `$.access_token`.
   - If your token-fetch test has multiple steps, select the EXTRACTED_TOKEN local variable you extracted in Step 1.

This variable's value updates automatically whenever the token-fetch test runs.

## Step 3: Pass the token to your mobile app test{% #step-3-pass-the-token-to-your-mobile-app-test %}

Mobile app tests support passing `key:value` pairs to your app at launch through [advanced options](https://docs.datadoghq.com/synthetics/mobile_app_testing.md#advanced-options). Reference your global variable by typing `{{` in the field, so its current value is substituted in at runtime:

{% tab title="Android (Initial Intent Extras)" %}

```json
{
  "auth_token": "{{ MOBILE_AUTH_TOKEN }}"
}
```

{% image
   source="https://docs.dd-static.net/images/mobile_app_testing/advanced/mobile_app_advanced_android.27fd26d12d8440796686aea995a1bacd.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/mobile_app_testing/advanced/mobile_app_advanced_android.27fd26d12d8440796686aea995a1bacd.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="Mobile app test creation page, showing an example of an advanced option for an Android device." /%}

{% /tab %}

{% tab title="iOS (Process Arguments)" %}

```json
{
  "auth_token": "{{ MOBILE_AUTH_TOKEN }}"
}
```

{% image
   source="https://docs.dd-static.net/images/mobile_app_testing/advanced/mobile_app_advanced_iOS.e9adce60a121da3f09ebd5cb00963635.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/mobile_app_testing/advanced/mobile_app_advanced_iOS.e9adce60a121da3f09ebd5cb00963635.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="Mobile app test creation page, showing an example of an advanced option for an iOS device." /%}

{% /tab %}

## Step 4: Handle the token in your app{% #step-4-handle-the-token-in-your-app %}

Your app must read the injected value at startup, store it securely, and use it to skip its login flow. Gate this behavior behind a build flag so the code path only exists in your test or automation builds.

{% tab title="Android (Java)" %}

```java
if (BuildConfig.AUTOMATION) {
    String authToken = getIntent().getStringExtra("auth_token");
    if (authToken != null) {
        SecureTokenStore.getInstance(this).save(authToken);
        SessionManager.getInstance().restoreSession(authToken);
    }
}
```

Back `SecureTokenStore` with `EncryptedSharedPreferences` and a `MasterKey`, rather than storing the token in plain `SharedPreferences`.
{% /tab %}

{% tab title="iOS (Swift)" %}

```swift
#if AUTOMATION
if let index = ProcessInfo.processInfo.arguments.firstIndex(of: "-auth_token"),
   index + 1 < ProcessInfo.processInfo.arguments.count {
    let authToken = ProcessInfo.processInfo.arguments[index + 1]
    KeychainManager.shared.save(token: authToken)
    SessionManager.shared.restoreSession(with: authToken)
}
#endif
```

Store the token in the Keychain rather than `UserDefaults`, so it's protected at rest like a token your app receives from a real login.
{% /tab %}

{% tab title="React Native" %}

```javascript
import { LaunchArguments } from 'react-native-launch-arguments';
import * as Keychain from 'react-native-keychain';

if (__DEV__ || Config.AUTOMATION) {
  const { auth_token: authToken } = LaunchArguments.value();
  if (authToken) {
    await Keychain.setGenericPassword('auth_token', authToken);
    SessionManager.restoreSession(authToken);
  }
}
```

`react-native-launch-arguments` reads process arguments on iOS and intent extras on Android through one API. `react-native-keychain` stores the token in the platform Keychain or Keystore instead of `AsyncStorage`.
{% /tab %}

## Security considerations{% #security-considerations %}

Accept an injected auth token only in test or automation builds, never in production. Check a build flag before reading the argument, and make sure that flag is unset in the builds you ship to app stores.

This matters most on Android. An intent extra sent to an exported launcher `Activity` can come from any app on the device, not only Datadog's test runner. Without a build-flag check, a production app that reads and trusts `auth_token` from its launch intent lets any local app authenticate as the test account.

## Further reading{% #further-reading %}

Additional helpful documentation, links, and articles:

- [Use authentication in API and multistep API tests](https://docs.datadoghq.com/synthetics/guide/authentication-protocols.md)
- [Create a mobile application test](https://docs.datadoghq.com/synthetics/mobile_app_testing.md)
- [Create a global variable](https://docs.datadoghq.com/synthetics/platform/settings.md#global-variables)
