agentsclimarketplace

Webflow security basics

Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/webflow-pack/skills/webflow-security-basics

425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.

Install
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill webflow-security-basics

Assembled 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 Webflow API security best practices \u2014 token management, scope\ \ least privilege, OAuth 2.0 secret rotation, webhook signature verification, and\ \ audit logging. Use when securing API tokens, implementing least privilege access, \ or auditing Webflow security configuration. Trigger with phrases like "webflow\ \ security", "webflow secrets", "secure webflow", "webflow API key security"\ , "webflow token rotation".

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

7.5 KB, as published. Nobody here has run it

Webflow Security Basics

Overview

Security best practices for Webflow Data API v2 tokens, OAuth secrets, webhook verification, and access control. Covers the full lifecycle from token creation to rotation and revocation.

Prerequisites

  • Webflow developer account at developers.webflow.com
  • Understanding of environment variables
  • Secret management solution (vault, cloud secret manager, etc.)

Instructions

Step 1: Token Types and Selection

Token TypeScopeBest For
Workspace TokenAll sites in workspaceInternal tools, scripts
Site TokenSingle site onlySingle-site integrations
OAuth Access TokenUser-authorized scopesPublic apps, marketplace apps

Rule: Never use a workspace token where a site token would suffice.

Step 2: Least Privilege Scopes

Only request scopes your integration actually needs:

OperationMinimum Scope
Read site infosites:read
Publish sitesites:write
Read CMS contentcms:read
Create/update CMS itemscms:write
Read pagespages:read
Read form submissionsforms:read
Read products/ordersecommerce:read
Create products, fulfill ordersecommerce:write
// Example: Read-only integration needs only these scopes
const READ_ONLY_SCOPES = "sites:read cms:read pages:read forms:read";

// CMS sync integration
const CMS_SYNC_SCOPES = "sites:read cms:read cms:write";

// Full ecommerce integration
const ECOMMERCE_SCOPES = "sites:read ecommerce:read ecommerce:write";

Step 3: Secure Token Storage

# .gitignore — MANDATORY
.env
.env.local
.env.*.local
*.pem
*.key

# .env.local (never committed)
WEBFLOW_API_TOKEN=your-token-here
WEBFLOW_WEBHOOK_SECRET=your-webhook-secret
WEBFLOW_OAUTH_CLIENT_SECRET=your-oauth-secret
// Load from environment, never hardcode
import { WebflowClient } from "webflow-api";

function createClient(): WebflowClient {
  const token = process.env.WEBFLOW_API_TOKEN;
  if (!token) {
    throw new Error(
      "WEBFLOW_API_TOKEN not set. " +
      "Generate at https://developers.webflow.com"
    );
  }
  return new WebflowClient({ accessToken: token });
}

Step 4: Secret Rotation Procedure

# 1. Generate new token at developers.webflow.com
#    (old token remains valid until revoked)

# 2. Update secret in your deployment platform
# Vercel
vercel env rm WEBFLOW_API_TOKEN production
vercel env add WEBFLOW_API_TOKEN production

# Fly.io
fly secrets set WEBFLOW_API_TOKEN=new-token-here

# GCP Secret Manager
echo -n "new-token-here" | \
  gcloud secrets versions add webflow-api-token --data-file=-

# AWS Secrets Manager
aws secretsmanager update-secret \
  --secret-id webflow/api-token \
  --secret-string "new-token-here"

# 3. Verify new token works
curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer $NEW_TOKEN" \
  https://api.webflow.com/v2/sites

# 4. Revoke old token in Webflow dashboard
# 5. Monitor for 401 errors in logs

Step 5: Environment-Specific Keys

// Use different tokens per environment
const TOKEN_MAP: Record<string, string> = {
  development: "WEBFLOW_API_TOKEN_DEV",
  staging: "WEBFLOW_API_TOKEN_STAGING",
  production: "WEBFLOW_API_TOKEN_PROD",
};

function getToken(): string {
  const env = process.env.NODE_ENV || "development";
  const envVar = TOKEN_MAP[env] || TOKEN_MAP.development;
  const token = process.env[envVar];

  if (!token) throw new Error(`${envVar} not set for ${env} environment`);
  return token;
}

Step 6: Webhook Signature Verification

Webflow webhooks include a signature header for request verification:

import crypto from "crypto";

function verifyWebhookSignature(
  rawBody: Buffer | string,
  signature: string,
  secret: string
): boolean {
  if (!signature || !secret) return false;

  const expectedSignature = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");

  // Timing-safe comparison prevents timing attacks
  try {
    return crypto.timingSafeEqual(
      Buffer.from(signature),
      Buffer.from(expectedSignature)
    );
  } catch {
    return false; // Length mismatch
  }
}

// Express middleware
import express from "express";

app.post(
  "/webhooks/webflow",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.headers["x-webflow-signature"] as string;
    const secret = process.env.WEBFLOW_WEBHOOK_SECRET!;

    if (!verifyWebhookSignature(req.body, signature, secret)) {
      console.error("Webhook signature verification failed");
      return res.status(401).json({ error: "Invalid signature" });
    }

    const event = JSON.parse(req.body.toString());
    // Process verified event...
    res.status(200).json({ received: true });
  }
);

Step 7: Audit Logging

interface WebflowAuditEntry {
  timestamp: string;
  operation: string;
  method: string;
  endpoint: string;
  statusCode: number;
  tokenType: "workspace" | "site" | "oauth";
  environment: string;
  durationMs: number;
}

function logApiCall(entry: WebflowAuditEntry): void {
  // Structured JSON log — ship to your logging platform
  console.log(JSON.stringify({
    level: entry.statusCode >= 400 ? "error" : "info",
    service: "webflow-integration",
    ...entry,
  }));
}

Security Checklist

  • API tokens stored in environment variables, never in code
  • .env files in .gitignore
  • Different tokens for dev/staging/production
  • Minimal scopes per token (least privilege)
  • Webhook signatures verified on every request
  • Timing-safe comparison for signature checks
  • Token rotation procedure documented and tested
  • Audit logging enabled for all API calls
  • No tokens in client-side code (tokens are server-side only)
  • Git history scanned for accidentally committed tokens

Output

  • Secure token storage with environment isolation
  • Least privilege scope selection
  • Webhook signature verification
  • Token rotation procedure
  • Audit logging for compliance

Error Handling

Security IssueDetectionMitigation
Token in git historygit log -p | grep WEBFLOWRevoke token immediately, rotate
Excessive scopesReview at developers.webflow.comGenerate new token with minimal scopes
Missing webhook verificationNo signature check in codeAdd verifyWebhookSignature()
Token never rotatedNo rotation logSchedule quarterly rotation

Resources

Next Steps

For production deployment, see webflow-prod-checklist.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.