HMAC Request Signing
For additional security, you can enable HMAC-SHA256 request signing on any application. When enabled, every Client API request must include a valid signature — preventing request tampering and replay attacks.
Optional: HMAC signing is disabled by default. Enable it per-app from the Dashboard API when you need stronger request integrity.
Setup
- Generate an HMAC secret:
POST /api/dashboard/apps/:appId/hmac-secret
- Store the returned
hmac_secret (prefixed hk_) in your client application
- Sign every Client API request using the scheme below
Signing Scheme
Construct the signature message as:
{timestamp}.{METHOD}.{path}.{body}
Where:
| Component | Description | Example |
timestamp | Current Unix epoch in seconds | 1740700800 |
METHOD | HTTP method, uppercased | POST |
path | Request pathname (no query string) | /api/v1/init |
body | Raw request body (empty string for GET) | {"version":"1.0"} |
Compute HMAC-SHA256(hmac_secret, message) and send as a hex string.
Required Headers
| Header | Description |
X-Signature | Hex-encoded HMAC-SHA256 signature |
X-Signature-Timestamp | Unix timestamp used in the signature (must be within 5 minutes of server time) |
import hmac, hashlib, time, json, requests
secret = "hk_your_hmac_secret"
timestamp = str(int(time.time()))
method = "POST"
path = "/api/v1/init"
body = json.dumps({"version": "1.0"})
message = f"{timestamp}.{method}.{path}.{body}"
signature = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
resp = requests.post("https://api.keyaux.com" + path,
headers={
"X-App-Secret": "as_your_app_secret",
"X-Signature": signature,
"X-Signature-Timestamp": timestamp,
"Content-Type": "application/json"
},
data=body
)
const crypto = require('crypto');
const secret = 'hk_your_hmac_secret';
const timestamp = Math.floor(Date.now() / 1000).toString();
const method = 'POST';
const path = '/api/v1/init';
const body = JSON.stringify({ version: '1.0' });
const message = `${timestamp}.${method}.${path}.${body}`;
const signature = crypto.createHmac('sha256', secret).update(message).digest('hex');
fetch('https://api.keyaux.com' + path, {
method,
headers: {
'X-App-Secret': 'as_your_app_secret',
'X-Signature': signature,
'X-Signature-Timestamp': timestamp,
'Content-Type': 'application/json'
},
body
});
HMAC Error Codes
| Code | HTTP | Description |
missing_signature | 401 | HMAC is enabled but X-Signature or X-Signature-Timestamp header is missing |
signature_expired | 401 | Timestamp is more than 5 minutes from server time |
invalid_signature | 401 | Signature does not match the expected value |
Dashboard Management
Generate (or rotate) an HMAC secret and enable signing. Returns the new secret — store it securely, it cannot be retrieved again.
{
"success": true,
"hmac_secret": "hk_a1b2c3d4e5f6...",
"message": "HMAC secret generated and signing enabled"
}
Disable HMAC signing and remove the secret. Client API requests will no longer require signatures.
Tip: You can also toggle hmac_enabled via PUT /api/dashboard/apps/:appId without rotating the secret.