Skip to content
Browse documentation

Build

AWS (SigV4)

Send events to SQS, SNS, EventBridge, Kinesis and S3 with AWS Signature Version 4, scoped IAM policies and per-service templates.

AWS APIs reject unsigned requests. Hooks signs each delivery with AWS Signature Version 4 after the URL, headers and body are rendered, so the generic HTTPS destination works with SQS, SNS, EventBridge, Kinesis and S3 — and with S3-compatible stores such as Cloudflare R2.

Select AWS SigV4 as the destination auth mode and provide:

Field Example Notes
Region us-east-1 Region in the endpoint and in the credential scope.
Service sqs sqs, sns, events, kinesis or s3.
Access key ID AKIA… Store it as a project secret; it is write-only in the console.
Secret access key — Write-only secret.
Session token — Only for temporary credentials; sent as x-amz-security-token.

At delivery time Hooks computes the canonical request (method, path, sorted query, signed headers, body hash), derives the signing key for <date>/<region>/<service>/aws4_request, and adds:

  • Authorization: AWS4-HMAC-SHA256 Credential=…, SignedHeaders=…, Signature=…
  • x-amz-date
  • x-amz-content-sha256 for S3 requests

Only host and the x-amz-* headers are signed, so retries and extra headers stay valid. Credentials never appear in the API response, the console or an attempt record: authorization, x-amz-date, x-amz-content-sha256 and x-amz-security-token are redacted before logging.

Console → Quick start ships one template per service. Each asks for the resource coordinates, the region, an access key pair and the source signing secret.

Template Request Body
Any event → Amazon SQS POST <queue URL>, form body MessageBody=<event JSON>
Any event → Amazon SQS FIFO POST <queue URL>, form body MessageGroupId, MessageDeduplicationId=<delivery id>
Any event → Amazon SNS POST https://sns.<region>.amazonaws.com/, form body Publish with Message=<event JSON>
Any event → Amazon EventBridge POST https://events.<region>.amazonaws.com/, X-Amz-Target: AWSEvents.PutEvents One entry, Detail=<event JSON>
Any event → Amazon Kinesis POST https://kinesis.<region>.amazonaws.com/, X-Amz-Target: Kinesis_20131202.PutRecord Data=<payload base64>, key = delivery id
Any event → Amazon S3 PUT https://<bucket>.s3.<region>.amazonaws.com/<prefix>/<delivery id>.json Raw payload as the object

The S3 template uses URL templates for the object key. EventBridge and Kinesis need the application/x-amz-json-1.1 content type and their X-Amz-Target header, which the templates set for you.

Grant only the one action each destination needs. Replace the placeholders with your account id, region and resource names.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sqs:SendMessage",
"Resource": "arn:aws:sqs:us-east-1:123456789012:hooks-events"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-east-1:123456789012:hooks-events"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "events:PutEvents",
"Resource": "arn:aws:events:us-east-1:123456789012:event-bus/default"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "kinesis:PutRecord",
"Resource": "arn:aws:kinesis:us-east-1:123456789012:stream/hooks-events"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::acme-webhook-archive/events/*"
}
]
}

The FIFO template sends MessageDeduplicationId=<delivery id>. Retries reuse the delivery id, so SQS drops the duplicate instead of delivering the event twice within the five-minute deduplication window. MessageGroupId is a template field: use one value per entity when ordering matters, or the project name when order only matters globally.

PutEvents answers 200 OK even when some entries are rejected. Hooks reads FailedEntryCount from the response and treats a non-zero count as a retryable failure (AWS_PARTIAL_FAILURE), so the delivery is retried with the normal backoff instead of being marked successful. The response body, including ErrorCode and ErrorMessage, is kept on the attempt record.

Cloudflare R2 speaks the S3 API. Use service s3 and region auto, then point the URL at the R2 S3 endpoint:

https://<account_id>.r2.cloudflarestorage.com/<bucket>/<prefix>/{{delivery.id}}.json

Sign with an R2 API token’s access key pair. The same path template applies; only the host and region differ.

Deliveries → newest attempt shows the status, response headers and body. Common SigV4 failures:

  • 403 SignatureDoesNotMatch — wrong secret, region or service, or a proxy rewrote the URL. The request URL in the console shows exactly what was signed.
  • 403 InvalidClientTokenId — the access key was deleted or belongs to another account.
  • 400 with an error_code — the signing succeeded; the request shape is wrong (queue name, ARN or stream).