April 11, 2026

How I Built a Full-Stack Security Audit Skill for Claude Code

Introduction "I want to run a security audit, but every time I have to start from...

By toshipon (@toshipon) • 6 min read
How I Built a Full-Stack Security Audit Skill for Claude Code

Introduction

"I want to run a security audit, but every time I have to start from zero."

That feeling gets old fast when you're building across a full-stack setup like Vercel + Supabase + Next.js + iOS. Each layer comes with its own security concerns, and just remembering what to check can be exhausting.

OWASP guidelines are comprehensive, but they’re also huge. And some critical settings — especially in Vercel and Supabase dashboards — can’t be fully inspected from the CLI alone.

So I built a Claude Code Custom Skill called security-audit.

Claude Code Custom Skills let you package reusable procedures and domain knowledge for a specific task. Instead of reconstructing the audit process from memory every time, I can now run a reproducible 6-phase full-stack security review from Next.js to iOS with a single command:

/security-audit all
Enter fullscreen mode Exit fullscreen mode

The key difference is that it doesn’t stop at CLI and SQL checks. It also uses Chrome MCP to inspect dashboard-only settings automatically.

What the Finished Skill Looks Like

/security-audit              # Choose target interactively
/security-audit all          # Full-stack end-to-end audit (recommended)
/security-audit nextjs       # Next.js application only
/security-audit vercel       # Vercel infrastructure only
/security-audit supabase     # Supabase backend only
/security-audit ios          # iOS app only
/security-audit web          # Next.js + Vercel + Supabase
Enter fullscreen mode Exit fullscreen mode

This is the part I like most: it turns a vague, easy-to-postpone task into something I can actually run on demand.
Instead of thinking, "I should probably do a security review soon," I can just start from a standard entry point and let the process unfold.

The Skill is structured into six phases:

Phase Focus Main inspection methods
1. Information Gathering Project structure, trust boundaries, data flows Grep / Glob
2. Next.js Audit Server Actions, Middleware, CVEs Grep / Bash
3. Vercel Audit Env vars, Deployment Protection, WAF CLI + Chrome MCP
4. Supabase Audit RLS, function privileges, Auth settings SQL + Chrome MCP
5. iOS Audit Keychain, ATS, biometrics Grep / Bash
6. Cross-Layer Analysis Auth flow consistency, token lifecycle Cross-cutting review

Phase Structure

Phase 1: Information Gathering
    │
    ├── Phase 2: Next.js Application
    │   Server Actions / Middleware / CSP / CVE
    │
    ├── Phase 3: Vercel Infrastructure
    │   Env vars (CLI) / Deployment Protection (Chrome MCP)
    │   / WAF (Chrome MCP) / Git Fork Protection (Chrome MCP)
    │
    ├── Phase 4: Supabase Backend
    │   RLS (SQL) / Function privileges (SQL) / Auth settings (Chrome MCP)
    │   / Security Advisor (Chrome MCP)
    │
    ├── Phase 5: iOS App
    │   Keychain / ATS / Biometrics / Privacy Manifest
    │
    └── Phase 6: Cross-Layer Analysis
        Auth flow consistency / token lifecycle
        / API transport security / continuity of data protection
Enter fullscreen mode Exit fullscreen mode

How I Built It in 3 Steps

Step 1: Research — learn from the best existing Skills

I didn’t start by writing.
I started by studying the best Skills I could find.

Resource What I learned
Trail of Bits skills (4.5k stars) A Skill should stay focused on one responsibility. Reference files should be separated out.
Anthropic best practices Keep SKILL.md under ~500 lines, use progressive disclosure, write in imperative form
SecOpsAgentKit Organizing by domain makes complex security workflows easier to navigate

Step 2: Design — three core principles

  1. Progressive Disclosure

    SKILL.md should contain only the overview and phase structure. Detailed inspection patterns belong in references/ and should be loaded only when needed.

  2. Evidence-First

    Not "this might be vulnerable," but "this grep pattern found this code, and here is why it’s risky."

  3. Use OWASP directly

    Instead of inventing custom categories, I adopted OWASP Top 10:2025, WSTG, and MASVS v2 as-is.

Step 3: Implementation — a 6-file structure

~/.claude/skills/security-audit/
├── SKILL.md                              # Main entry (overview + phase structure)
└── references/
    ├── nextjs-security.md                # Next.js-specific inspection patterns
    ├── vercel-security.md                # Vercel CLI + Chrome MCP checks
    ├── supabase-security.md              # Supabase SQL + Chrome MCP checks
    ├── ios-testing.md                    # MASVS v2 categories
    └── web-testing.md                    # OWASP WSTG + Top 10:2025
Enter fullscreen mode Exit fullscreen mode

