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

# Signature validation

> Verify X-Kairo-Signature with HMAC-SHA256

Kairo Shield signs each delivery with **HMAC-SHA256** of the **raw body** (compact JSON, UTF-8).

## Signature header

```
X-Kairo-Signature: sha256=a1b2c3d4e5f6...
```

The value includes the `sha256=` prefix followed by the hexadecimal digest.

## Verification steps

1. Read the body **without parsing** (raw bytes/string).
2. Compute `HMAC-SHA256(body, secret)` in hexadecimal.
3. Compare with the header value **without** the `sha256=` prefix.
4. Use constant-time comparison (`hmac.compare_digest`, `hash_equals`, `timingSafeEqual`).
5. If mismatch, return **401 Unauthorized** and do not process the payload.

> [!WARNING]
>
> Do not use the JSON-parsed body from your framework to compute the signature. Any whitespace or key order change will invalidate verification.

## Conceptual example (Python)

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

def verify_kairo_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    received = signature_header.removeprefix("sha256=")
    return hmac.compare_digest(expected, received)
```

See [Language examples](/docs/shield/webhooks/signature-verification) for PHP, Node.js, and Java.

## Idempotency

Use `X-Kairo-Delivery` as a deduplication key. Kairo Shield may retry failed deliveries.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.