> ## Documentation Index
> Fetch the complete documentation index at: https://docs.insightsecure.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Public and private keys, HMAC signing, and how to authenticate every request

Every InsightAI tenant gets three credentials at creation time (see [SDKs & Integration](/device-intelligence/sdks#getting-your-credentials) for how to generate them). Each has a distinct purpose — using the wrong one for the wrong call is the most common integration mistake, so read this before wiring anything up.

## The three credentials

| Credential                 | Format                             | Used for                                                         | Where it's used                                         |
| -------------------------- | ---------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------- |
| **Public API key**         | `dpk_live_...` / `dpk_sandbox_...` | Identifying your tenant on dashboard/admin-facing REST calls     | `Authorization: Bearer` header                          |
| **Private HMAC secret**    | Opaque 32+ char string             | Signing every telemetry payload the SDK sends                    | SDK config, never sent over the wire itself             |
| **Webhook signing secret** | Opaque 32+ char string             | Verifying payloads InsightAI sends back to your webhook endpoint | Your webhook handler, to verify `X-InsightAI-Signature` |

<Warning>
  The **private HMAC secret** and **webhook signing secret** should never be embedded in client-side code beyond the SDK's own signing logic, and never logged. The SDK signs locally — the raw secret itself doesn't need to leave the device except inside the signature computation.
</Warning>

## Signing outbound telemetry (SDK → InsightAI)

Every telemetry payload the SDK sends is signed with HMAC-SHA256, using your private HMAC secret, over the raw JSON request body:

```
X-InsightAI-Signature: base64(HMAC-SHA256(raw_request_body, hmac_secret))
```

Your SDK config handles this automatically — you only need to supply the secret:

```kotlin theme={null}
InsightAiConfig(
    tenantId = "your_tenant_id",
    hmacSecretKey = "your_private_hmac_secret",
    // ...
)
```

If you're calling the ingest API directly (outside an SDK, e.g. from a server-side integration), sign it yourself:

<CodeGroup>
  ```python Python theme={null}
  import hmac, hashlib, base64, json

  body = json.dumps(payload, separators=(",", ":")).encode()
  signature = base64.b64encode(
      hmac.new(hmac_secret.encode(), body, hashlib.sha256).digest()
  ).decode()

  headers = {
      "Content-Type": "application/json",
      "X-InsightAI-Signature": signature,
  }
  ```

  ```javascript Node.js theme={null}
  const crypto = require('crypto');

  const body = JSON.stringify(payload);
  const signature = crypto
    .createHmac('sha256', hmacSecret)
    .update(body)
    .digest('base64');

  const headers = {
    'Content-Type': 'application/json',
    'X-InsightAI-Signature': signature,
  };
  ```
</CodeGroup>

## Verifying inbound webhooks (InsightAI → your backend)

When InsightAI delivers a `risk.alert` event to your configured webhook URL (see [Webhooks & Payload Reference](/api-reference/webhooks-and-payload)), verify the signature **before** processing the payload — never act on an unverified webhook body.

```python theme={null}
import hmac, hashlib, base64

def verify_webhook(raw_body: bytes, signature_header: str, webhook_secret: str) -> bool:
    expected = base64.b64encode(
        hmac.new(webhook_secret.encode(), raw_body, hashlib.sha256).digest()
    ).decode()
    # Constant-time comparison — never use `==` for signature checks
    return hmac.compare_digest(expected, signature_header)
```

<Tip>
  Compute the signature over the **raw, unparsed** request body — not a re-serialized version of the parsed JSON. Re-serializing can change key ordering or whitespace and produce a signature mismatch even for a genuinely valid payload.
</Tip>

## REST API calls (dashboard/admin endpoints)

Use your public API key as a bearer token:

```bash theme={null}
curl https://api.insightsecure.ai/v1/di/alerts \
  -H "Authorization: Bearer dpk_live_..."
```

## Key rotation

Both the HMAC secret and webhook signing secret can be rotated from the DI Dashboard under **Admin → Integrations → \[your tenant] → Rotate keys**. Rotating invalidates the old secret immediately — coordinate a deploy so your SDK config and webhook verification update together, since there's no overlap window where both old and new secrets are valid simultaneously.
