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
fix(webhooks): generate_signature returns prefixed wire form
Receivers copy-pasting `generate_signature(...)` into their handler used
to produce a bare hex digest like `"abc123..."` and had to remember to
wrap it as `f"sha256={sig}"` to match the dispatcher's wire format.
Forgetting the wrap silently produced malformed signatures that failed
verification on the other side.
`generate_signature(body, secret)` now returns the full
`"sha256=<lowercase hex>"` form, ready to be assigned to the
`X-Tango-Signature` header directly. `verify_signature` continues to
accept both the prefixed wire form and the bare-hex form so callers
that pre-strip the prefix keep working — added an explicit regression
test for that.
Audited and updated:
- `tango/webhooks/simulate.py` — `sign()` builds the header from the
prefixed form directly; `SignedRequest.signature` field stays bare hex
- `tango/webhooks/cli.py` — uses `SIGNATURE_PREFIX` for the printed
signature value (via the SimulationResult.signature bare-hex field)
- `tests/test_webhooks_signing.py` — vectors updated to prefixed form;
added explicit dual-form acceptance test
- `tests/test_webhooks_receiver.py` — `_post_signed` no longer
double-wraps the header
- `docs/WEBHOOKS.md` and `docs/API_REFERENCE.md` — receiver examples
drop the manual `f"sha256={...}"` wrap
Breaking change for direct callers of `generate_signature` who relied
on bare-hex output — pass through `parse_signature_header()` to recover
the previous form. Folded into the v0.7.0 release.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
31
31
### Changed
32
32
-`create_webhook_alert` accepts `endpoint=` (keyword-only). Required for accounts with multiple webhook endpoints; auto-resolves for single-endpoint accounts. Closes the multi-endpoint smoke-test gap (tango#2256).
33
33
-`test_webhook_delivery` now sends the canonical `endpoint` body key instead of the deprecated `endpoint_id` alias (tango#2252). The Python kwarg name stays `endpoint_id=` for backwards compatibility; the wire payload is what changed.
34
+
-**`generate_signature(body, secret)` now returns the full wire form `"sha256=<hex>"`** instead of bare hex. Callers can assign the return value directly to the `X-Tango-Signature` header without wrapping in a format string. This is a breaking change for code that relied on the bare-hex return; pass it through `parse_signature_header()` to recover the previous form. `verify_signature` accepts both prefixed and bare-hex inputs (unchanged), so receivers continue to work either way.
34
35
35
36
### Removed
36
37
-**Subject-based webhook subscription surface** (tango#2275). Migrate to `create_webhook_alert(...)` and the alerts API.
0 commit comments