Skip to content

Support webhook integrations#5039

Merged
Json-Andriopoulos merged 18 commits into
feature/webhook-triggersfrom
feature/webhook-integrations
Jul 21, 2026
Merged

Support webhook integrations#5039
Json-Andriopoulos merged 18 commits into
feature/webhook-triggersfrom
feature/webhook-integrations

Conversation

@Json-Andriopoulos

@Json-Andriopoulos Json-Andriopoulos commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Describe changes

Introduces a new project-level component called webhook-integrations. Users can use the feature to create an integration point within ZenMl for events on extternal platforms (like Github).

The PR focuses on getting CRUD functionality in place (CLI, SDK, Rest, SQL). Integration with trigger code is out of scope and will be a follow-up branch.

Pre-requisites

Please ensure you have done the following:

  • I have read the CONTRIBUTING.md document.
  • I have added tests to cover my changes.
  • I have based my new branch on develop and the open PR is targeting develop. If your branch wasn't based on develop read Contribution guide on rebasing branch to develop.
  • IMPORTANT: I made sure that my changes are reflected properly in the following resources:
    • ZenML Docs
    • Dashboard: Needs to be communicated to the frontend team.
    • Templates: Might need adjustments (that are not reflected in the template tests) in case of non-breaking changes and deprecations.
    • Projects: Depending on the version dependencies, different projects might get affected.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Other (add details above)

@github-actions github-actions Bot added the enhancement New feature or request label Jul 7, 2026
@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch 2 times, most recently from 3a82850 to e5dcb90 Compare July 7, 2026 14:37
@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch from e5dcb90 to 4ef6ca7 Compare July 8, 2026 12:50
@Json-Andriopoulos Json-Andriopoulos added the no-release-notes Release notes will NOT be attached and used publicly for this PR. label Jul 9, 2026
@Json-Andriopoulos
Json-Andriopoulos marked this pull request as ready for review July 10, 2026 11:25
@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch from 63e35d3 to 1ef4939 Compare July 10, 2026 13:59
@htahir1

htahir1 commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@Json-Andriopoulos nice work on this - one request while the adapter design is still soft.

We have concrete customer demand (can't name names here) for exactly this flow with Firecrawl's monitoring webhooks: a monitor detects a page change, posts a monitor.page event, and that should trigger a pipeline snapshot. I just built an example around it on example/firecrawl-web-monitor (#5065) - right now it works around the missing trigger integration by pulling checks via the Firecrawl API, but webhook triggers are the architecture we actually want to sell there.

Two things in the current BaseWebhookAdapter would need overrides for Firecrawl, and they're probably representative of a lot of non-GitHub providers:

  1. Auth: Firecrawl doesn't sign payloads with HMAC - it sends whatever custom headers you configure on the monitor (typically a shared bearer token). So authenticate() assuming an HMAC signature header shouldn't be baked into the base contract, just into the GitHub adapter.
  2. Event type location: parse() requires the event type in a request header (self.event_header), but Firecrawl puts it in the JSON body ("type": "monitor.page"). An adapter should be able to derive event_type from the parsed payload.

Both are cheap to generalize now and annoying to retrofit once adapters exist downstream. Happy to contribute a FirecrawlWebhookAdapter as the first non-GitHub adapter once the trigger follow-up branch is ready - the example gives us a live end-to-end test bed for it.

@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch from cfb479a to e0b8a43 Compare July 13, 2026 09:08
@bcdurak bcdurak linked an issue Jul 13, 2026 that may be closed by this pull request
1 task
@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch from e9c8445 to 2c8e2a2 Compare July 14, 2026 08:21
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Documentation Link Check Results

Absolute links check passed
Relative links check passed
Last checked: 2026-07-16 11:32:35 UTC

@Json-Andriopoulos
Json-Andriopoulos changed the base branch from feature/webhook-triggers to develop July 14, 2026 08:35
@Json-Andriopoulos
Json-Andriopoulos changed the base branch from develop to feature/webhook-triggers July 14, 2026 08:35
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74918aef-b14b-420f-b81f-f0d2ed6b5b16

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/webhook-integrations

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch from 2c8e2a2 to cda47ac Compare July 14, 2026 10:12
Comment thread src/zenml/zen_server/rbac/utils.py
Comment thread src/zenml/client.py Outdated
Comment thread src/zenml/client.py Outdated
Comment thread src/zenml/cli/webhook_integration.py Outdated
Comment thread src/zenml/cli/webhook_integration.py Outdated
Comment thread src/zenml/zen_stores/sql_zen_store.py Outdated
Comment thread src/zenml/zen_stores/sql_zen_store.py Outdated
Comment thread src/zenml/zen_stores/sql_zen_store.py Outdated
)
schema.update(update)
session.add(schema)
session.commit()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the commit fails, shouldn't we delete the potentially newly created secret, similar to the create method?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, valid but making this operation atomic is more complex that is sounds. Current code separate secret & metadata updates which is the simplest solution imo.

Comment thread src/zenml/zen_stores/sql_zen_store.py Outdated
try:
reference_id = UUID(values[_WEBHOOK_SECRET_REFERENCE_ID_KEY])
reference_key = values[_WEBHOOK_SECRET_REFERENCE_VALUE_KEY]
referenced_values = self._get_secret_values(reference_id)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is going to hurt with a potentially large amount of events coming in (imagine a GH webhook for lots of events in a huge organization). Every authentication check would now require one extra secret call that could be avoided by not allowing referencing existing secrets (or allow referencing it on creation, but don't point to it but instead just duplicate the value).

Would also reduce some of the complexity in the rotate handling. WDYT?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, duplicating the value won't work that easily. We would need to keep it updated when it is rotated. I like referencing the secret as UX but you are right unless a reliable cacheing layer is available we should avoid it for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant was essentially: We just copy it from their original secret, but from that point on it's completely disconnected. As in, rotating the original secret wouldn't work, they would need to rotate it via the webhook rotate request. But I guess that's also confusing.

In the current implementation though, the user wouldn't even know what secret they've connected to the webhook, which is also not ideal IMO.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, current code optimizes a bit the Db and Store I/O by reducing operations to a minimum:

  1. We drop support for more expensive secret reference
  2. We make webhook integration resolution at the intake endpoint super light
  3. We make stats update 1-pass (converted nested stats to flat table).

@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch 5 times, most recently from 9926a9d to b7da142 Compare July 15, 2026 11:42
@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch from b7da142 to 1124d13 Compare July 15, 2026 11:47
@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch from 478527f to 0004e50 Compare July 15, 2026 13:32
@Json-Andriopoulos
Json-Andriopoulos force-pushed the feature/webhook-integrations branch from 0004e50 to 7e976a0 Compare July 15, 2026 15:56
- Flat stats table - single query atomic update (intake endpoint imp)
- Drop support for secret ref (reduce secrets store calls)
- Lightweight webhook resolution (intake endpoint imp)
@Json-Andriopoulos
Json-Andriopoulos merged commit d531372 into feature/webhook-triggers Jul 21, 2026
53 of 54 checks passed
@Json-Andriopoulos
Json-Andriopoulos deleted the feature/webhook-integrations branch July 21, 2026 10:14
Json-Andriopoulos added a commit that referenced this pull request Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request no-release-notes Release notes will NOT be attached and used publicly for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Webhook triggers

3 participants