This guide was originally written for NCR’s developer platform, where it reduced auth-related support tickets by 40%.
- The request details: method, path, query, and selected headers
- A shared secret key known only to your application and server
- A timestamp
- Request integrity: The request was not modified in transit.
- Caller authenticity: The caller possesses the valid secret key.
- Replay protection: Attackers cannot reuse intercepted requests.
Key components
| Component | Purpose |
|---|---|
| Shared key | The public identifier for your application. Include this with every request. |
| Secret key | The private key used to generate signatures. Never transmit this key. |
Authorization format
<shared-key>is your application’s shared key<signature>is the Base64-encoded HMAC signature
How it works
Build the canonical request string
Concatenate the following values in fixed order, separated by newlines (
\n):- HTTP method — uppercase (e.g.,
POST,GET) - Request URI — the path and query string, URL-encoded
Generate the signature
Compute the signature using the following parameters:
| Parameter | Value |
|---|---|
| Algorithm | HMAC-SHA256 |
| Input | Canonical request string |
| Output | Binary hash |
| Encoding | Base64 |
Code examples
Troubleshooting
| Error | Likely cause | Solution |
|---|---|---|
| 401 Invalid Signature | Canonical request mismatch | Verify method casing, URI encoding, header order, and whitespace |
| 401 Expired Request | Timestamp outside allowed window | Ensure your system clocks are synchronized via NTP |
| 403 Invalid Key | Incorrect shared key | Confirm the shared key matches the intended client credentials |
Next steps
- Secure your keys: Store secret keys in environment variables or a secrets manager. Never hardcode them.
- Synchronize clocks: Ensure your servers use NTP (Network Time Protocol) to avoid Expired Request errors.
- Limit scope: Avoid signing headers that might change in transit (like
User-AgentorAccept) unless strictly required.
