Repository navigation
feat: HMAC-signed ingest completion webhooks (#14) - #42
Conversation
Optional callback_url on POST /v1/ingestions fires a signed POST when a batch worker job reaches a terminal state. HMAC-SHA256 uses a per-key whsec_ secret (or WEBHOOK_SECRET). Delivery is fail-open with retries. References #14 Co-authored-by: Leonardo <leo-aa88@users.noreply.github.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Code review — PR #42 (issue #14)must-fixNone HMAC-SHA256 is over the raw JSON body with should-fix
nice-to-have
Verdictmust-fix count: 0 |
Persist done/failed with db.commit() before outbound HTTP so pollers see terminal status and a crash during retries cannot re-claim the job. References #14 Co-authored-by: Leonardo <leo-aa88@users.noreply.github.com>
Code review — PR #42 (issue #14), round 2Previous should-fix status
must-fixNone should-fixNone nice-to-haveNone Verdictmust-fix count: 0 |
Closes #14.
Optional
callback_urlonPOST /v1/ingestionsso consumers get a signed terminal-state POST instead of only polling.When it fires
After a batch worker job is marked
doneorfailed. Payloadstatusissucceeded,partial(done witherror_count > 0), orfailed.job_idis the ingestion job id when present. Tail jobs and syncPOST /v1/ingestions/linesdo not send callbacks.Webhook failures are logged and do not change ingest status. Polling still works.
Signing
HMAC-SHA256 over the raw JSON body. Header:
The signature is not inside the JSON. Per-key
whsec_…is generated atraglogs keys createand stored onapi_keys.webhook_secret(Alembic0006). Delivery loads it viaapi_key_idin the worker payload. Fallback isWEBHOOK_SECRETwhen auth is off, OIDC, or the key has a null secret. The API bearer token is never used for HMAC.Retries: jittered exponential backoff (
WEBHOOK_MAX_RETRIES,WEBHOOK_TIMEOUT). 5xx and connect errors retry; other 4xx do not.Tests
Unit tests cover HMAC verify/tamper, URL scheme checks, mocked httpx retry counts, fail-open after exhausted retries, and worker invocation on done/failed.