This guide covers the HMAC signature authentication pattern used to secure requests to the Papermap Dashboard API.
How HMAC Authentication Works
The core security pattern uses HMAC-SHA256 to sign requests to the Papermap API:
Concatenate workspace_id + valid_until timestamp
Create HMAC-SHA256 hash using your secret key
Send signature + timestamp in headers
Papermap API verifies signature with the same secret
Authentication Flow
Your API → Generate HMAC Signature
payload = "workspace-456" + "1699999999"
signature = HMAC-SHA256(payload, secret_key)
Your API → Call Papermap Dashboard API
POST ${PAPERMAP_API_URL}/api/v1/external/dashboards
Headers:
X-API-Key-ID: your-api-key
X-Workspace-ID: workspace-456
X-Valid-Until: 1699999999
X-Signature: abc123...
Papermap API → Verifies Signature
- Extracts workspace_id and valid_until
- Computes: HMAC-SHA256(workspace_id + valid_until, secret_key)
- Compares computed signature with X-Signature header
- Checks valid_until hasn't expired
If the signature doesn’t match or the timestamp has expired, the request is
rejected with a 401 Unauthorized error.
Implementation by Language
Python
TypeScript/Node.js
PHP
Java
C#
Go
import hmac
import hashlib
import time
def _create_signature ( workspace_id : str , valid_until : str , secret_key : str ) -> str :
"""Create HMAC signature for authentication"""
payload = f " { workspace_id }{ valid_until } "
signature = hmac.new(
secret_key.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return signature
def _get_auth_headers ( workspace_id : str , api_key_id : str , secret_key : str ) -> dict :
"""Generate authentication headers with HMAC signature"""
valid_until = str ( int (time.time()) + 300 ) # Valid for 5 minutes
signature = _create_signature(workspace_id, valid_until, secret_key)
return {
"X-API-Key-ID" : api_key_id,
"X-Workspace-ID" : workspace_id,
"X-Valid-Until" : valid_until,
"X-Signature" : signature,
"Content-Type" : "application/json"
}
Token Expiration
API requests : 5 minutes validity(advisable) based on the example above (valid_until = now + 300)
Expired tokens are automatically rejected
Security Best Practices
Never hardcode API credentials: - Always use environment variables or a
secrets management system - The API endpoint URL should be treated as
sensitive configuration - Store credentials securely and rotate them regularly
Environment Configuration
Store your credentials securely:
PAPERMAP_API_KEY_ID = your-api-key-id
PAPERMAP_SECRET_KEY = your-secret-key-never-share
PAPERMAP_API_URL =< your-api-endpoint >
Obtaining Your Configuration: - API Credentials : Available in your
Papermap dashboard under Settings → API Keys - API Endpoint : Available
in Settings → API Configuration - Always use the values provided in your
dashboard for your specific workspace
Next Steps
Creating Dashboards Learn how to create and manage dashboards for your tenants
Iframe Tokens Generate secure tokens for embedding dashboards