Trigger Authentication
External systems must sign trigger requests using HMAC authentication to securely execute SOPs (Sophosic Operating Protocols) via the API.
Overview
Trigger authentication ensures that only authorized external systems can execute SOPs. Each SOP has a unique trigger secret returned at trigger creation time.
Required Headers
Each call to /api/sops/{id|slug}/trigger requires two headers:
X-SOP-Timestamp: <unix seconds>
X-SOP-Signature: sha256=<hex_digest>Header Descriptions
- X-SOP-Timestamp - Current Unix timestamp in seconds
- X-SOP-Signature - HMAC SHA256 signature of
<timestamp>.<request body>
HMAC Signature Generation
The hex_digest is the HMAC SHA256 of <timestamp>.<request body> using the trigger secret.
Example: Python Implementation
import time
from src.services.hmac_service import sign_payload
body = b'{"input": {"foo": "bar"}}'
timestamp = str(int(time.time()))
signature = sign_payload(secret, body, timestamp)
headers = {
"X-SOP-Timestamp": timestamp,
"X-SOP-Signature": f"sha256={signature}",
}import hmac
import hashlib
import time
import json
# Configuration
trigger_secret = "your-trigger-secret-here" # pragma: allowlist secret
request_body = {"input": {"foo": "bar"}}
# Generate timestamp
timestamp = str(int(time.time()))
# Convert request body to bytes
body_bytes = json.dumps(request_body).encode('utf-8')
# Create message to sign: "<timestamp>.<request body>"
message = f"{timestamp}.{body_bytes.decode('utf-8')}".encode('utf-8')
# Generate HMAC SHA256 signature
signature = hmac.new(
trigger_secret.encode('utf-8'),
message,
hashlib.sha256
).hexdigest()
# Headers for API request
headers = {
"X-SOP-Timestamp": timestamp,
"X-SOP-Signature": f"sha256={signature}",
"Content-Type": "application/json"
}Secret Rotation
Rotate trigger secrets periodically for security:
POST /api/sops/{sopId}/triggers/{triggerId}/rotateThis endpoint:
- Generates a new trigger secret
- Invalidates the old secret
- Returns the new secret (store securely!)
Security Best Practices
- Store Secrets Securely - Use environment variables or secret management systems
- Rotate Regularly - Rotate secrets every 90 days or when compromised
- Use HTTPS - Always call the API over HTTPS
- Validate Timestamps - Implement timestamp tolerance on the server side
- Monitor Failed Attempts - Track and alert on signature verification failures
Timestamp Tolerance
The platform validates timestamps to prevent replay attacks:
- Maximum age: 5 minutes (configurable)
- Prevents reuse of old signatures
- Protects against timing attacks
Troubleshooting
”Invalid signature” errors
- Verify the trigger secret is correct
- Check timestamp format (Unix seconds, not milliseconds)
- Ensure message format:
<timestamp>.<request body> - Verify HMAC algorithm is SHA256
- Check for whitespace in request body
”Timestamp too old” errors
- Ensure system clocks are synchronized (use NTP)
- Check for network delays
- Verify timestamp is in seconds, not milliseconds
API Endpoint Reference
Trigger SOP Execution
POST /api/sops/{id|slug}/triggerHeaders:
X-SOP-Timestamp- Unix timestamp in secondsX-SOP-Signature-sha256=<hex_digest>Content-Type-application/json
Body:
{
"input": {
"key": "value"
}
}POST /api/sops/{sopId}/triggers/{triggerId}/rotateResponse:
{
"secret": "new-trigger-secret", # pragma: allowlist secret
"triggerId": "trigger-id",
"createdAt": "2025-01-15T12:00:00Z"
}Related Documentation
- SOP Webhooks - Learn how to receive notifications when SOPs complete
Last updated on