concepts / security
Security
Kite verifies every inbound webhook at the relay edge before it reaches your listener. Unverified or tampered payloads are rejected. Your local app only sees events that have passed cryptographic signature checks.
Signature verification
Each provider signs its webhook payload with a shared HMAC secret. Kite verifies this signature on receipt using the secret you configured. The raw payload is never forwarded until verification passes.
If verification fails, Kite returns 401 Unauthorized to the provider and logs the attempt. Your listener sees nothing.
Supported providers
| Provider | Signature header | Algorithm | Replay guard |
|---|---|---|---|
| Stripe | Stripe-Signature | HMAC-SHA256 | ✓ timestamp |
| GitHub | X-Hub-Signature-256 | HMAC-SHA256 | id dedup |
| Slack | X-Slack-Signature | HMAC-SHA256 | ✓ timestamp |
| Linear | Linear-Signature | HMAC-SHA256 | id dedup |
| Shopify | X-Shopify-Hmac-Sha256 | HMAC-SHA256 | id dedup |
| Twilio | X-Twilio-Signature | HMAC-SHA1 | id dedup |
| PagerDuty | X-PagerDuty-Signature | HMAC-SHA256 | ✓ timestamp |
Replay protection
For providers that include a timestamp in the signed payload (Stripe, Slack, PagerDuty), Kite rejects any event where the timestamp is more than 5 minutes old. This prevents attackers from replaying captured requests.
For providers without timestamp signing (GitHub, Linear, Shopify), Kite deduplicates by CloudEvent id within a 24-hour rolling window. Duplicate events are silently dropped.
Secrets management
Webhook signing secrets are stored encrypted at rest using AES-256-GCM. They are never logged or included in any API response. You can rotate a secret without downtime:
$ kite sources update my-stripe \
--secret $NEW_STRIPE_WEBHOOK_SECRETKite accepts both the old and new secret during a configurable overlap window (default: 10 minutes) so you can update the provider secret without dropping events.
Transport security
All traffic between the provider and the Kite relay uses TLS 1.2+. The WebSocket connection between the relay and the CLI uses TLS with certificate pinning. Events in transit are never stored unencrypted.
Summary:
- Provider → relay: HTTPS (TLS 1.2+), HMAC verified
- Relay → CLI: WebSocket over TLS, cert-pinned
- CLI → local sink: plain HTTP (local loopback only)
- Secrets at rest: AES-256-GCM
Unverified sources
Custom HTTP sources without a signing secret are still accepted and delivered, but are flagged in the CloudEvent extensions:
{
"kite-verified": "false",
"kite-source": "http"
}Your handler can inspect kite-verified and reject or downgrade untrusted events according to your own policy.
Next: Manifest
Combine sources, sinks, and security config into a single declarative kite.json manifest.