> For the complete documentation index, see [llms.txt](https://sentinel.rexiox.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sentinel.rexiox.co/attestation/server-side-integration.md).

# Server-Side Integration

### 1. Nonce Generation Endpoint

Before initiating the attestation process on the client side, the client must request a short-lived cryptographically secure token (Nonce) from the server to prevent replay attacks.

`GET` `/api/v1/attestation/nonce`

* Purpose: Generates a single-use, unpredictable value and stores it temporarily on the backend.

### 2. Data Models

The raw data structure sent by the client to your server and the decrypted object models are defined below.

#### 2.1. Encrypted Request Model (Incoming Server Payload)

The client encrypts the prepared package using hybrid encryption - both asymmetric ([RSA](/attestation/cryptography.md)) and symmetric ([AES](/attestation/cryptography.md#aes-properties)) - and sends it to your server's `/api/v1/attestation/verify` endpoint via a `POST` request.

```kotlin
@Serializable
data class EncryptedAttestation(
    val encryptedKey: String,  // Base64-encoded one-time AES key, encrypted with the server's RSA Public Key
    val encryptedData: String, // Base64-encoded core payload data, encrypted with the AES key
    val iv: String             // Base64-encoded Initialization Vector (IV) used in the AES encryption
)
```

#### 2.2. Decrypted Data Model (Payload)

Once the `EncryptedAttestation` is successfully decrypted, this is the main object model you will obtain to execute your core validation logic:

```kotlin
@Serializable
data class AttestationPayload(
    val nonce: String,                      // A unique, single-use token generated by the server
    val attestationToken: String,           // The attestation token from Play Integrity (Android) or App Attest (iOS)
    val securityReport: SecurityReportDto   // Sentinel device security analysis report
    val platform: String,                   // operating system indicator: "android" or "iOS"
    val timestamp: Long                     // The epoch timestamp (ms) when the request was created on the client side
)
```

#### 2.3. Sentinel Security Report Details (SecurityReport)

This report contains the real-time security status of the device, root/jailbreak detection flags, and specific threats detected:

```kotlin
@Serializable
data class SecurityReport(
    val severity: Int,              // Total risk weight score (e.g., 90, 120, 330)
    val riskLevel: String,          // Categorized risk level (e.g., "SAFE", "LOW", "MEDIUM", "HIGH")
    val isCompromised: Boolean,     // Indicates if the device is rooted/jailbroken or if system integrity is breached
    val isTampered: Boolean,        // Indicates if the application package or its signature has been modified
    val isHooked: Boolean,          // Indicates active runtime manipulation (e.g., Frida, Xposed)
    val isVirtualDevice: Boolean,   // Indicates if the app is running on an emulator or simulator
    val isDebugged: Boolean,        // Indicates if a debugger is attached to the application
    val isMockLocation: Boolean,    // Indicates if mock or spoofed location providers are active
    val threats: List<String>,      // A list of class names representing the specific violations detected
    val timestamp: Long             // The generation timestamp of the report
)
```

### 3. Server-Side Processing Pipeline

When the server receives an attestation request (e.g., `POST /api/v1/attestation/verify`), it must execute the following operations in sequence:

#### Step 1: Hybrid Decryption

1. Decrypt the AES Key (RSA): Decrypt the incoming `EncryptedAttestation.encryptedKey` using your server's securely stored RSA Private Key to retrieve the raw symmetric AES key.
2. Decrypt the Payload (AES): Decrypt the `EncryptedAttestation.encryptedData` using the extracted AES key along with the provided `EncryptedAttestation.iv`.
3. Deserialization: Convert the resulting decrypted plaintext string (which is in JSON format) into the `AttestationPayload` object.

{% hint style="info" icon="toolbox" %}
**Tip for Testing & Debugging:** While implementing and testing your server-side validation, you can use the following trusted online tools to manually decode, decrypt, and inspect your payloads:

* [RSA Key Generator](https://emn178.github.io/online-tools/rsa/key-generator/)
* [RSA Encryption](https://emn178.github.io/online-tools/rsa/encrypt/)
* [RSA Decryption](https://emn178.github.io/online-tools/rsa/decrypt/)
* [AES Encryption](https://emn178.github.io/online-tools/aes/encrypt/)
* [AES Decryption](https://emn178.github.io/online-tools/aes/decrypt/)
* [CBOR Playground](https://hildjj.github.io/cbor2/playground/)
  {% endhint %}

#### Step 2: Nonce and Expiration Validation (Replay Attack Protection)

1. Nonce Verification: Look up the `payload.nonce` in your database or cache layer (e.g., Redis).
   * If the nonce does not exist or has already been marked as used, reject the request immediately.
   * If the nonce is valid, delete it from your system immediately to prevent any subsequent reuse.
2. Timestamp Expiration Check: Compare the server's current time with `payload.timestamp`. Reject any requests that exceed your configured threshold (e.g., older than 5 minutes) to protect against time-lagged replay attacks.

#### Step 3: Attest Provider Platform Verification

Execute secondary platform-specific validation based on the `payload.platform` flag:

* **`android`**: Forward the `payload.attestationToken` to the [official Google Play Integrity API](https://developer.android.com/google/play/integrity/standard?hl=tr#decrypt-and) servers for remote validation. Verify that the `packageName` returned by Google matches your application's unique identifier.
* **`iOS`**: Validate the `payload.attestationToken` on your backend according to Apple's native [App Attest Validation guidelines](https://developer.apple.com/documentation/devicecheck/validating-apps-that-connect-to-your-server).

#### Step 4: Sentinel Security Policy Evaluation

Enforce your specific business rules based on the telemetry inside `payload.securityReport`. You can implement flexible mitigation policies:

* Strict Policy (Full Block): If `isCompromised`, `isTampered`, or `isHooked` is `true`, or if the `riskLevel` is evaluated as `"HIGH"`, return an error response to the client and block the user from proceeding with critical transactions (e.g., money transfers, login attempts).
* Monitoring / Restricted Mode: If lighter flags like `isVirtualDevice` or `isDebugged` are triggered, you may choose to log the event or flag the user profile for review rather than terminating the session entirely.

Once all layers of validation (Decryption, Nonce lifecycle, Apple/Google ecosystem verification, and the Sentinel report) pass successfully, return a successful response (`HTTP 200 OK`) to the client.

{% hint style="info" %}
Backend Developer Note: The `threats` list contains specific technical categories of the violations caught on the client side (e.g., `Root`, `Tamper`, `Hook`). We highly recommend passing this array directly into your logging or SIEM infrastructure to analyze real-time attack trends from your backend dashboard.
{% endhint %}
