123eworld Knowledge Hub → Transactional SMS → Page 151

Transactional SMS API Request Signing: HMAC, Canonical Requests, Replay Protection and Secure Verification

A technical reference for signed SMS API requests covering HMAC, canonicalization, timestamps, replay protection, raw request bodies and key rotation.

Why sign requests

API keys authenticate a caller, while request signing can add integrity and replay controls for sensitive integrations. A signature allows the server to verify that defined request data was created using a shared secret and has not been modified. The value is strongest when the platform defines exactly what is signed and provides reliable client libraries.

HMAC basics

HMAC produces a keyed digest over canonical request data. The server calculates the expected signature with the shared secret and compares it using a safe constant-time comparison. The cryptographic primitive should come from a well-maintained standard library rather than custom code.

Canonical representation

Both sides must sign exactly the same bytes. Define the HTTP method, normalized path, timestamp, body hash and required headers in a precise canonical format. Signature failures often come from JSON serialization, whitespace, URL encoding or header-order differences rather than from the HMAC algorithm itself.

Raw request body

If the signature includes the request body, verify the original byte representation before a framework parses and reserializes it. Two JSON documents can represent the same data while containing different bytes. Signing parsed-and-reformatted JSON can therefore create false signature failures.

Timestamp and replay

A captured valid request should not remain usable forever. Include a timestamp and enforce a short acceptance window. A nonce or unique request identifier can provide additional replay protection. Store enough recent identifiers to detect reuse without creating an unbounded database workload.

Key rotation

Use key versions so clients can introduce a new secret before the old one expires. During overlap, the server can accept both versions and record which one authenticated each request. Once adoption is confirmed, retire the old key.

Authentication order

Verify the signature before expensive business processing. A public endpoint should not parse complex templates, access large databases or call providers before the request is authenticated. This protects both performance and security.

Error handling

Return a deliberately generic authentication error. Do not tell an attacker whether the timestamp, key identifier or signature was the specific component that failed. Detailed diagnostics can be retained in protected security logs.

SDK support

Provide signing helpers in official SDKs when possible. Canonicalization is easy to implement inconsistently across programming languages. A small helper that produces the exact expected signature can eliminate an entire category of integration failures.

Testing

Test modified bodies, altered headers, expired timestamps, reused nonces, invalid signatures, key rotation and different JSON whitespace. Test large payloads and Unicode content because encoding assumptions can affect body hashing.

Performance

Signature verification should remain lightweight enough for high request volume. Keep the replay store efficient and avoid synchronously querying a slow external service for every signature. Rate-limit repeated invalid attempts to reduce abuse.

Common mistakes

Do not sign a representation that the server later changes before verification. Do not use a raw password hash as an improvised signature protocol. Do not accept an unlimited timestamp window. Do not compare signatures with ordinary string operations if the platform's security guidance requires constant-time comparison.

Developer takeaway

Request signing is only as reliable as its canonicalization contract. Document the exact fields and bytes that are signed, provide tested examples and make replay protection part of the protocol rather than an optional feature.

Implementation pattern

Define a canonical signing string containing method, path, timestamp, body hash and key version. Hash the exact raw request body and use a standard HMAC implementation. Verify timestamp and replay controls before business processing.

Failure example

If a framework reformats JSON before signature verification, the body hash can differ from the client calculation. Capture the original request bytes and verify them before parsing.

Production rule

Document the exact bytes and fields that are signed; naming the algorithm alone is not an integration specification.

Operational reference

Security review should include canonicalization, replay storage, key rotation, timestamp tolerance, failed-attempt rate limiting and logging. A signing scheme is not complete until its operational lifecycle is defined.

Canonicalization example

A practical canonical request might combine method, normalized path, timestamp, key ID and SHA-256 body digest separated by fixed newline characters. The exact format is a contract and should be identical in every SDK. Do not improvise optional whitespace or alternate JSON formatting rules.

Replay-store design

Replay detection can use a short-lived store keyed by tenant, key version and nonce or request identifier. The store needs bounded retention because replay windows are intentionally short. Rate-limit repeated invalid signatures so an attacker cannot turn verification into a high-volume storage workload.

Key compromise

If a signing secret is suspected to be exposed, revoke the affected key version and activate a replacement. Keep the old version's audit evidence so security teams can identify which requests were authenticated with it. Do not delete historical security records simply because the key is no longer valid.

Protocol documentation

Publish examples for at least one raw HTTP request, one canonical string and one computed signature. Developers should be able to reproduce the signature independently and compare intermediate values during integration testing.

Clock tolerance

Clock skew should be bounded rather than ignored. If the accepted timestamp window is too small, legitimate clients with inaccurate clocks will fail; if it is too large, replay protection becomes weaker. Document the tolerance and recommend time synchronization.

Replay versus duplicate

Replay protection prevents reuse of the same signed request, while idempotency prevents duplicate business operations. They solve different problems and should not be treated as substitutes.

Audit evidence

Record key version, authentication result, timestamp and request ID. This allows security teams to investigate suspicious patterns without storing the signed secret or full sensitive payload.

Final engineering rule

Use standard cryptography, precise canonicalization and bounded replay protection. Never invent a signing protocol ad hoc for production traffic.

Production reference

Production teams should monitor invalid-signature rates separately from ordinary authentication failures. A sudden spike can indicate a broken deployment, clock drift, key mismatch or an attack. The response should first determine which category changed before rotating every key.

Production reference

The replay store should be sized for the accepted request rate and timestamp window. A very short replay window reduces storage but can create false failures for slow clients; a very long window increases exposure. Select the window from actual integration behaviour and security requirements.

Production reference

Finally, keep signing tests as permanent interoperability tests. When SDKs or gateway frameworks change, run known request vectors to ensure canonicalization and signature output remain identical.

Design review

Request signing should be evaluated together with transport security, authentication and idempotency. TLS protects the network path, signing protects the defined request representation and idempotency protects the business operation from duplicate retries. Each control solves a different problem.

Reference checklist

Confirm canonical vectors, raw-body verification, timestamp validation, replay detection, key rotation, invalid-attempt controls and SDK interoperability.

Reference architecture note

A mature signing system should make interoperability testable before production. Provide fixed sample requests and expected signatures, document encoding precisely and publish test credentials that cannot access real messaging. This allows developers to solve canonicalization problems safely before connecting their application to production traffic. It also gives the platform a stable regression suite whenever gateway or SDK code changes.

Final production test

The final production test should use a known request vector, then deliberately modify one signed component. The platform must reject the modified request while continuing to accept the original vector. Repeat the test after key rotation to confirm both security and operational continuity.

Final reference rule

Keep cryptographic verification before business processing. Authentication should be a gate, not an afterthought performed after expensive application work.

Documentation rule

Document the signing protocol alongside the API version so changes to canonicalization are treated as contract changes. A working signature implementation is not enough; customers need stable examples and migration guidance.

Final check

Use fixed test vectors in every SDK release.

Continue through the 123eworld Knowledge Hub

Explore the complete 123eworld Knowledge Hub for practical SMS API, transactional messaging, queue, security and developer architecture guides.

Visit 123eworld.com for messaging and digital communication services.