All Products
Search
Document Center

Web Application Firewall:Integrate the app protection SDK for Android

Last Updated:Sep 23, 2026

To enable app protection for your Android apps, integrate the Anti-Bot SDK (referred to as SDK in this topic) before activating the feature.

Limitations

Android API level 16 or later is required. If your app targets an earlier API level, the SDK will not work as expected.

Prerequisites

Before you begin, make sure you have:

  • App protection purchased and enabled. See Procedure to enable app protection.

  • The SDK package (AAR file) for Android. Contact technical support in the DingTalk service group, or submit a ticket to request it. The file is named AliTigerTally_X.Y.Z.aar, where X.Y.Z is the version number.

  • The app key (SDK authentication key). To get it, log on to the WAF console, choose Protection Config > Website Protection, go to the Bot Management tab, turn on App Protection, and click Obtain and Copy Appkey.

Each Alibaba Cloud account has one unique app key that works for all domain names in your Web Application Firewall (WAF) instance, and for both Android and iOS apps. Example app key:
****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****

How it works

The SDK signs each outgoing request from your app. WAF verifies these signatures server-side to detect and block malicious traffic, then forwards legitimate requests to your origin server.

(Optional) Create a test Android project

If you want to practice the integration steps before applying them to your production app, create a test project in Android Studio first.

The following figure shows a sample test project named TigerTally_sdk_test.

Run the test project to verify it works before proceeding.

Integrate the SDK

Step 1: Open the project in Android Studio

Open your project in Android Studio and navigate to the project's file directory.

Step 2: Add the AAR dependency

  1. Copy AliTigerTally.aar into the libs directory of your project. You can also drag the file directly into the directory.

  2. Open build.gradle and add the following configurations:

    • Declare libs as a local repository:

      repositories {
          flatDir {
              dirs 'libs'
          }
      }
    • Add a compile dependency:

      dependencies {
          compile(name: 'AliTigerTally_X.Y.Z', ext: 'aar')
      }
      Important: Replace X.Y.Z with the actual version number from the AAR filename you downloaded.
  3. Click Sync Now to apply the changes.

  4. If you use ProGuard to obfuscate your app, add the following rule to your ProGuard configuration file immediately after adding the dependency. This prevents SDK classes from being stripped at build time, which would cause runtime failures.

    -keep class com.aliyun.TigerTally.* {*;}

Step 3: Configure native library filters (if needed)

Skip this step if your project already includes an SO file. Otherwise, add the following ndk block to build.gradle:

android {
    defaultConfig {
        ndk {
            abiFilters 'arm64-v8a', 'x86', 'armeabi-v7a'
            //abiFilters "armeabi-v7a"
        }
    }
}

Step 4: Apply for permissions

Add the following permissions to your AndroidManifest.xml. Only INTERNET is required for the SDK to function.

Permission Required Runtime request (Android 6.0+) Description
android.permission.INTERNET Yes No — automatically granted at install Allows the SDK to send signed requests to WAF.
android.permission.ACCESS_NETWORK_STATE No No — automatically granted at install Reads the device network status for enhanced risk signals.
android.permission.ACCESS_WIFI_STATE No No — automatically granted at install Reads the Wi-Fi connection status for enhanced risk signals.
android.permission.READ_PHONE_STATE No Yes — must request at runtime Reads device identity for enhanced risk signals.
android.permission.BLUETOOTH No No — automatically granted at install Reads Bluetooth device information for enhanced risk signals.
android.permission.READ_EXTERNAL_STORAGE No Yes — must request at runtime Reads external storage for enhanced risk signals.
android.permission.CHANGE_NETWORK_STATE No No — automatically granted at install Modifies network connectivity state for enhanced risk signals.

Step 5: Add the integration code

5a. (Optional) Set the user ID

Call setAccount() to associate a user ID with SDK requests. This helps WAF apply user-level protection policies. Skip this call if the user is not logged in — call init() directly instead.

// Signature: int setAccount(String account)
// Returns: 0 on success, -1 on failure

final String account = "account"; // Use a masked user ID
TigerTallyAPI.setAccount(account);
Parameter Type Description
account String The user ID. Use a masked value to protect user privacy.

5b. Initialize the SDK

Call init() once when your app starts. This performs a one-time collection of device information used for risk analysis.

Two collection modes are available:

  • `DEFAULT`: Collects all device data, including sensitive fields (imei, imsi, simSerial, wifiMac, wifiList, bluetoothMac). Requires the corresponding permissions. Use this mode after the user has accepted the app's privacy policy.

  • `NOT_GRANTED`: Skips sensitive fields. Use this mode before the user has accepted the privacy policy.

// Signature: int init(Context context, String appkey, int type)
// Returns: 0 on success, -1 on failure

final String appkey = "your_appkey";

// Full data collection (after user accepts privacy policy)
int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, TigerTallyAPI.CollectType.DEFAULT);

// Exclude sensitive fields (before user accepts privacy policy)
int ret = TigerTallyAPI.init(this.getApplicationContext(), appkey, TigerTallyAPI.CollectType.NOT_GRANTED);

Log.d("AliSDK", "ret:" + ret);
Parameter Type Description
context Context The application context.
appkey String The app key obtained from the WAF console.
type CollectType Data collection mode: DEFAULT or NOT_GRANTED.

5c. Sign the request

Call vmpSign() before each outgoing HTTP request. Pass the request body as a byte array; for GET requests or empty POST bodies, pass null or "".getBytes("UTF-8").

// Signature: String vmpSign(int signType, byte[] input)
// Returns: the wToken signature string

String request_body = "i am the request body, encrypted or not!";
String wToken = null;
try {
    wToken = TigerTallyAPI.vmpSign(1, request_body.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
Log.d("AliSDK", "wToken:" + wToken);
Parameter Type Description
signType int Signature algorithm. Set to 1 to use the default algorithm.
input byte[] The request body to sign. Pass null or an empty byte array for GET or empty POST requests.

5d. Add the signature to the HTTP header

Set the wToken value as an HTTP header property before sending the request. The following example uses HttpURLConnection:

String request_body = "i am the request body, encrypted or not!";
new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            URL url = new URL("https://www.aliyundoc.com");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(5000);
            conn.setRequestMethod("POST");
            // Add the wToken signature to the request header
            conn.setRequestProperty("wToken", wToken);
            OutputStream os = conn.getOutputStream();
            // Write the request body
            byte[] requestBody = request_body.getBytes("UTF-8");
            os.write(requestBody);
            os.flush();
            os.close();
            int code = conn.getResponseCode();
            Log.d("respCode", Integer.toString(code));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

What happens after integration

Once integrated, for every outbound request your app sends:

  1. vmpSign() generates a wToken signature from the request body.

  2. Your code attaches wToken as an HTTP header.

  3. WAF inspects the wToken header, blocks requests that fail signature verification, and forwards valid requests to your origin server.

What's next