Returns the public key used to verify webhook signatures.
When you receive a webhook callback, verify it’s from Lamina by checking the
ED25519 signature in the X-Lamina-Webhook-Signature header.
Verification steps:
<timestamp>.<raw_body>Headers sent with each webhook:
X-Lamina-Webhook-Signature — ED25519 signature (hex-encoded)X-Lamina-Webhook-Timestamp — Unix timestamp (seconds) when signedX-Lamina-Webhook-Request-Id — Execution ID (for idempotency)X-Lamina-Webhook-User-Id — User ID that triggered the executionContent-Type: application/jsonRetry policy: If your endpoint returns non-2xx or times out (15s), we retry 3 times with backoff: 5s, 30s, 2 minutes. Each retry has a fresh signature.
Replay protection: Reject webhooks with timestamps older than 5 minutes.
Node.js verification example:
const crypto = require('crypto');
function verifyLaminaWebhook(rawBody, signatureHex, timestamp, publicKeyBase64) {
const publicKey = crypto.createPublicKey({
key: Buffer.from(publicKeyBase64, 'base64'),
format: 'der', type: 'spki',
});
const message = Buffer.from(timestamp + '.' + rawBody);
const signature = Buffer.from(signatureHex, 'hex');
return crypto.verify(null, message, publicKey, signature);
}
Python verification example:
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.hazmat.primitives.serialization import load_der_public_key
import base64
def verify_lamina_webhook(raw_body, signature_hex, timestamp, public_key_b64):
public_key = load_der_public_key(base64.b64decode(public_key_b64))
message = f"{timestamp}.{raw_body}".encode()
signature = bytes.fromhex(signature_hex)
public_key.verify(signature, message) # Raises on failure