Claude-code-plugins-plus fireflies-security-basics
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/fireflies-pack/skills/fireflies-security-basics" ~/.claude/skills/jeremylongshore-claude-code-plugins-plus-fireflies-security-basics && rm -rf "$T"
manifest:
plugins/saas-packs/fireflies-pack/skills/fireflies-security-basics/SKILL.mdsource content
Fireflies.ai Security Basics
Overview
Security essentials for Fireflies.ai: API key management, webhook HMAC-SHA256 signature verification, transcript access controls, and audit practices.
Prerequisites
- Fireflies.ai API key
- Understanding of environment variables
- HTTPS endpoint for webhooks (required by Fireflies)
Instructions
Step 1: Secure API Key Storage
# .env (NEVER commit) FIREFLIES_API_KEY=your-api-key FIREFLIES_WEBHOOK_SECRET=your-16-to-32-char-secret # .gitignore .env .env.local .env.*.local
Pre-commit hook to catch leaked keys:
#!/bin/bash # .git/hooks/pre-commit if git diff --cached --name-only | xargs grep -l 'FIREFLIES_API_KEY\s*=' 2>/dev/null; then echo "ERROR: Potential API key in commit. Remove before committing." exit 1 fi
Step 2: Webhook Signature Verification (HMAC-SHA256)
Fireflies signs webhook payloads with HMAC-SHA256. The signature arrives in the
x-hub-signature header.
import crypto from "crypto"; function verifyFirefliesWebhook( payload: string, signature: string, secret: string ): boolean { const expected = crypto .createHmac("sha256", secret) .update(payload) .digest("hex"); // Timing-safe comparison prevents timing attacks return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); } // Express middleware import express from "express"; const app = express(); app.post("/webhooks/fireflies", express.raw({ type: "application/json" }), (req, res) => { const signature = req.headers["x-hub-signature"] as string; const payload = req.body.toString(); if (!signature || !verifyFirefliesWebhook(payload, signature, process.env.FIREFLIES_WEBHOOK_SECRET!)) { console.warn("Invalid webhook signature rejected"); return res.status(401).json({ error: "Invalid signature" }); } const event = JSON.parse(payload); console.log(`Verified webhook: ${event.eventType} for ${event.meetingId}`); res.status(200).json({ received: true }); } );
Step 3: Configure Webhook Secret
- Go to app.fireflies.ai/settings
- Select Developer settings tab
- Enter a 16-32 character secret or click Generate
- Store the secret in your environment as
FIREFLIES_WEBHOOK_SECRET
Step 4: Python Webhook Verification
import hmac, hashlib, json from flask import Flask, request, jsonify app = Flask(__name__) def verify_signature(payload: bytes, signature: str, secret: str) -> bool: expected = hmac.new( secret.encode(), payload, hashlib.sha256 ).hexdigest() return hmac.compare_digest(signature, expected) @app.post("/webhooks/fireflies") def handle_webhook(): signature = request.headers.get("x-hub-signature", "") if not verify_signature(request.data, signature, os.environ["FIREFLIES_WEBHOOK_SECRET"]): return jsonify({"error": "Invalid signature"}), 401 event = request.json print(f"Verified: {event['eventType']} for {event['meetingId']}") return jsonify({"received": True})
Step 5: Transcript Privacy Levels
Fireflies supports these privacy levels via
updateMeetingPrivacy:
| Level | Access |
|---|---|
| Only meeting organizer |
| Only meeting participants |
| Workspace members + participants |
| All workspace members |
| Anyone with the link |
// Lock a transcript to participants only await firefliesQuery(` mutation($id: String!, $privacy: String!) { updateMeetingPrivacy(transcript_id: $id, privacy_level: $privacy) } `, { id: "transcript-id", privacy: "participants" });
Step 6: API Key Rotation
set -euo pipefail # 1. Generate new key in Fireflies dashboard (Integrations > Fireflies API) # 2. Test new key curl -s -X POST https://api.fireflies.ai/graphql \ -H "Authorization: Bearer $NEW_KEY" \ -H "Content-Type: application/json" \ -d '{"query": "{ user { email } }"}' | jq '.data.user.email' # 3. Update environment/secret store # 4. Verify production # 5. Old key is automatically invalidated when new one is generated
Security Checklist
- API key in environment variables, not code
-
files in.env.gitignore - Webhook signatures verified with HMAC-SHA256
- Webhook secret is 16-32 characters
- Transcript privacy set to
or stricterparticipants - Pre-commit hook catches key leaks
- Separate API keys for dev/staging/prod
- HTTPS required for all webhook endpoints
Error Handling
| Issue | Detection | Fix |
|---|---|---|
| Leaked API key | Git scanning, CI alerts | Regenerate immediately in dashboard |
| Invalid webhook signature | 401 from your endpoint | Verify secret matches dashboard |
| Overly permissive privacy | Audit transcript visibility | Set to default |
| Key rotation gap | Auth failures after rotation | Deploy new key before revoking old |
Output
- Secure API key storage with leak prevention
- HMAC-SHA256 webhook signature verification
- Privacy-controlled transcript access
- Key rotation procedure
Resources
Next Steps
For production deployment, see
fireflies-prod-checklist.