> ## 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 verification – language examples

> Sample code to validate X-Kairo-Signature in PHP, Python, Node.js, and Java

Kairo Shield sends the signature in `X-Kairo-Signature` as `sha256={hex}`. Compute HMAC-SHA256 of the raw body (UTF-8) with your webhook secret and compare the hex **without** the prefix.

**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("utf-8"),
        raw_body,
        hashlib.sha256,
    ).hexdigest()
    received = signature_header.removeprefix("sha256=")
    return hmac.compare_digest(expected, received)
```

**Node.js**

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

function verifyKairoSignature(rawBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody, 'utf8')
    .digest('hex');
  const received = signatureHeader.replace(/^sha256=/, '');
  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(received, 'hex')
  );
}
```

**PHP**

```php theme={null}
function verifyKairoSignature(string $rawBody, string $signatureHeader, string $secret): bool {
    $expected = hash_hmac('sha256', $rawBody, $secret, false);
    $received = str_starts_with($signatureHeader, 'sha256=')
        ? substr($signatureHeader, 7)
        : $signatureHeader;
    return hash_equals($expected, $received);
}
```

**Java**

```java theme={null}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public static boolean verifyKairoSignature(
        byte[] rawBody, String signatureHeader, String secret) throws Exception {
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
    byte[] hash = mac.doFinal(rawBody);
    StringBuilder sb = new StringBuilder();
    for (byte b : hash) sb.append(String.format("%02x", b));
    String received = signatureHeader.startsWith("sha256=")
        ? signatureHeader.substring(7) : signatureHeader;
    return MessageDigest.isEqual(sb.toString().getBytes(), received.getBytes());
}
```

After validating the signature, process the JSON according to `X-Kairo-Event` or the payload `event` field.


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