> ## Documentation Index
> Fetch the complete documentation index at: https://evalgate.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Web Bot Auth signing

> Operate EvalGate's public signing directory and signed outgoing webhooks.

EvalGate can identify its outgoing webhooks using Ed25519 HTTP Message
Signatures. This is an additional sender-identity proof: the existing
`X-Webhook-Signature` HMAC, destination checks, redaction and delivery authority
remain in place. It does not authenticate incoming agents, issue API credentials
or bypass a webhook recipient's authorization.

The implementation follows the September 2026
[IETF Web Bot Auth working-group draft](https://datatracker.ietf.org/doc/html/draft-ietf-webbotauth-httpsig-protocol-00).
It uses the dictionary form of `Signature-Agent`. Cloudflare's separately
documented legacy integration and verified-bot registration are not claimed.

## Publish before activating

These commands are for an operator in the application repository with Node 24
and an installed Vercel CLI. The checkout must already be linked through
`.vercel/project.json`; each command requires its explicit project ID and either
`production` or `preview`. Production and Preview use independent keyrings.

```bash theme={null}
node scripts/web-bot-auth-keyring.mjs init --project prj_YOUR_PROJECT --target production --origin https://www.evalgate.com
node scripts/web-bot-auth-keyring.mjs status --project prj_YOUR_PROJECT --target production
node scripts/web-bot-auth-keyring.mjs install --project prj_YOUR_PROJECT --target production
```

`init` creates an independent Ed25519 key with a maximum 90-day lifetime in an
owner-only file beneath `.evalgate-runtime/web-bot-auth/`. It starts with
`activateAt: null`: the key can prove possession in the public directory but
cannot sign outgoing requests. Status output includes public fingerprints and
lifecycle state only. Never print, commit, attach or paste the private keyring.
Authority-changing operations hold an exclusive per-keyring lock. A stale lock
is never cleared automatically; verify that its recorded process has stopped
before removing that exact lock file and retrying.

`install` verifies the linked project and team, inspects the explicit project,
and supplies both environment values through protected stdin using sensitive
Vercel variables. It captures and discards provider output. It never deploys or
promotes anything. Use `--vercel-cli /path/to/vercel/dist/index.js` when the
installed CLI is elsewhere. Production requires its explicit HTTPS origin;
when the Preview origin variable is unset, the server derives its own
`https://<VERCEL_URL>` origin.

The environment update must reach the deployment that serves
`/.well-known/http-message-signatures-directory` before activation. Environment
installation alone is not publication. The endpoint returns a public JWKS with
one possession signature per key, RFC 7638 fingerprints and `nbf`/`exp` bounds.
No configured keyring, or no valid published key, produces an unavailable
response rather than an invented identity.

Once the intended HTTPS origin serves that directory, select the public `kid`
reported by `status`:

```bash theme={null}
node scripts/web-bot-auth-keyring.mjs activate --project prj_YOUR_PROJECT --target production --kid PUBLIC_FINGERPRINT
node scripts/web-bot-auth-keyring.mjs install --project prj_YOUR_PROJECT --target production
```

`activate` fetches the exact canonical directory without following redirects.
It verifies the body digest, expected public key, fresh signature and origin
binding before scheduling activation ten minutes later. It changes only the
local protected keyring. Install the updated schedule and roll it out through
the normal reviewed deployment process. Protected or unavailable deployment
URLs cannot pass publication verification.

During initial pending setup, established HMAC-authenticated webhooks continue
without the extra Web Bot Auth headers. After activation, requests bind the
HTTP method, exact target, final redacted body digest and sender identity, with
a unique nonce and at most 60 seconds of signature validity. An expired or
revoked previously active configuration fails closed; it never silently falls
back to an unsigned sender identity.

## Rotate or revoke

```bash theme={null}
node scripts/web-bot-auth-keyring.mjs rotate --project prj_YOUR_PROJECT --target production
node scripts/web-bot-auth-keyring.mjs install --project prj_YOUR_PROJECT --target production
```

Rotation adds a separate pending key. Publish it, run `activate` for its new
fingerprint, then install and roll out the schedule. The previous active key
stays available through activation plus 120 seconds, covering the 30-second
directory cache and 60-second request signatures. The keyring holds at most
three entries; expired or revoked history is pruned only when doing so cannot
turn a failed active signer into pending-only setup.

```bash theme={null}
node scripts/web-bot-auth-keyring.mjs revoke --project prj_YOUR_PROJECT --target production --kid PUBLIC_FINGERPRINT
node scripts/web-bot-auth-keyring.mjs install --project prj_YOUR_PROJECT --target production
```

Revocation removes the selected private PEM locally and retains a non-authority
tombstone so the runtime cannot downgrade a previously active signer. Install
and roll out that revocation to every webhook worker and web deployment using
the identity. Verifiers can retain already fetched public keys until their
bounded caches and signature lifetimes expire. Revoking the final valid key
makes the directory unavailable and blocks additional Web Bot Auth signing.

Local protocol tests and environment installation do not establish deployed
acceptance. Verify the actual directory and an actual authorized webhook at
the intended deployment before describing signing as operational there.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.