You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(webhooks): make signature optional on verify_and_parse_sqs/sns (CHA-3071)
Stream does not ship an X-Signature on SQS or SNS deliveries — those
transports ride AWS-internal infrastructure (IAM-authenticated queues
and AWS-signed SNS notifications), so HMAC verification on top is
theatre. signature + secret are now optional on both module helpers
and on the StreamChat / StreamChatAsync instance methods.
- verify_and_parse_sqs(body) -> decode + parse
- verify_and_parse_sqs(body, sig, secret) -> decode + verify + parse
- verify_and_parse_sns(envelope_body) -> unwrap + decode + parse
- verify_and_parse_sns(envelope_body, sig, secret) -> + verify
Passing only one of (signature, secret) raises InvalidWebhookError.
The HTTP-webhook path (verify_and_parse_webhook) is unchanged.
Co-authored-by: Cursor <cursoragent@cursor.com>
Copy file name to clipboardExpand all lines: docs/webhooks/webhooks_overview/webhooks_overview.md
+20-13Lines changed: 20 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -141,42 +141,49 @@ The original `client.verify_webhook(request.body, request.headers["X-Signature"]
141
141
142
142
#### SQS / SNS firehose
143
143
144
-
For events delivered through SQS or SNS, call the matching helper. It base64-decodes the envelope, gzip-decompresses when the magic bytes are present, verifies the HMAC, and returns the parsed event.
144
+
For events delivered through SQS or SNS, call the matching helper. It base64-decodes the envelope, gzip-decompresses when the magic bytes are present, and returns the parsed event.
145
+
146
+
Stream does **not** ship an `X-Signature` on SQS or SNS deliveries: those transports run on AWS-internal infrastructure that is already authenticated end-to-end. SQS queues are reached via IAM-authenticated polling, and SNS notifications carry an AWS signature on the notification envelope itself, so verifying that the message really came from your topic happens at the AWS layer. Layering an HMAC check on top is redundant, so `signature` and `secret` are optional for the SQS/SNS helpers. If you want the legacy verification pipeline you can still pass both — but you do not need to.
145
147
146
148
For SQS, pass the message `Body` (already the payload):
For SNS, pass the **raw notification body** (the full `{"Type":"Notification", ...}` JSON envelope Amazon delivers). The SDK extracts the inner `Message` field for you, so the call site mirrors what HTTP frameworks already hand you in `request.body`:
event = client.verify_and_parse_sns(request.body) # raw envelope (bytes/str)
166
159
```
167
160
168
161
#### Stateless / module-level form
169
162
170
-
If you do not want to construct a `StreamChat` client (for example in a lightweight Lambda that only handles webhooks), call the module-level helpers directly. They take the API secret as a third argument and are otherwise identical:
163
+
If you do not want to construct a `StreamChat` client (for example in a lightweight Lambda that only handles webhooks), call the module-level helpers directly. The HTTP helper still requires the signature and secret; the SQS/SNS helpers take them as optional positional arguments:
Passing only one of `signature` / `secret` to the SQS or SNS helper is a programmer error and raises `InvalidWebhookError("signature and secret must both be provided to verify the SQS/SNS payload")`.
The module also exposes the primitives the composites are built from — `gunzip_payload`, `decode_sqs_payload`, `decode_sns_payload`, `verify_signature` (constant-time HMAC-SHA256), and `parse_event` — for callers that need to run the steps individually.
0 commit comments