Authentication.
Every webhook request is authenticated by an Access Key — the same ak_*
token your backend would use to invoke the agent directly. No webhook secrets to rotate,
no HMAC signatures.
The Access Key
An Access Key is a token prefixed with ak_. It is minted in Studio, scoped to
a single organization, and carries a set of permissions. For webhooks the relevant
permission is agents:invoke.
ak_a1b2c3d4e5f6...
Send the key on every request as a Bearer token:
Authorization: Bearer ak_<your-key>
Minting a key
From Studio
Open Organization → Access Keys, click Create key, name it, scope it, copy the token shown.
From the API
POST https://studio.olbrain.com/api/v1/organizations/<org_id>/access-keys
Authorization: Bearer <your-user-token>
Content-Type: application/json
{
"name": "webhook key — shopify production",
"permissions": ["agents:invoke"]
}
The response contains the raw key once. Store it in a secrets manager — it cannot be retrieved again.
Scope & access
A key is scoped to a single organization. It can invoke any agent in that organization
that grants the agents:invoke permission. You cannot use a key from
organization A to call an agent in organization B — requests like that come back as
404.
Revoking a key
In Studio, open Access Keys, find the key, click Revoke. The next webhook request signed with that key is rejected with 401 within about 30 seconds.
Best practices
- One key per integration. A separate key for Shopify, another for the marketing CRM, another for the ops dashboard — so you can rotate one without breaking the others.
- Name keys for humans.
webhook — shopify productionbeatskey-3. The name appears in audit logs. - Rotate on offboarding. If someone who knew a key leaves the team, revoke it and mint a new one. There is no in-place rotation.
- Never log the Bearer header. Mask it before writing request logs.