feat(gateway): add Datadog webhook source#456
Conversation
yordis
commented
Jul 1, 2026
- Datadog monitor and event alerts need to reach the NATS event bus alongside the other observability sources (Sentry, incident.io) so downstream services can react to them.
- Datadog webhooks are unsigned, so authentication relies on a shared-secret custom header with an optional timestamp-based anti-replay window rather than the HMAC verification the signed sources use.
PR SummaryMedium Risk Overview The new handler is mounted at Verified payloads publish to Reviewed by Cursor Bugbot for commit edcb685. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
Warning Review limit reached
Next review available in: 45 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR adds Datadog as a webhook source for trogon-gateway. It introduces Datadog-specific config, typed token/event helpers, signature verification, webhook handling and JetStream publishing, plugin wiring, and matching docs, templates, and telemetry updates. ChangesDatadog Webhook Source
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Code Coverage SummaryDetailsDiff against mainResults for commit: edcb685 Minimum allowed coverage is ♻️ This comment has been updated with latest results |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@rsworkspace/crates/trogon-gateway/src/config.rs`:
- Around line 1732-1734: The enabled integration handling in config resolution
is silently skipping entries when integration.webhook is missing, which lets an
invalid Datadog integration disappear from ResolvedConfig.datadog. Update the
logic around the integration processing block in config.rs so that the code
paths using integration.webhook fail with a configuration error instead of
continuing, and ensure the error is surfaced during config resolution rather
than being ignored by the DatadogPlugin mount/provision flow.
In `@rsworkspace/crates/trogon-gateway/src/source/datadog/config.rs`:
- Around line 12-15: The documentation on timestamp_tolerance uses the wrong
Datadog template variable name; update the comment in the Datadog config around
timestamp_tolerance to refer to Datadog’s documented $DATE_POSIX value instead
of $DATE_EPOCH. Keep the guidance aligned with the webhook payload templating
used by the Datadog source config so users can correctly populate the timestamp
field.
In `@rsworkspace/crates/trogon-gateway/src/source/datadog/server.rs`:
- Around line 178-234: The Datadog webhook handler still works directly with
serde_json::Value and validates timestamp, id, and event_type in scattered
helper calls, instead of using a dedicated boundary type. Update the request
flow in server.rs around the Datadog webhook handling to deserialize into a
DatadogWebhookRequest/DatadogWebhookWire type, then convert that boundary type
exactly once into validated domain values before routing. Keep the existing
helper symbols like body_timestamp_secs, body_event_id, and
DatadogEventType::new as needed, but move the untrusted-input parsing into the
distinct request type so validation is centralized.
- Around line 60-68: The body_timestamp_secs helper currently truncates
non-negative fractional JSON timestamps by casting as_f64() to u64, which can
alter replay-window decisions. Update body_timestamp_secs in server.rs to only
accept exact integer values: keep as_u64() and string parsing that succeeds
cleanly, but reject any floating-point timestamp (including whole-number floats)
instead of converting it. Ensure the timestamp extraction logic in
body_timestamp_secs preserves exactness for the replay check.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 258df577-a083-48cf-bcc6-1bb650152e15
⛔ Files ignored due to path filters (2)
rsworkspace/crates/trogon-semconv/src/gen/attribute.rsis excluded by!**/gen/**rsworkspace/crates/trogon-semconv/src/gen/span.rsis excluded by!**/gen/**
📒 Files selected for processing (22)
devops/docker/compose/.env.exampledevops/docker/compose/services/trogon-gateway/README.mddevops/docker/compose/services/trogon-gateway/gateway.tomlotel/semconv/registry/gateway.yamlrsworkspace/crates/trogon-gateway/README.mdrsworkspace/crates/trogon-gateway/src/config.rsrsworkspace/crates/trogon-gateway/src/config/tests.rsrsworkspace/crates/trogon-gateway/src/http/tests.rsrsworkspace/crates/trogon-gateway/src/source/datadog/config.rsrsworkspace/crates/trogon-gateway/src/source/datadog/constants.rsrsworkspace/crates/trogon-gateway/src/source/datadog/datadog_event_type.rsrsworkspace/crates/trogon-gateway/src/source/datadog/datadog_event_type/tests.rsrsworkspace/crates/trogon-gateway/src/source/datadog/datadog_webhook_token.rsrsworkspace/crates/trogon-gateway/src/source/datadog/datadog_webhook_token/tests.rsrsworkspace/crates/trogon-gateway/src/source/datadog/mod.rsrsworkspace/crates/trogon-gateway/src/source/datadog/server.rsrsworkspace/crates/trogon-gateway/src/source/datadog/server/tests.rsrsworkspace/crates/trogon-gateway/src/source/datadog/signature.rsrsworkspace/crates/trogon-gateway/src/source/datadog/signature/tests.rsrsworkspace/crates/trogon-gateway/src/source/mod.rsrsworkspace/crates/trogon-gateway/src/source_plugin.rsrsworkspace/crates/trogon-gateway/src/streams/tests.rs
Datadog monitor and event alerts need to land on the NATS event bus alongside the other observability sources so downstream consumers can react to them. Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Operators front Datadog behind proxies and conventions that dictate the custom header name, so the shared-secret header must be overridable while keeping a sensible default. Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Centralize untrusted-payload extraction into a single boundary type, reject fractional timestamps that could shift the replay-window decision, and correct the documented Datadog time variable to $DATE_POSIX so operators configure a timestamp the source actually accepts. Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Silently dropping a configured-but-webhook-less integration lets the gateway start with an operator-declared integration missing, so it must fail config resolution loudly instead. Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
The coverage gate fails when a diff adds uncovered lines; the Datadog resolver's invalid-id, disabled-integration, and invalid-common-field branches had no tests. Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>