shopify-policy-guardrails

Implement Shopify app policy enforcement with ESLint rules for API key detection, query cost budgets, and App Store compliance checks. Trigger with phrases like "shopify policy", "shopify lint", "shopify guardrails", "shopify compliance", "shopify eslint", "shopify app review".

1,868 stars

Best use case

shopify-policy-guardrails is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Implement Shopify app policy enforcement with ESLint rules for API key detection, query cost budgets, and App Store compliance checks. Trigger with phrases like "shopify policy", "shopify lint", "shopify guardrails", "shopify compliance", "shopify eslint", "shopify app review".

Teams using shopify-policy-guardrails should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/shopify-policy-guardrails/SKILL.md --create-dirs "https://raw.githubusercontent.com/jeremylongshore/claude-code-plugins-plus-skills/main/plugins/saas-packs/shopify-pack/skills/shopify-policy-guardrails/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/shopify-policy-guardrails/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How shopify-policy-guardrails Compares

Feature / Agentshopify-policy-guardrailsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Implement Shopify app policy enforcement with ESLint rules for API key detection, query cost budgets, and App Store compliance checks. Trigger with phrases like "shopify policy", "shopify lint", "shopify guardrails", "shopify compliance", "shopify eslint", "shopify app review".

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Shopify Policy & Guardrails

## Overview

Automated policy enforcement for Shopify apps: secret detection, query cost budgets, App Store compliance checks, and CI policy validation.

## Prerequisites

- ESLint configured in project
- Pre-commit hooks infrastructure
- CI/CD pipeline with GitHub Actions
- Shopify app with `shopify.app.toml`

## Instructions

### Step 1: Secret Detection Rules

```javascript
// eslint-rules/no-shopify-secrets.js
module.exports = {
  meta: {
    type: "problem",
    docs: { description: "Detect hardcoded Shopify tokens and secrets" },
    messages: {
      adminToken: "Hardcoded Shopify Admin API token detected (shpat_*)",
      apiSecret: "Potential Shopify API secret detected",
      storefrontToken: "Hardcoded Storefront API token detected",
    },
  },
  create(context) {
    return {
      Literal(node) {
        if (typeof node.value !== "string") return;
        const v = node.value;

        // Admin API access token: shpat_ + 32 hex chars
        if (/^shpat_[a-f0-9]{32}$/i.test(v)) {
          context.report({ node, messageId: "adminToken" });
        }
        // Storefront token: shpss_ pattern
        if (/^shpss_[a-f0-9]{32}$/i.test(v)) {
          context.report({ node, messageId: "storefrontToken" });
        }
        // Generic secret pattern (32+ hex that's clearly a token)
        if (/^[a-f0-9]{32,}$/i.test(v) && v.length === 32) {
          context.report({ node, messageId: "apiSecret" });
        }
      },
      TemplateLiteral(node) {
        for (const quasi of node.quasis) {
          if (/shpat_[a-f0-9]/i.test(quasi.value.raw)) {
            context.report({ node, messageId: "adminToken" });
          }
        }
      },
    };
  },
};
```

### Step 2: Query Cost Budget Enforcement

```typescript
// Enforce query cost budgets at build/test time
interface QueryCostBudget {
  maxFirstParam: number;        // Max items per page
  maxNestedDepth: number;       // Max nested connection depth
  maxEstimatedCost: number;     // Max estimated query cost
}

const BUDGET: QueryCostBudget = {
  maxFirstParam: 100,           // Never request more than 100 items
  maxNestedDepth: 3,            // No more than 3 levels of edges/node
  maxEstimatedCost: 500,        // Stay well under 1,000 point limit
};

function validateQueryCost(query: string): string[] {
  const violations: string[] = [];

  // Check `first:` parameter values
  const firstParams = query.matchAll(/first:\s*(\d+)/g);
  for (const match of firstParams) {
    if (parseInt(match[1]) > BUDGET.maxFirstParam) {
      violations.push(
        `first: ${match[1]} exceeds budget of ${BUDGET.maxFirstParam}`
      );
    }
  }

  // Check nesting depth (count "edges { node {" patterns)
  const depth = (query.match(/edges\s*\{/g) || []).length;
  if (depth > BUDGET.maxNestedDepth) {
    violations.push(
      `Nesting depth ${depth} exceeds budget of ${BUDGET.maxNestedDepth}`
    );
  }

  // Estimate cost: multiply all `first` values along nested path
  const firstValues = [...query.matchAll(/first:\s*(\d+)/g)].map((m) =>
    parseInt(m[1])
  );
  const estimatedCost = firstValues.reduce((a, b) => a * b, 1);
  if (estimatedCost > BUDGET.maxEstimatedCost) {
    violations.push(
      `Estimated cost ${estimatedCost} exceeds budget of ${BUDGET.maxEstimatedCost}`
    );
  }

  return violations;
}
```

### Step 3: Pre-Commit Hooks

