Engineering
A webhook is a claim until it is signed
When an agent finishes its work, something has to tell your systems. That message is only as trustworthy as your ability to prove where it came from.
An agent finishes a run and your system needs to know. The usual answer is a webhook: an HTTP request to an address you gave us, carrying the result. It is simple, it works with everything, and it has one awkward property - the address is, by definition, reachable from the internet. Anyone who learns it can send a request there too.
So the receiving end has a question to answer before it does anything else: did this really come from where it says it did?
What a signature buys you
Every webhook Yekar.AI delivers is signed with HMAC, using a secret that only you and the platform hold. The signature is computed over the body of the request. Your endpoint recomputes it with the same secret and compares the two.
If they match, two things are true. The request came from someone holding the secret, and the body has not been altered since it was signed. If they do not match, the request is noise, and should be dropped without being read.
This matters more for agents than for most webhook senders, because of what tends to sit downstream. A webhook that says "the invoice was approved" or "the research is done, here are the rows" usually sets something off - a write, a payment step, a message to a customer. An endpoint that accepts unsigned requests is an endpoint anyone can use to set those things off.
An unsigned webhook is a rumour with a JSON body.
Checking it properly
Signing is our half. Verifying is yours, and a few details decide whether the check is worth anything.
- Verify against the raw body. If your framework parses the JSON and you re-serialise it before checking, the bytes have changed and a valid signature will fail - at which point someone will be tempted to switch the check off.
- Compare in constant time. Every mainstream language has a function for this. A plain string comparison leaks how much of the signature was right.
- Treat the secret as a credential. It belongs in your secret store, not in the repository.
- Expect the same event more than once. Networks fail and senders retry, so sooner or later something arrives twice. Make the handler safe to run again - the same discipline that stops a retried run from charging a card twice.
The same rule in both directions
There is a symmetry here. We do not let an agent act on a system without a clear answer to who it is acting as. A webhook is the same question pointed the other way: your system should not act on a message without a clear answer to who sent it.
Neither check is sophisticated. Both are easy to leave for later, and both are much cheaper than the incident that makes later arrive.