From shopify-commerce
Secures Shopify apps via HMAC webhook verification, session token validation, OAuth scope checks, CSP headers, GDPR webhooks, and input sanitization.
npx claudepluginhub orcaqubits/agentic-commerce-skills-plugins --plugin shopify-commerceThis skill is limited to using the following tools:
**Fetch live docs**:
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides MCP server integration in Claude Code plugins via .mcp.json or plugin.json configs for stdio, SSE, HTTP types, enabling external services as tools.
Fetch live docs:
site:shopify.dev security best practices for security guidelinessite:shopify.dev webhook verification hmac for HMAC implementationsite:shopify.dev session token for session token verificationEvery webhook includes X-Shopify-Hmac-SHA256:
import crypto from 'crypto';
function verifyShopifyWebhook(
rawBody: Buffer,
hmacHeader: string,
secret: string,
): boolean {
const calculated = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('base64');
return crypto.timingSafeEqual(
Buffer.from(calculated),
Buffer.from(hmacHeader),
);
}
Critical: Use timingSafeEqual to prevent timing attacks. Use raw body buffer, not parsed JSON.
For embedded apps using App Bridge:
import jwt from 'jsonwebtoken';
function verifySessionToken(token: string, apiSecret: string) {
const decoded = jwt.verify(token, apiSecret, {
algorithms: ['HS256'],
});
// Verify issuer is a valid Shopify shop
const iss = decoded.iss as string;
if (!iss.match(/^https:\/\/[a-zA-Z0-9-]+\.myshopify\.com\/admin$/)) {
throw new Error('Invalid issuer');
}
return decoded;
}
Session token claims:
iss — shop admin URLdest — shop URLsub — user IDexp — expiration (1 minute)nbf — not beforeiat — issued atjti — unique token IDVerify the access token has expected scopes:
For embedded apps in Shopify admin:
eval(), no external fonts without proper headersframe-ancestors header for iframe embedding:
Content-Security-Policy: frame-ancestors https://*.myshopify.com https://admin.shopify.com;
Every app MUST implement:
customers/data_request — respond within 30 days with customer datacustomers/redact — delete customer data within 30 daysshop/redact — delete ALL store data within 48 hours of uninstallFailing to implement these results in app rejection.
| escape filter to user-generated content| json filter for embedding data in JavaScriptcustomer data without escapinguserErrors in mutation responses.env files locally (excluded from version control)timingSafeEqual for all secret comparisonsnpm audit regularlyFetch the Shopify security documentation for exact HMAC implementation, session token structure, and CSP requirements before implementing.