Files
sim/apps
Waleed d643be0b93 feat(triggers): add GitLab, PagerDuty, and Zendesk webhook triggers (#5150)
* feat(triggers): add GitLab, PagerDuty, and Zendesk webhook triggers

Add webhook trigger support for three integrations that previously had
blocks but no triggers:

- GitLab: push, merge request, issue, pipeline, comment, and all-events.
  Verifies the X-Gitlab-Token secret token; filters by object_kind.
- PagerDuty: incident triggered/acknowledged/resolved/escalated/reassigned
  and all-events. Verifies X-PagerDuty-Signature (HMAC-SHA256 over raw body,
  comma-separated rotation); idempotency on event id.
- Zendesk: ticket created/status changed/comment added/priority changed and
  all-events. Verifies X-Zendesk-Webhook-Signature (base64 HMAC-SHA256 over
  timestamp+body); idempotency on event id.

Register GitLab's X-Gitlab-Event-UUID delivery header for webhook
idempotency dedup.

* fix(triggers): scope webhook secrets to owner and add Zendesk replay protection

Address review feedback:
- Add paramVisibility: 'user-only' to the webhookSecret fields for GitLab,
  PagerDuty, and Zendesk so signing secrets are scoped to the credential
  owner and not exposed to workspace collaborators (repo convention).
- Reject Zendesk deliveries whose signed timestamp is more than 5 minutes
  from now, closing a replay window once an event id ages out of the
  idempotency cache. The X-Zendesk-Webhook-Signature-Timestamp header is
  ISO-8601, so it is parsed with Date.parse (matches the Slack handler's
  skew-check convention).

* feat(triggers): auto-register GitLab, PagerDuty, and Zendesk webhooks

Replace the manual-registration model with automatic webhook creation on
deploy and cleanup on undeploy, via createSubscription/deleteSubscription
on each provider handler:

- GitLab: POST /projects/:id/hooks with a Personal Access Token; generates
  the secret token (stored for X-Gitlab-Token verification) and enables only
  the event flags for the selected trigger. Deletes the hook on undeploy.
- PagerDuty: POST /webhook_subscriptions (account-scoped) with a REST API
  key; captures delivery_method.secret (returned only on create) for
  X-PagerDuty-Signature verification. Deletes the subscription on undeploy.
- Zendesk: POST /api/v2/webhooks with native event subscriptions, then GET
  /webhooks/:id/signing_secret for X-Zendesk-Webhook-Signature verification.
  Deletes the webhook on undeploy.

Trigger config now collects the provider credentials (user-only) instead of a
pasted signing secret; the signing secret is generated or fetched and stored
in providerConfig by the orchestration layer (no route/deploy changes).

* fix(triggers): fail closed on missing webhook secret and clean up Zendesk orphans

Address review feedback on the auto-registration changes:
- verifyAuth now rejects (401) when webhookSecret is absent for GitLab,
  PagerDuty, and Zendesk. Since the secret is generated/fetched during
  auto-registration and stored before the webhook can receive deliveries, a
  missing secret indicates misconfiguration and must fail closed rather than
  skip signature verification. Adds an opt-in requireSecret flag to
  createHmacVerifier (default off, preserving behavior for other providers).
- Zendesk createSubscription now deletes the just-created webhook if the
  follow-up signing-secret fetch fails, avoiding an orphaned subscription in
  Zendesk when setup cannot complete.

* fix(triggers): clean up GitLab and PagerDuty webhooks on failed setup

Extend the orphan-prevention fix to the remaining providers. When a create
call succeeds but post-create validation fails, the created webhook is now
deleted before throwing:
- GitLab: if the create response can't be parsed for its hook id, the hook is
  located by its URL and deleted.
- PagerDuty: if the subscription response lacks an id or signing secret, the
  subscription is deleted (by id when known, otherwise located by URL).

Both cleanups are best-effort and never throw.

* docs(triggers): note GitLab tag_push only flows through the all-events trigger
2026-06-20 15:00:59 -07:00
..