Agent skill
hubspot-security-basics
Apply HubSpot security best practices for tokens, scopes, and webhook verification. Use when securing private app tokens, implementing least privilege scopes, or validating HubSpot webhook signatures. Trigger with phrases like "hubspot security", "hubspot token rotation", "secure hubspot", "hubspot scopes", "hubspot webhook verify".
Install this agent skill to your Project
npx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/main/plugins/saas-packs/hubspot-pack/skills/hubspot-security-basics
SKILL.md
HubSpot Security Basics
Overview
Security best practices for HubSpot private app tokens, OAuth scopes, webhook signature verification, and secret management.
Prerequisites
- HubSpot private app or OAuth app configured
- Understanding of environment variables and secret management
Instructions
Step 1: Least-Privilege Scopes
Only request the scopes your integration actually uses:
| Use Case | Required Scopes |
|---|---|
| Read contacts | crm.objects.contacts.read |
| Write contacts | crm.objects.contacts.read, crm.objects.contacts.write |
| Read/write deals | crm.objects.deals.read, crm.objects.deals.write |
| Marketing emails | content |
| Forms | forms |
| Contact lists | crm.lists.read, crm.lists.write |
| Properties | crm.schemas.contacts.read |
| Custom objects | crm.objects.custom.read, crm.objects.custom.write, crm.schemas.custom.read |
| Webhooks | automation |
Never use: Do not grant all scopes. If you regenerate a private app token, the old token is immediately revoked.
Step 2: Token Storage
# .env (NEVER commit)
HUBSPOT_ACCESS_TOKEN=pat-na1-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
HUBSPOT_WEBHOOK_SECRET=your-webhook-secret
# .gitignore
.env
.env.local
.env.*.local
// Validate token is present at startup
function validateConfig(): void {
if (!process.env.HUBSPOT_ACCESS_TOKEN) {
throw new Error('HUBSPOT_ACCESS_TOKEN is required. See .env.example');
}
// Never log the token
console.log('HubSpot: Token configured', {
prefix: process.env.HUBSPOT_ACCESS_TOKEN.substring(0, 8) + '...',
});
}
Step 3: Webhook Signature Verification (v3)
HubSpot sends webhooks with signature verification headers:
import crypto from 'crypto';
import express from 'express';
// HubSpot v3 signature verification
// Header: X-HubSpot-Signature-v3
function verifyHubSpotSignatureV3(
requestBody: string,
signature: string,
timestamp: string,
clientSecret: string,
requestUri: string,
method: string = 'POST'
): boolean {
// Reject if timestamp is older than 5 minutes (replay protection)
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp)) > 300) {
console.warn('HubSpot webhook timestamp too old');
return false;
}
// v3: HMAC SHA-256 of method + URI + body + timestamp
const sourceString = `${method}${requestUri}${requestBody}${timestamp}`;
const expectedSignature = crypto
.createHmac('sha256', clientSecret)
.update(sourceString)
.digest('base64');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Express middleware
const webhookRouter = express.Router();
webhookRouter.post('/hubspot',
express.raw({ type: 'application/json' }),
(req, res) => {
const signature = req.headers['x-hubspot-signature-v3'] as string;
const timestamp = req.headers['x-hubspot-request-timestamp'] as string;
const requestUri = `https://${req.headers.host}${req.originalUrl}`;
if (!verifyHubSpotSignatureV3(
req.body.toString(), signature, timestamp,
process.env.HUBSPOT_WEBHOOK_SECRET!, requestUri
)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const events = JSON.parse(req.body.toString());
// Process events...
res.status(200).json({ received: true });
}
);
Step 4: Token Rotation Procedure
# 1. Generate new token in HubSpot
# Settings > Integrations > Private Apps > [Your App] > Auth tab
# Click "Rotate token" (old token revoked immediately)
# 2. Update in your secret manager
# AWS Secrets Manager
aws secretsmanager update-secret --secret-id hubspot/production \
--secret-string '{"access_token":"pat-na1-NEW_TOKEN"}'
# GCP Secret Manager
echo -n "pat-na1-NEW_TOKEN" | gcloud secrets versions add hubspot-token --data-file=-
# 3. Restart/redeploy your application to pick up new token
# 4. Verify new token works
curl -s https://api.hubapi.com/crm/v3/objects/contacts?limit=1 \
-H "Authorization: Bearer $HUBSPOT_ACCESS_TOKEN" | jq .status
Step 5: Git Secret Scanning
# .github/workflows/secret-scan.yml
name: Secret Scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check for HubSpot tokens
run: |
if grep -rE "pat-[a-z]{2}[0-9]-[a-f0-9-]{36}" --include="*.ts" --include="*.js" --include="*.json" .; then
echo "ERROR: HubSpot access token found in source code"
exit 1
fi
Output
- Minimal scopes configured per use case
- Tokens stored in environment variables, never in code
- Webhook signatures verified with replay protection
- Token rotation procedure documented
- CI scanning for leaked tokens
Error Handling
| Security Issue | Detection | Mitigation |
|---|---|---|
| Token in git history | git log -p --all -S "pat-na1" |
Rotate token immediately |
| Excessive scopes | Audit in Settings > Private Apps | Remove unneeded scopes |
| Unverified webhooks | Security audit | Add signature verification |
| Token never rotated | Track creation date | Schedule quarterly rotation |
Resources
Next Steps
For production deployment, see hubspot-prod-checklist.
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
dockerfile-generator
Dockerfile Generator - Auto-activating skill for DevOps Basics. Triggers on: dockerfile generator, dockerfile generator Part of the DevOps Basics skill category.
branch-naming-helper
Branch Naming Helper - Auto-activating skill for DevOps Basics. Triggers on: branch naming helper, branch naming helper Part of the DevOps Basics skill category.
readme-generator
Readme Generator - Auto-activating skill for DevOps Basics. Triggers on: readme generator, readme generator Part of the DevOps Basics skill category.
makefile-generator
Makefile Generator - Auto-activating skill for DevOps Basics. Triggers on: makefile generator, makefile generator Part of the DevOps Basics skill category.
gitignore-generator
Gitignore Generator - Auto-activating skill for DevOps Basics. Triggers on: gitignore generator, gitignore generator Part of the DevOps Basics skill category.
pre-commit-hook-setup
Pre Commit Hook Setup - Auto-activating skill for DevOps Basics. Triggers on: pre commit hook setup, pre commit hook setup Part of the DevOps Basics skill category.
Didn't find tool you were looking for?