Why Chrome MCP Matters

One of the biggest strengths of this Skill is that it uses Chrome MCP to inspect settings that the CLI can’t access.

For example, Vercel’s Deployment Protection and some Supabase Auth settings are only partially available via CLI or API. With Chrome MCP, the agent can navigate those dashboards, inspect toggle states, and capture screenshots as evidence.

# Vercel example
navigate_page -> /settings/deployment-protection
take_screenshot -> record evidence
evaluate_script -> extract toggle states and protection scope

# Supabase example
navigate_page -> /database/security-advisor
take_screenshot -> record all findings
take_snapshot -> inspect details via accessibility tree
Enter fullscreen mode Exit fullscreen mode
Target Available via CLI/SQL Requires Chrome MCP
Vercel environment variable list vercel env ls -
Deployment Protection - Toggle state on settings page
Supabase RLS state pg_class queries -
Supabase Auth settings - MFA, email confirmation, rate limits
Supabase Security Advisor - Full lint findings

Why a Skill Instead of One Long Prompt?

At first, I thought I could just write one long audit prompt.

But in practice, turning it into a Skill was much more manageable.

  • Reusable: /security-audit all always starts from the same reliable entry point
  • Modular: SKILL.md and references/ separate responsibilities cleanly
  • Standardized: The order of inspection and evaluation criteria stays consistent
  • Target-aware: It can branch into nextjs, vercel, supabase, or ios
  • Higher audit consistency: It follows predefined criteria instead of improvising every time

In other words, I didn’t turn this into a Skill just for convenience.
I did it to improve the reproducibility of the audit itself.

Key Design Decisions

Progressive Disclosure

This is the pattern Anthropic emphasizes most strongly.
Claude’s context window is a shared resource, so if you cram everything into SKILL.md, it competes with the rest of the task.

SKILL.md (always loaded)
  -> overview + phase structure + report format

references/ (loaded only when needed)
  -> nextjs-security.md: Next.js-specific inspection patterns
  -> vercel-security.md: Vercel dashboard inspection steps
  -> supabase-security.md: SQL queries + dashboard checks
  -> ios-testing.md: MASVS v2 commands
  -> web-testing.md: WSTG commands
Enter fullscreen mode Exit fullscreen mode

Evidence-First

This came directly from studying the Trail of Bits Skills.
Every inspection item should include concrete bash, grep, or SQL commands.

-- Tables in public schema with RLS disabled (Critical)
SELECT n.nspname AS schema, c.relname AS table_name
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
  AND n.nspname = 'public'
  AND c.relrowsecurity = false;
Enter fullscreen mode Exit fullscreen mode

Direct OWASP Adoption

I chose not to invent any custom taxonomy.
Instead, I used the standard frameworks directly:

  • Web: OWASP Top 10:2025 + WSTG
  • iOS: MASVS v2 + MASTG
  • Shared vocabulary: CWE for vulnerability classification

The biggest advantage is obvious: it gives your team and external reviewers a common language.

Anti-Patterns I Learned from Anthropic’s Best Practices

Anti-pattern Example Better approach
Vague description "A security-related skill" Include explicit trigger phrases
Overloaded SKILL.md One file with 3,000+ lines Split detailed content into references/
Second-person instructions "You should check..." Use imperative form: "Check..."
Deep reference chains A -> B -> C -> D Keep references to one level
Choices with no default "Choose one of the following..." Recommend a default (all)
No concrete inspection method "Check RLS" Attach exact SQL queries

Results

Turning full-stack security auditing into a Claude Code Custom Skill gave me several clear benefits:

  1. Reproducibility: the same six-phase audit runs with consistent quality every time
  2. Coverage: OWASP categories are mapped across four layers — Next.js, Vercel, Supabase, and iOS
  3. Efficiency: /security-audit all triggers a full-stack audit in one command
  4. Automation: CLI/SQL for machine-readable checks, Chrome MCP for dashboard-only settings
  5. Shared language: OWASP-aligned findings are easier to discuss with other engineers and reviewers

The most important thing in Skill design is not starting to write too early.
Study the best existing examples first. Define your principles — especially Progressive Disclosure and Evidence-First — and only then implement.

That’s what turns a one-off prompt into something you can actually keep using.

Skill Files

I also published the full Skill files on GitHub:

The article only covers the core ideas, but the full files are ready to drop into:

~/.claude/skills/security-audit/
Enter fullscreen mode Exit fullscreen mode

If you're building with a similar stack, you can use it as-is or adapt the phase structure to your own environment.
The main value is not the exact wording of the Skill — it's having a repeatable audit workflow that doesn't depend on memory.

References

Ready to build your next web project? Let's work together.