Signed webhooks for incident ingestion

Availability: available

POST /hooks/{token} is the implemented public ingress path. The opaque path token identifies an enabled project trigger without requiring a login session. Despite the configuration name, the current ingress contract does not require an HMAC secret to save or receive a webhook.

  1. Set MENDRY_PUBLIC_URL to the externally reachable API origin.
  2. Save a signed_webhook trigger after signing in.
  3. Copy the returned inboundUrl from the configuration response.
  4. Configure the sender to post UTF-8 text or JSON no larger than the API body limit.
Terminal window
curl -X POST \
-H 'Content-Type: application/json' \
-d '{"title":"database latency increased","service":"checkout-api"}' \
'https://mendry.example/hooks/REPLACE_WITH_INBOUND_TOKEN'

A valid token/body returns 202 before background normalization and incident writes finish. JSON uses bounded semantic grouping with deterministic fallback; plain text uses its first non-empty line.

Choose AWS CloudWatch Alarm via SNS and save the exact standard SNS Topic ARN, for example arn:aws:sns:us-east-1:123456789012:mendry-alarms. Only the commercial aws partition is supported. FIFO topics, cross-account alarms, and cross-region alarms are rejected.

In AWS:

  1. Open the SNS topic and create an HTTPS subscription whose endpoint is the generated inboundUrl; leave Raw message delivery disabled.
  2. Wait for Mendry to verify the signed SubscriptionConfirmation and call the exact AWS confirmation URL.
  3. In CloudWatch, configure the alarm action to publish to that SNS topic. Restrict the topic policy to the CloudWatch service and the intended alarm/account with aws:SourceArn and aws:SourceAccount conditions.
  4. Send a CloudWatch test alarm and verify an Event Stream observation appears.

Mendry does not need an AWS access key or IAM permission for this integration. It verifies SNS RSA signatures using the regional AWS certificate endpoint. The HTTPS endpoint must be publicly reachable by SNS. SNS envelopes are limited to 512 KiB.

ALARM creates an observation and enters incident analysis after normalized evidence is stored. AWS-triggered remediation is permanently analysis-only: it can diagnose and propose a solution, but cannot patch, validate, publish, repair, or deploy. OK and INSUFFICIENT_DATA create observations only and do not resolve or otherwise mutate incident lifecycle state.

AWS references: verify SNS message signatures, prepare an HTTP/S endpoint, and configure CloudWatch alarm notifications.

  • 404 webhook_not_found: the token is wrong, rotated, disabled, or belongs to another trigger.
  • 403 invalid_aws_sns_signature: the Topic ARN, signature, certificate URL, or signed confirmation URL did not match exactly.
  • 400 invalid_aws_sns_message: the envelope is malformed, contains duplicate JSON keys, or is not a CloudWatch alarm publication.
  • 503 aws_sns_unavailable: certificate retrieval or subscription confirmation failed transiently; SNS should retry.
  • No incident for OK or INSUFFICIENT_DATA: expected; inspect the Event Stream observation instead.

Never log the inbound token, SNS SubscribeURL, confirmation token, signature, certificate body, or raw SNS envelope. Rotate the inbound URL if it is exposed.

The logged-in user rotates the token through POST /api/v1/projects/{projectKey}/configuration/webhook-token. Rotation invalidates the old token. Update the sender immediately; do not log or paste either token into tickets.

Unknown, disabled, incomplete, and old tokens all return 404 webhook_not_found. The access log records POST /hooks/{token} rather than the raw path. Raw provider bodies are excluded from application logs.

  • backend/README.md