Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Apply ElevenLabs security best practices for API keys, webhook HMAC validation, and voice data protection. Use when securing API keys, validating webhook signatures, or auditing ElevenLabs security configuration. Trigger with "elevenlabs security", "elevenlabs secrets", "secure elevenlabs", "elevenlabs API key security", "elevenlabs webhook signature", "elevenlabs HMAC".
.claude/skills/jeremylongshore-elevenlabs-security-basics/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | -9% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 11% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 30% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 74% | 0% |
| case-16 | ✗→✓ | ▲ Improved | -10% | 0% |
Security best practices for ElevenLabs API key management, webhook HMAC signature verification, and protecting cloned voice data. ElevenLabs uses a single API key (xi-api-key) and HMAC webhook authentication.
This SKILL.md carries the workflow at a high level with the essential skeletons. Full production code for each step lives in references/implementation.md, and end-to-end scenarios live in references/examples.md.
Keep keys out of source, and add a hook that blocks accidental commits:
bash# .env (NEVER commit to git) ELEVENLABS_API_KEY=sk_your_key_here # .gitignore — MUST include these .env .env.local .env.*.local
bash#!/bin/bash # .git/hooks/pre-commit — reject staged ElevenLabs keys if git diff --cached | grep -qE 'sk_[a-zA-Z0-9]{20,}'; then echo "ERROR: ElevenLabs API key detected in staged changes!" echo "Remove the key and use environment variables instead." exit 1 fi
Load the key at startup, fail fast when it is missing, and warn if a production key leaks into development. Full getSecurityConfig() implementation: references/implementation.md.
ElevenLabs webhooks carry an ElevenLabs-Signature header formatted as t=TIMESTAMP,v1=SIGNATURE. Verify it with HMAC-SHA256, reject timestamps older than 5 minutes (replay protection), and use a timing-safe comparison. Full verifyWebhookSignature() implementation: references/implementation.md.
Verify against the raw request body, respond 200 fast, then process asynchronously so you never trip the webhook timeout. Full endpoint: references/implementation.md.
Generate the new key, validate it before cutover, push to every environment, verify production, then revoke the old key — zero downtime. Full runbook: references/implementation.md.
Cloned voices are biometric PII: restrict who can clone, audit-log every operation, and require documented consent. Full policy and audit logger: references/implementation.md.
Applying this skill produces a hardened ElevenLabs integration:
.env gitignored and apre-commit hook that blocks the sk_ key pattern.
verifyWebhookSignature() helper and Express endpoint that reject invalidsignatures (HTTP 401) and replayed requests (timestamp > 5 minutes).
elevenlabs.voice.audit) for every voice clone,delete, and use, plus a completed Security Checklist below.
.env files in .gitignoresk_)ElevenLabs auto-disables webhooks after:
Always return HTTP 200 quickly from your webhook handler.
| Security Issue | Detection | Mitigation | |----------------|-----------|------------| | Exposed API key | Git scanning, CI check | Rotate immediately, revoke old key | | Invalid webhook signature | verifyWebhookSignature() returns false | Log and reject (HTTP 401) | | Replay attack | Timestamp > 5 minutes old | Reject with timestamp check | | Unauthorized voice cloning | Audit logs | Restrict clone permissions |
Worked, end-to-end scenarios live in references/examples.md:
commit containing sk_....
timestamp.
cut over, then revoke.
voice and whether consent was on file.
Once these basics are in place, harden the wider deployment: apply the elevenlabs-prod-checklist skill for production readiness, schedule the quarterly key rotation from Step 5, and wire the voice audit logs into your central logging or SIEM so cloning activity is reviewable.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 22,153 | 17,933 | -19% | 1 | 1 | 0% | 4,319 | 5,024 | +16% | 0 | 0 | — |
case-02 | fail→pass | 22,080 | 16,271 | -26% | 1 | 1 | 0% | 4,247 | 3,844 | -9% | 0 | 0 | — |
case-03 | fail→fail | 29,406 | 26,470 | -10% | 1 | 1 | 0% | 4,711 | 5,548 | +18% | 0 | 0 | — |
case-04 | pass→pass | 13,023 | 15,299 | +17% | 1 | 1 | 0% | 2,540 | 3,892 | +53% | 0 | 0 | — |
case-05 | fail→pass | 11,094 | 6,599 | -41% | 1 | 1 | 0% | 1,838 | 2,041 | +11% | 0 | 0 | — |
case-06 | pass→pass | 10,720 | 8,403 | -22% | 1 | 1 | 0% | 1,832 | 2,806 | +53% | 0 | 0 | — |
case-07 | pass→pass | 9,170 | 8,779 | -4% | 1 | 1 | 0% | 1,401 | 2,697 | +93% | 0 | 0 | — |
case-08 | pass→pass | 2,357 | 3,350 | +42% | 1 | 1 | 0% | 302 | 1,678 | +456% | 0 | 0 | — |
case-09 | pass→pass | 13,665 | 6,926 | -49% | 1 | 1 | 0% | 1,777 | 2,446 | +38% | 0 | 0 | — |
case-10 | pass→pass | 13,702 | 17,261 | +26% | 1 | 1 | 0% | 2,176 | 3,985 | +83% | 0 | 0 | — |
case-11 | fail→pass | 10,456 | 4,769 | -54% | 1 | 1 | 0% | 1,460 | 1,891 | +30% | 0 | 0 | — |
case-12 | pass→pass | 10,599 | 9,775 | -8% | 1 | 1 | 0% | 1,476 | 2,726 | +85% | 0 | 0 | — |
case-13 | fail→pass | 8,449 | 4,413 | -48% | 1 | 1 | 0% | 1,176 | 2,041 | +74% | 0 | 0 | — |
case-14 | pass→pass | 5,780 | 9,724 | +68% | 1 | 1 | 0% | 759 | 1,675 | +121% | 0 | 0 | — |
case-15 | pass→pass | 13,674 | 11,823 | -14% | 1 | 1 | 0% | 2,264 | 3,051 | +35% | 0 | 0 | — |
case-16 | fail→pass | 18,347 | 5,656 | -69% | 1 | 1 | 0% | 2,574 | 2,316 | -10% | 0 | 0 | — |
case-17 | fail→pass | 16,195 | 8,863 | -45% | 1 | 1 | 0% | 2,243 | 2,827 | +26% | 0 | 0 | — |
case-18 | pass→pass | 7,510 | 2,881 | -62% | 1 | 1 | 0% | 919 | 1,672 | +82% | 0 | 0 | — |
case-19 | pass→pass | 15,908 | 8,875 | -44% | 1 | 1 | 0% | 2,144 | 2,751 | +28% | 0 | 0 | — |
case-20 | pass→pass | 21,178 | 22,621 | +7% | 1 | 1 | 0% | 3,352 | 4,928 | +47% | 0 | 0 | — |
case-21 | pass→pass | 14,823 | 12,760 | -14% | 1 | 1 | 0% | 2,352 | 3,482 | +48% | 0 | 0 | — |
case-22 | pass→pass | 23,946 | 23,438 | -2% | 1 | 1 | 0% | 3,620 | 5,852 | +62% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +27 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.