Skip to Content
For DevelopersTrigger Authentication

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}", }

Example: Manual Implementation

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}/rotate

This endpoint:

  • Generates a new trigger secret
  • Invalidates the old secret
  • Returns the new secret (store securely!)

Security Best Practices

  1. Store Secrets Securely - Use environment variables or secret management systems
  2. Rotate Regularly - Rotate secrets every 90 days or when compromised
  3. Use HTTPS - Always call the API over HTTPS
  4. Validate Timestamps - Implement timestamp tolerance on the server side
  5. 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}/trigger

Headers:

  • X-SOP-Timestamp - Unix timestamp in seconds
  • X-SOP-Signature - sha256=<hex_digest>
  • Content-Type - application/json

Body:

{ "input": { "key": "value" } }

Rotate Trigger Secret

POST /api/sops/{sopId}/triggers/{triggerId}/rotate

Response:

{ "secret": "new-trigger-secret", # pragma: allowlist secret "triggerId": "trigger-id", "createdAt": "2025-01-15T12:00:00Z" }
  • SOP Webhooks - Learn how to receive notifications when SOPs complete
Last updated on
Trigger Authentication | Sophosic™ Platform