```yaml
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: shopify-token-scan
        name: Scan for Shopify tokens
        language: system
        entry: bash -c '
          if git diff --cached --diff-filter=d | grep -E "shpat_[a-f0-9]{32}|shpss_[a-f0-9]{32}" ; then
            echo "ERROR: Shopify access token detected in staged changes"
            exit 1
          fi'
        pass_filenames: false

      - id: shopify-env-check
        name: Check .env not staged
        language: system
        entry: bash -c '
          if git diff --cached --name-only | grep -E "^\.env$|^\.env\.local$|^\.env\.production$" ; then
            echo "ERROR: .env file staged for commit"
            exit 1
          fi'
        pass_filenames: false
```

### Step 4: App Store Compliance Checker

```typescript
// scripts/check-app-compliance.ts
// Run before submitting to Shopify App Store

interface ComplianceCheck {
  name: string;
  required: boolean;
  check: () => Promise<boolean>;
}

const checks: ComplianceCheck[] = [
  {
    name: "GDPR webhook: customers/data_request",
    required: true,
    check: async () => {
      const toml = await readFile("shopify.app.toml", "utf-8");
      return toml.includes("customers/data_request");
    },
  },
  {
    name: "GDPR webhook: customers/redact",
    required: true,
    check: async () => {
      const toml = await readFile("shopify.app.toml", "utf-8");
      return toml.includes("customers/redact");
    },
  },
  {
    name: "GDPR webhook: shop/redact",
    required: true,
    check: async () => {
      const toml = await readFile("shopify.app.toml", "utf-8");
      return toml.includes("shop/redact");
    },
  },
  {
    name: "No hardcoded tokens in source",
    required: true,
    check: async () => {
      const { execSync } = require("child_process");
      const result = execSync(
        'grep -rE "shpat_[a-f0-9]{32}" app/ --include="*.ts" --include="*.tsx" || true'
      ).toString();
      return result.trim() === "";
    },
  },
  {
    name: "CSP frame-ancestors header set",
    required: true,
    check: async () => {
      const files = await glob("app/**/*.ts");
      const hasCSP = files.some((f) => {
        const content = readFileSync(f, "utf-8");
        return content.includes("frame-ancestors");
      });
      return hasCSP;
    },
  },
  {
    name: "API version is not unstable",
    required: true,
    check: async () => {
      const toml = await readFile("shopify.app.toml", "utf-8");
      return !toml.includes('api_version = "unstable"');
    },
  },
];

async function runComplianceChecks(): Promise<void> {
  console.log("=== Shopify App Store Compliance Check ===\n");
  let passed = 0;
  let failed = 0;

  for (const check of checks) {
    const result = await check.check();
    const status = result ? "PASS" : check.required ? "FAIL" : "WARN";
    console.log(`${status}: ${check.name}`);
    result ? passed++ : failed++;
  }

  console.log(`\n${passed} passed, ${failed} failed`);
  if (failed > 0) process.exit(1);
}
```

### Step 5: CI Policy Pipeline

```yaml
# .github/workflows/shopify-policy.yml
name: Shopify Policy

on: [push, pull_request]

jobs:
  policy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Scan for hardcoded Shopify tokens
        run: |
          if grep -rE "shpat_[a-f0-9]{32}|shpss_[a-f0-9]{32}" \
            --include="*.ts" --include="*.tsx" --include="*.js" \
            app/ src/ ; then
            echo "::error::Hardcoded Shopify tokens found!"
            exit 1
          fi

      - name: Check GDPR webhooks configured
        run: |
          for topic in "customers/data_request" "customers/redact" "shop/redact"; do
            if ! grep -q "$topic" shopify.app.toml; then
              echo "::error::Missing mandatory GDPR webhook: $topic"
              exit 1
            fi
          done
          echo "All GDPR webhooks configured"

      - name: Validate API version
        run: |
          VERSION=$(grep 'api_version' shopify.app.toml | head -1 | grep -oP '\d{4}-\d{2}')
          if [ "$VERSION" = "unstable" ]; then
            echo "::error::Cannot use unstable API version"
            exit 1
          fi
          echo "API version: $VERSION"
```

## Output

- ESLint rules catching hardcoded tokens
- Query cost budgets enforced
- Pre-commit hooks blocking secret leaks
- App Store compliance checker
- CI policy pipeline preventing violations

## Error Handling

| Issue | Cause | Solution |
|-------|-------|----------|
| False positive on token | Base64 string matched | Narrow regex pattern |
| Query cost estimate wrong | Complex variable nesting | Use actual debug header in tests |
| Pre-commit bypassed | `--no-verify` flag | Enforce in CI as backup |
| App Store rejection | Missing GDPR webhook | Run compliance checker before submit |

## Examples

### Quick Policy Scan

```bash
# One-liner: check for token leaks in staged changes
git diff --cached | grep -E "shpat_|shpss_" && echo "TOKEN LEAK!" || echo "Clean"

# Check GDPR compliance
grep -c "customers/data_request\|customers/redact\|shop/redact" shopify.app.toml
# Should output: 3
```

## Resources

