Skip to main content
Webhooks tell your systems that a secret changed. When someone creates, updates, or deletes a secret in a project, Krypt sends a signed HTTP POST to the URL you registered — so you can redeploy a service, invalidate a cache, or post to a team channel.
Webhook payloads contain metadata only — never secret values. A delivery tells you which key changed, in which environment, and when. It never includes the value of the secret, before or after the change. To read a value, use krypt pull or the dashboard.

Creating a webhook

Webhooks are configured per project, and only owners and admins can manage them.
1

Open the Webhooks tab

In your Krypt dashboard, open a project and select the Webhooks tab.
2

Add the endpoint

Enter a name (3–50 characters) and the URL that will receive deliveries.The URL must use https://. Private, loopback, and internal addresses are rejected — both when you save the webhook and again on every delivery.
3

Choose environment and events

Scope the webhook to development, staging, production, or all environments, then pick which of the three events it should receive.
4

Save the signing secret

On save, Krypt shows a signing secret — a 64-character hex string used to sign every delivery.It is shown once and cannot be recovered. Copy it and store it with your other secrets before closing the dialog.
If you lose the signing secret, you cannot retrieve it. Rotate it from the webhook’s menu to generate a new one — the old secret stops working immediately, so update your receiver before rotating.

Events

Three events exist: A delivery is sent only when both conditions hold: the event is in the webhook’s subscribed list, and the webhook’s environment is all or matches the environment of the changed secret.
Restoring a secret to a previous version fires secret.updated, the same as an ordinary edit. The payload does not distinguish the two.

Payload

Every secret event sends this JSON body:
These five fields are the entire payload. In particular, it does not identify who made the change — to see the actor, check the project’s activity log in the dashboard. Two headers accompany every delivery:

Test ping

The Test action on a webhook sends a ping so you can confirm your endpoint is reachable. The test payload has a different shape to a real event:
Differences from a secret event:
  • There is no key and no environment field. A receiver that assumes those are always present will break on a test ping.
  • It carries test: true and a human-readable message.
  • It ignores the webhook’s event and environment filters — a test ping is delivered even if the webhook only subscribes to secret.deleted in production.
The ping is signed exactly like a real delivery, with X-Krypt-Event: test.ping. The webhook must be active — testing a disabled webhook returns an error instead of sending.
Handle test.ping explicitly in your receiver and return 200 — that way the dashboard reports a successful test, and your event-handling logic never sees a payload without a key.

Verifying signatures

Every delivery is signed with HMAC-SHA256 using your webhook’s signing secret. The digest is computed over the raw request body and sent as:
Verify against the raw bytes of the request body, exactly as received. If you parse the JSON and re-serialise it, key order and whitespace can differ from what Krypt signed, and the signature will not match. In Express this means using express.raw() on the webhook route — not express.json().
A complete Node.js + Express receiver:
Reject any request whose signature does not match. An unverified request proves nothing about its origin.

Endpoint authentication

If your receiver needs its own credentials on top of the signature, set an auth type when creating the webhook. Krypt then adds an Authorization header to every delivery: Basic credentials are entered as username:password. Stored credentials are encrypted at rest and never returned in full by the API — reads show a masked value only. This is optional and independent of signing. The signature is always sent; endpoint auth is for receivers that additionally gate on a token.

Limitations

Current behaviour, stated plainly so you can design your receiver around it:
  • One delivery attempt, no retries. Krypt sends each event once, with a 10-second timeout. If your endpoint is down, returns a non-2xx status, or times out, the event is not retried and is lost. The failure is recorded in the project’s activity log and as the webhook’s last status, but it is never resent.
  • No delivery ID. Payloads carry no unique event identifier, so there is nothing to deduplicate on if you receive the same event twice.
  • No replay protection. There is no timestamp header and no expiry on a signature. A captured delivery remains valid indefinitely if replayed against your endpoint. The timestamp inside the body is signed — you can reject old payloads yourself by comparing it against the current time.
  • No actor. The payload does not say who made the change.
Because nothing is retried, your only record of a delivery is the dashboard: each webhook in the project’s Webhooks tab shows when it last fired and the HTTP status it returned, and the project’s activity log lists every individual success and failure. Additional constraints worth knowing:
  • Only https:// URLs are accepted; private, loopback, and internal addresses are blocked, and the URL is re-validated on every delivery.
  • Only owners and admins can create, edit, test, or delete webhooks.
  • On a Free project that is over the team-member cap, the project becomes read-only and webhooks stop firing entirely — including test pings.

Next steps