Flyio security basics
Skill jeremylongshore/claude-code-plugins-plus-skills/skills/.curated/flyio-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 flyio-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 Fly.io security best practices for secrets management, private networking,
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
4.0 KB, as published. Nobody here has run it
Fly.io Security Basics
Overview
Fly.io deploys applications to edge locations worldwide using Firecracker microVMs. Security concerns center on deploy token scoping (org-wide vs per-app), secrets management (encrypted at rest, injected as env vars), private networking via WireGuard mesh (6PN), and TLS certificate management. A leaked deploy token can push arbitrary code to production machines across all regions.
API Key Management
function validateFlyToken(): void {
const token = process.env.FLY_API_TOKEN;
if (!token) {
throw new Error("Missing FLY_API_TOKEN — use `fly tokens create deploy -a <app>`");
}
// Never log tokens; log only token type for debugging
const isDeployToken = token.startsWith("FlyV1");
console.log("Fly.io token loaded, type:", isDeployToken ? "deploy" : "personal");
}
Webhook Signature Verification
import crypto from "crypto";
import { Request, Response, NextFunction } from "express";
function verifyFlyWebhook(req: Request, res: Response, next: NextFunction): void {
const signature = req.headers["x-fly-signature"] as string;
const secret = process.env.FLY_WEBHOOK_SECRET!;
const expected = crypto.createHmac("sha256", secret).update(req.body).digest("hex");
if (!signature || !crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
res.status(401).send("Invalid signature");
return;
}
next();
}
Input Validation
import { z } from "zod";
const FlyDeploySchema = z.object({
app_name: z.string().regex(/^[a-z0-9-]+$/).max(63),
region: z.enum(["iad", "ord", "lax", "sjc", "ams", "lhr", "nrt", "syd", "gru"]),
image: z.string().regex(/^registry\..+\/.+:.+$/),
vm_size: z.enum(["shared-cpu-1x", "shared-cpu-2x", "performance-1x", "performance-2x"]).optional(),
min_machines: z.number().int().min(0).max(20).optional(),
});
function validateDeployConfig(data: unknown) {
return FlyDeploySchema.parse(data);
}
Data Protection
const FLY_SENSITIVE_FIELDS = ["fly_api_token", "deploy_token", "db_password", "wireguard_private_key", "tls_private_key"];
function redactFlyLog(record: Record<string, unknown>): Record<string, unknown> {
const redacted = { ...record };
for (const field of FLY_SENSITIVE_FIELDS) {
if (field in redacted) redacted[field] = "[REDACTED]";
}
return redacted;
}
Security Checklist
- All sensitive values in
fly secrets, never in[env]section of fly.toml - Deploy tokens scoped per-app, not org-wide
-
force_https = trueset in fly.toml[http_service] - Internal services use
.internalDNS with no public ports - WireGuard keys rotated and unused tunnels removed
- Secrets rotated on schedule (triggers rolling restart)
- CI/CD uses deploy-scoped tokens, not personal tokens
- Container images scanned before deployment
Error Handling
| Vulnerability | Risk | Mitigation |
|---|---|---|
| Leaked deploy token | Arbitrary code deployed to production | Per-app scoped tokens + rotation |
Secrets in fly.toml [env] | Plaintext credentials in version control | Use fly secrets set exclusively |
| Open internal ports | Services exposed to public internet | .internal DNS + NetworkPolicy |
| Org-wide token in CI | All apps in org compromised via CI breach | Deploy-scoped tokens per pipeline |
| Expired TLS certificates | MITM attacks on custom domains | Automated Let's Encrypt renewal |
Resources
Next Steps
See flyio-prod-checklist.