- [Shopify App Store Requirements](https://shopify.dev/docs/apps/launch/app-requirements)
- [ESLint Plugin Development](https://eslint.org/docs/latest/extend/plugins)
- [git-secrets](https://github.com/awslabs/git-secrets)

## Next Steps

For architecture blueprints, see `shopify-architecture-variants`.

Related Skills

windsurf-policy-guardrails

1868
from jeremylongshore/claude-code-plugins-plus-skills

Implement team-wide Windsurf usage policies, code quality gates, and Cascade guardrails. Use when setting up code review policies for AI-generated code, configuring Turbo mode safety controls, or implementing CI gates for Cascade output. Trigger with phrases like "windsurf policy", "windsurf guardrails", "cascade safety rules", "windsurf team rules", "AI code policy".

vercel-policy-guardrails

1868
from jeremylongshore/claude-code-plugins-plus-skills

Implement lint rules, CI policy checks, and automated guardrails for Vercel projects. Use when setting up code quality rules, preventing secret exposure, or enforcing deployment policies for Vercel applications. Trigger with phrases like "vercel policy", "vercel lint", "vercel guardrails", "vercel best practices check", "vercel secret scan".

supabase-policy-guardrails

1868
from jeremylongshore/claude-code-plugins-plus-skills

Enforce organizational governance for Supabase projects: shared RLS policy library with reusable templates, table and column naming conventions, migration review process with CI checks, cost alert thresholds, and security audit scripts scanning for common misconfigurations. Use when establishing Supabase standards across teams, creating RLS policy templates, setting up migration review workflows, or auditing existing projects for security and cost issues. Trigger with phrases like "supabase governance", "supabase policy library", "supabase naming convention", "supabase migration review", "supabase cost alert", "supabase security audit", "supabase RLS template".

snowflake-policy-guardrails

1868
from jeremylongshore/claude-code-plugins-plus-skills

Implement Snowflake governance guardrails with network rules, session policies, authentication policies, and automated compliance checks. Use when enforcing security policies, implementing data governance, or configuring automated compliance for Snowflake. Trigger with phrases like "snowflake policy", "snowflake guardrails", "snowflake governance", "snowflake compliance", "snowflake enforce".

shopify-upgrade-migration

1868
from jeremylongshore/claude-code-plugins-plus-skills

Upgrade Shopify API versions and migrate from REST to GraphQL with breaking change detection. Use when upgrading API versions, migrating from deprecated REST endpoints, or handling Shopify's quarterly API release cycle. Trigger with phrases like "upgrade shopify", "shopify API version", "shopify breaking changes", "migrate REST to GraphQL", "shopify deprecation".

shopify-security-basics

1868
from jeremylongshore/claude-code-plugins-plus-skills

Apply Shopify security best practices for API credentials, webhook HMAC validation, and access scope management. Use when securing API keys, validating webhook signatures, or auditing Shopify security configuration. Trigger with phrases like "shopify security", "shopify secrets", "secure shopify", "shopify HMAC", "shopify webhook verify".

shopify-sdk-patterns

1868
from jeremylongshore/claude-code-plugins-plus-skills

Apply production-ready patterns for @shopify/shopify-api including typed GraphQL clients, session management, and retry logic. Use when implementing Shopify integrations, refactoring SDK usage, or establishing team coding standards for Shopify. Trigger with phrases like "shopify SDK patterns", "shopify best practices", "shopify code patterns", "idiomatic shopify", "shopify client wrapper".

shopify-reliability-patterns

1868
from jeremylongshore/claude-code-plugins-plus-skills

Implement reliability patterns for Shopify apps including circuit breakers for API outages, webhook retry handling, and graceful degradation. Trigger with phrases like "shopify reliability", "shopify circuit breaker", "shopify resilience", "shopify fallback", "shopify retry webhook".

shopify-reference-architecture

1868
from jeremylongshore/claude-code-plugins-plus-skills

Implement Shopify app reference architecture with Remix, Prisma session storage, and the official app template patterns. Trigger with phrases like "shopify architecture", "shopify app structure", "shopify project layout", "shopify Remix template", "shopify app design".

shopify-rate-limits

1868
from jeremylongshore/claude-code-plugins-plus-skills

Handle Shopify API rate limits for both REST (leaky bucket) and GraphQL (calculated query cost). Use when hitting 429 errors, implementing retry logic, or optimizing API request throughput. Trigger with phrases like "shopify rate limit", "shopify throttling", "shopify 429", "shopify THROTTLED", "shopify query cost", "shopify backoff".

shopify-prod-checklist

1868
from jeremylongshore/claude-code-plugins-plus-skills

Execute Shopify app production deployment checklist covering App Store requirements, mandatory webhooks, API versioning, and rollback procedures. Trigger with phrases like "shopify production", "deploy shopify", "shopify go-live", "shopify launch checklist", "shopify app store submit".

shopify-performance-tuning

1868
from jeremylongshore/claude-code-plugins-plus-skills

Optimize Shopify API performance with GraphQL query cost reduction, bulk operations, caching strategies, and Storefront API for high-traffic storefronts. Trigger with phrases like "shopify performance", "optimize shopify", "shopify slow", "shopify caching", "shopify bulk operation", "shopify query cost".