Klaviyo security basics
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill klaviyo-security-basicsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
'Apply Klaviyo security best practices for API key management and access control.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
6.4 KB, as published. Nobody here has run it
Klaviyo Security Basics
Overview
Security best practices for Klaviyo: API key types, OAuth scopes, webhook HMAC-SHA256 signature verification, and secret rotation procedures.
Prerequisites
- Klaviyo account with API key access
- Understanding of environment variables and secret management
- Access to Klaviyo dashboard (Settings > API Keys)
Instructions
Step 1: Understand Key Types
| Key Type | Format | Use Case | Sensitivity |
|---|---|---|---|
| Private API Key | pk_* (40+ chars) | Server-side REST API | CRITICAL -- never expose client-side |
| Public API Key | 6 alphanumeric chars | Client-side Track/Identify only | Low -- safe in browser JS |
Private keys authenticate via Authorization: Klaviyo-API-Key pk_*** header. Public keys pass as company_id query parameter.
Step 2: Store Keys in Environment Variables
Keep every private key and the webhook signing secret out of source: load them
from .env (git-ignored) through a validated config loader that throws on a
missing secret, so misconfiguration fails at boot instead of at first API call.
// src/config/klaviyo.ts -- validated config loader (skeleton)
export const klaviyoConfig = {
privateKey: requireEnv('KLAVIYO_PRIVATE_KEY'), // throws if absent
publicKey: process.env.KLAVIYO_PUBLIC_KEY || '',
webhookSecret: process.env.KLAVIYO_WEBHOOK_SIGNING_SECRET || '',
};
Full .env template, .gitignore entries, and the requireEnv helper:
implementation.md → Environment Variable Configuration.
Step 3: Scope Keys per Environment (Least Privilege)
Issue a separate key for each environment with only the scopes that environment needs — read-only in dev and CI, full read/write in staging, the exact production scope set in prod — so a leaked key has the smallest possible blast radius. Scope table and per-environment env-var layout: implementation.md → Least-Privilege API Key Scopes.
Step 4: Verify Webhook Signatures (HMAC-SHA256)
Klaviyo signs each webhook payload with your signing secret. Recompute the
HMAC-SHA256 digest over the raw body and compare with crypto.timingSafeEqual
to defeat timing attacks; reject anything that does not match with 401.
const expected = crypto.createHmac('sha256', secret)
.update(rawBody).digest('base64');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
Full verifier plus the Express raw-body middleware that returns
401 Invalid signature:
implementation.md → Webhook Signature Verification
and Express Webhook Middleware.
Step 5: Rotate Keys with Zero Downtime
Rotate private keys on a schedule (quarterly) or immediately on suspected leak:
generate a replacement with identical scopes, deploy it to the secret store,
verify with a curl against /api/accounts/, then revoke the old key and watch
logs for 401s. Full five-step runbook with per-platform commands:
implementation.md → API Key Rotation Procedure.
Security Checklist
- Private API keys stored in environment variables / secret manager
-
.envfiles in.gitignore - Different API keys per environment (dev/staging/prod)
- Minimal scopes per environment
- Webhook signatures verified with HMAC-SHA256
- API key rotation scheduled (quarterly recommended)
- No private keys in client-side code
- CI/CD uses read-only key for tests
- Git history scanned for leaked keys (
git log -p | grep pk_)
Error Handling
| Security Issue | Detection | Mitigation |
|---|---|---|
| Leaked private key | Git scanning, trufflehog | Revoke immediately, rotate |
| Excessive scopes | Scope audit | Reduce to minimum required |
| Missing webhook verification | Code review | Add HMAC check |
| Key not rotated | Age > 90 days | Schedule rotation |
| 401s after rotation | Log monitoring | Verify all services updated |
Output
Applying this skill produces a hardened Klaviyo integration:
- A git-ignored
.envplus asrc/config/klaviyo.tsloader that fails fast on a missing private key. - Environment-scoped API keys (dev/staging/prod/CI) each holding minimum scopes.
- A webhook endpoint that returns
200 { "received": true }only for payloads whose HMAC-SHA256 signature verifies, and401 { "error": "Invalid signature" }for everything else. - A documented, zero-downtime rotation runbook and a completed security checklist.
Examples
Three worked scenarios — validated config loader, rejecting a forged webhook, and zero-downtime key rotation — with inputs and expected results are in examples.md. Quick sketch of the webhook case:
POST /webhooks/klaviyo (tampered body, original signature)
→ verifyKlaviyoWebhookSignature() recomputes HMAC → mismatch
→ 401 { "error": "Invalid signature" }, logged as rejected
See examples.md for the full walkthrough of each.
Resources
- Authenticate API Requests
- OAuth Setup
- Webhooks API Overview
- implementation.md — full copy-paste code for every step
- examples.md — end-to-end worked scenarios
Next Steps
For production hardening beyond secrets — rate limits, monitoring, and deploy
gates — see the klaviyo-prod-checklist skill in this pack.