Skip to main content
Always verify that webhook payloads actually came from Smartcar before processing them.

Verify Payload Signatures

Every webhook payload includes an SC-Signature header containing an HMAC-SHA256 signature. Always verify this signature before processing the payload.

How It Works

  1. Smartcar creates an HMAC-SHA256 hash of the payload using your Application Management Token as the secret key
  2. The hash is sent in the SC-Signature header
  3. You recreate the hash using the same secret and compare it to the received signature
  4. If they match, the payload is authentic

Implementation

const crypto = require('crypto');

function verifySignature(payload, signature, managementToken) {
  // Create HMAC hash
  const hmac = crypto
    .createHmac('sha256', managementToken)
    .update(payload)
    .digest('hex');
  
  // Use timingSafeEqual to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(hmac),
    Buffer.from(signature)
  );
}

app.post('/webhooks/smartcar', express.raw({ type: 'application/json' }), (req, res) => {
  // Get signature from header
  const signature = req.headers['sc-signature'];
  
  // Get raw body
  const rawBody = req.body.toString();
  
  // Verify before processing
  if (!verifySignature(rawBody, signature, MANAGEMENT_TOKEN)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
  
  // Safe to process
  const payload = JSON.parse(rawBody);
  processWebhook(payload);
  res.status(200).json({ status: 'received' });
});
Critical: You must verify the signature against the raw request body, before parsing it as JSON. Many frameworks automatically parse JSON, which can alter the body and break signature verification.

Why Signature Verification Matters

Without verification, anyone could send fake webhook payloads to your endpoint. Signature verification proves the payload came from Smartcar.
While signatures don’t prevent replays alone, combining them with eventId deduplication creates a complete defense.
If the payload is tampered with in transit, the signature won’t match, alerting you to the modification.
Many security standards and regulations require verification of external data sources.

Additional Security Measures

Use HTTPS Only

Smartcar only delivers webhooks to HTTPS endpoints with valid SSL certificates.
Required: Your callback URL must use HTTPS with a valid, trusted SSL certificate. Self-signed certificates are not supported.

Restrict Access by IP (Optional)

While Smartcar doesn’t publish a fixed IP range (addresses may change), you can add an extra layer of security by:
  1. Logging all webhook source IPs
  2. Alerting on unusual source addresses
  3. Rate limiting by IP to prevent abuse
Don’t rely on IP filtering alone. Signature verification is the primary security mechanism. IP-based restrictions should be supplementary.

Rotate Management Tokens Periodically

Your Application Management Token is used to verify webhook signatures. Rotate it periodically for security:
1

Generate new token

Create a new Application Management Token in the Dashboard
2

Update your code

Deploy code that accepts either the old or new token temporarily
3

Switch to new token

Once deployed, switch Dashboard to use the new token
4

Remove old token

After confirming all webhooks use the new token, remove old token support

Monitor Failed Verifications

Track and alert on signature verification failures:
@app.post("/webhooks/smartcar")
def webhook_handler():
    signature = request.headers.get('SC-Signature')
    raw_body = request.data.decode('utf-8')
    
    if not verify_signature(raw_body, signature, MANAGEMENT_TOKEN):
        # Log the failure
        logger.warning(
            "Invalid webhook signature",
            extra={
                "source_ip": request.remote_addr,
                "signature": signature,
                "payload_size": len(raw_body)
            }
        )
        
        # Alert if threshold exceeded
        if recent_failures_count() > 10:
            send_security_alert("High rate of invalid webhook signatures")
        
        return {"error": "Invalid signature"}, 401

Using SDK Helpers

Smartcar’s SDKs provide built-in methods for signature verification:
const smartcar = require('smartcar');

// Verify signature
const isValid = smartcar.verifyPayload(
  managementToken,
  signature,
  rawBody
);

Next Steps