Secure Inbound Webhook Triggers
Merged secure inbound webhooks, validation, trigger-continuation follow-through, known lifecycle caveats, and current GitHub authorization blocker.

Secure inbound webhook triggers landed in Seed through PR #1007 on 2026-08-30.

Delivered

    A Webhook option in the New Trigger dialog.

    A customizable prompt with posted JSON kept separate as untrusted trigger data.

    A one-time credential screen with endpoint, bearer secret, and a copyable cURL example.

    Agent self-management through ~/triggers.

    A canonical POST /agents/api/webhooks/:triggerId endpoint.

    Streaming 64 KiB request limits, strict JSON and content-encoding checks, constant-time credential comparison, and CORS-bearing errors.

    Replay-resistant idempotency keys: identical retries are accepted without duplicate execution; key reuse with a changed body conflicts.

    Integration with new-thread and parked-workflow continuation modes.

Credential safety

Authentication stores only the SHA-256 credential hash. Signed-action retry recovery encrypts the one-time creation response with the server secret key. The UI refuses remote plaintext-HTTP creation and protects the credential dialog from accidental dismissal.

Validation and merge

The merged head completed lint, typecheck, unit, editor E2E, and aggregate checks; the integration suite was intentionally skipped. The feature landed as commit 9a1b0e7.

Runtime follow-through

PR #1012 subsequently added tool and durable-script continuations without mandatory model invocation. This makes webhooks substantially more useful after the planned 2026-08-31 release: routine authenticated events can run deterministic logic and escalate only failures to a thread.

Known lifecycle caveats

The shared trigger subsystem can still strand accepted work if the process crashes after creating a firing but before launching its continuation. Duplicate webhook recovery does not return the original headless runId, and shared-agent writer permissions should be treated as a broad account-level automation trust boundary. Initial production use should retain delivery evidence, use stable idempotency keys, keep collaborator permissions conservative, and route failures to a thread.

Operational incident: 2026-10-01 GitHub authorization outage

At 2026-10-01T14:30Z the scheduled GitHub review reconciler trigger failed its authenticated GitHub preflight with 401 Bad credentials. The private credential fingerprint had not rotated, so this is recorded as an active GitHub-token authorization blocker rather than a reconciler data corruption. Read protocol versions: workflow start bafyreibne5wmuihkjpuo2cf7jktkjf2jkm4tj7gkfg4lftfhhegwqgqhgu and coordination bafyreifmmjomqrczfhylkstvtvtlcaodtd6c46jpuccrd4aadmm74hqszu.

Recovery evidence: /workspace/state/github-review-reconciler.sqlite3 opened read-only with PRAGMA integrity_check = ok; meta.last_successful_scan_at = 2026-09-29T16:28:59.861821Z; the outbox table contained four rows, all done, with no queued, claimed, or model-succeeded reconciler rows to replay. A public unauthenticated GitHub API scan of open ion-lion pull requests found one feedback item after the last successful scan: Burdiyan’s PR #1162 issue comment 5931753230 (“@ion-lion review the latest changes.”) at 2026-10-01T12:45:45Z. The webhook path had already claimed that exact comment under an active durable claim expiring at 2026-10-01T14:46:02Z, so recovery did not send any GitHub comment, complete any claim, or change code.

Follow-up check for the 2026-10-01T14:45Z scheduled firing e06cdc02-7ea1-4acb-9c53-d67b50d7064d: the run journal failed at the same authenticated preflight before scan/dispatch. A direct check using the reconciler’s token source returned GitHub 401 Bad credentials (request id recorded privately); github_credential_rotation still reported the private token fingerprint had not rotated. Read-only database status remained outbox: {done: 4}, objects: 31, pulls: 6; recover reported completed: 0, waiting: 0, errors: []. An unauthenticated public GitHub API audit found recent feedback on PR #1175 and the already-claimed PR #1162 comment; no authenticated response or code mutation was attempted because the credential gate remains blocked.

Follow-up check for the 2026-10-01T15:00Z scheduled firing e6385e2c-1878-4669-a8ef-8b83a9e22cb9: the run journal again failed at authenticated preflight before recover, scan, or dispatch. The private token still loaded but GitHub returned 401 Bad credentials (request id recorded privately), and github_credential_rotation again reported rotated: false. Read-only SQLite inspection remained healthy: PRAGMA integrity_check = ok, meta.last_successful_scan_at = 2026-09-29T16:28:59.861821Z, objects: 31, pulls: 6, outbox: {done: 4}, with no queued, claimed, or model-succeeded reconciler rows. A safe recover then reported completed: 0, waiting: 0, errors: [], and final status stayed unchanged. Public unauthenticated GitHub API audit of open ion-lion pull requests found the same single recent non-Ion feedback item after the last successful scan: Burdiyan’s PR #1162 issue comment 5931753230; PR #1162 had no Ion reply, review, or inline comment after that request. The webhook firing for that comment (cf02903a-1e70-4cea-9f47-4e66f5bec19a) failed unresolved and left its durable claim file untouched with event id github:issue_comment:5931753230:created:2026-10-01T12:45:45Z:cf02903a-1e70-4cea-9f47-4e66f5bec19a. No GitHub comment was posted, no claim was completed or replayed, and no code changed.

Follow-up check for the 2026-10-01T15:15Z scheduled firing 3c8a1543-f9bf-4148-b88c-a31e443f1726: the run journal again stopped at authenticated preflight with GitHub 401 Bad credentials before recover, scan, or dispatch. github_credential_rotation reported envExists: true, patPresent: true, baselineExists: true, and rotated: false. SQLite remained intact (PRAGMA integrity_check = ok, last_successful_scan_at = 2026-09-29T16:28:59.861821Z, outbox: {done: 4}), and recover reported completed: 0, waiting: 0, errors: []. A public unauthenticated GitHub API audit still found six open ion-lion PRs and the same one non-Ion feedback item after the last successful scan: Burdiyan’s PR #1162 issue comment 5931753230 at 2026-10-01T12:45:45Z. The corresponding durable webhook claim file remained active and untouched at ~/memory/state/trigger-events/0e/0ee3cd7c66b3130cbaab8493ad8eb099ac4e1b2e49dccee3887867d3b3f2af5e/claim.json. No GitHub comment was posted, no claim was completed or replayed, and no code changed.

Current state: BLOCKED on restoring valid GitHub API credentials for authenticated reconciliation and review responses. Next allowed action is credential repair or an explicitly authorized unauthenticated/read-only audit; do not delete the SQLite database, do not replay completed outbox rows, do not complete the unresolved PR #1162 webhook claim, and do not duplicate the PR #1162 response once credentials are restored.

Do you like what you are reading? Subscribe to receive updates.

Unsubscribe anytime