intercom-security-basics

'Apply Intercom security best practices for tokens, webhook verification,

3 Tools
intercom-pack Plugin
saas packs Category

Allowed Tools

ReadWriteGrep

Provided by Plugin

intercom-pack

Claude Code skill pack for Intercom (24 skills)

saas packs v1.0.0
View Plugin

Installation

This skill is included in the intercom-pack plugin:

/plugin install intercom-pack@claude-code-plugins-plus

Click to copy

Instructions

Intercom Security Basics

Overview

Security best practices for Intercom access tokens, webhook signature verification, Identity Verification (HMAC), and least-privilege OAuth scopes.

Prerequisites

  • Intercom access token or OAuth credentials
  • Understanding of HMAC cryptographic signatures
  • Access to Intercom Developer Hub

Instructions

Step 1: Secure Token Storage


# .env (NEVER commit to git)
INTERCOM_ACCESS_TOKEN=dG9rOmFiY2RlZmdoaQ==
INTERCOM_WEBHOOK_SECRET=your-webhook-signing-secret
INTERCOM_IDENTITY_SECRET=your-identity-verification-secret

# .gitignore (mandatory entries)
.env
.env.local
.env.*.local

Verify no tokens are committed:


# Scan git history for leaked tokens
git log --all -p | grep -i "INTERCOM_ACCESS_TOKEN\|dG9r" | head -5
# If found: rotate token immediately, then use git-filter-repo to remove

Step 2: Webhook Signature Verification (X-Hub-Signature)

Intercom signs webhook notifications with HMAC-SHA1 using X-Hub-Signature. You must verify this on every incoming webhook.


import crypto from "crypto";
import express from "express";

function verifyIntercomWebhook(
  payload: Buffer,
  signature: string,
  secret: string
): boolean {
  // Intercom uses X-Hub-Signature with HMAC-SHA1
  const expectedSignature = "sha1=" + crypto
    .createHmac("sha1", secret)
    .update(payload)
    .digest("hex");

  // Timing-safe comparison to prevent timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

const app = express();

app.post(
  "/webhooks/intercom",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.headers["x-hub-signature"] as string;

    if (!signature) {
      return res.status(401).json({ error: "Missing signature" });
    }

    if (!verifyIntercomWebhook(req.body, signature, process.env.INTERCOM_WEBHOOK_SECRET!)) {
      return res.status(401).json({ error: "Invalid signature" });
    }

    const event = JSON.parse(req.body.toString());
    // Process verified webhook...
    res.status(200).json({ received: true });
  }
);

Step 3: Identity Verification (User Hash)

Intercom Identity Verification prevents impersonation by requiring an HMAC of the user's identifier.


import crypto from "crypto";

// Server-side: generate user hash
function generateIntercomUserHash(userId: string): string {
  return crypto
    .createHmac("sha256", process.env.INTERCOM_IDENTITY_SECRET!)
    .update(userId)
    .digest("hex");
}

// Pass to frontend for Messenger initialization
app.get("/api/intercom-settings", (req, res) => {
  const userId = req.user.id;
  res.json({
    app_id: process.env.INTERCOM_APP_ID,
    user_id: userId,
    user_hash: generateIntercomUserHash(userId),
  });
});

Step 4: Least-Privilege OAuth Scopes

Only request scopes your app actually needs:

Use Case Required Scopes
Read contact data only Read contacts
Manage conversations Read conversations, Write conversations
Send messages Write messages
Manage Help Center Read articles, Write articles
Full CRM integration Read/write contacts, Read/write conversations, Read/write tags

Step 5: Token Rotation Procedure


# 1. Generate new token in Developer Hub
#    Settings > Developer Hub > Your App > Authentication

# 2. Update in secret manager (examples)
# AWS
aws secretsmanager update-secret \
  --secret-id intercom/access-token \
  --secret-string "new_token_here"

# GCP
echo -n "new_token_here" | gcloud secrets versions add intercom-token --data-file=-

# Vault
vault kv put secret/intercom access_token="new_token_here"

# 3. Verify new token
curl -s https://api.intercom.io/me \
  -H "Authorization: Bearer $NEW_TOKEN" | jq '.type'
# Should return "admin"

# 4. Deploy updated config
# 5. Revoke old token in Developer Hub

Security Checklist

  • [ ] Access tokens stored in environment variables or secret manager
  • [ ] .env files in .gitignore
  • [ ] Different tokens for dev/staging/production workspaces
  • [ ] Webhook signatures verified on every request (X-Hub-Signature)
  • [ ] Identity Verification enabled (user_hash)
  • [ ] OAuth scopes are minimal (least privilege)
  • [ ] Token rotation procedure documented and tested
  • [ ] Git history scanned for leaked credentials
  • [ ] HTTPS enforced for all webhook endpoints

Error Handling

Security Issue Detection Mitigation
Leaked token in git `git log -p \ grep dG9r` Rotate immediately, remove from history
Invalid webhook signature 401 from verification Check secret matches Developer Hub
Missing Identity Verification Intercom dashboard warning Implement user_hash on server
Excessive OAuth scopes Scope audit Remove unnecessary scopes
Token never rotated Age tracking Schedule quarterly rotation

Resources

Next Steps

For production deployment, see intercom-prod-checklist.

Ready to use intercom-pack?