supabase-extract-service-key
CRITICAL - Detect if the Supabase service_role key is leaked in client-side code. This is a P0 severity issue.
What this skill does
# Supabase Service Key Detection
> ๐ด **CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED**
>
> You MUST write to context files **AS YOU GO**, not just at the end.
> - Write to `.sb-pentest-context.json` **IMMEDIATELY after each discovery**
> - Log to `.sb-pentest-audit.log` **BEFORE and AFTER each action**
> - **DO NOT** wait until the skill completes to update files
> - If the skill crashes or is interrupted, all prior findings must already be saved
>
> **This is not optional. Failure to write progressively is a critical error.**
This skill detects if the **service_role key** (admin key) is accidentally exposed in client-side code.
## When to Use This Skill
- As part of every security audit (this is critical)
- When reviewing code before production deployment
- After detecting Supabase usage to check for this common mistake
## Prerequisites
- Target application accessible
- Supabase detection completed (auto-invokes if needed)
## Why This Is Critical
The **service_role key** bypasses ALL Row Level Security (RLS) policies. If exposed:
| Impact | Description |
|--------|-------------|
| ๐ด Full DB Access | Read/write/delete all data in all tables |
| ๐ด Auth Bypass | Access all user data without authentication |
| ๐ด Storage Access | Read/write all files in all buckets |
| ๐ด User Impersonation | Generate tokens for any user |
**This is a P0 (Critical) finding that requires immediate action.**
## Service Key vs Anon Key
| Aspect | Anon Key | Service Key |
|--------|----------|-------------|
| Role claim | `"role": "anon"` | `"role": "service_role"` |
| RLS | โ
Respects RLS | โ Bypasses RLS |
| Client-side | โ
Expected | โ NEVER |
| Server-side | โ
Can use | โ
Should use |
## Detection Patterns
The skill searches for:
### 1. Key with service_role Claim
```javascript
// Decoded JWT payload contains:
{
"role": "service_role", // โ CRITICAL if in client code
"iss": "supabase",
"ref": "abc123def"
}
```
### 2. Variable Names
```javascript
// Common naming patterns
SUPABASE_SERVICE_KEY
SUPABASE_SERVICE_ROLE_KEY
SUPABASE_ADMIN_KEY
SUPABASE_SECRET_KEY
SERVICE_ROLE_KEY
```
### 3. Accidental Exposure
```javascript
// Sometimes exposed alongside anon key
const keys = {
anon: 'eyJ...',
service: 'eyJ...' // โ Should not be here
}
```
## Usage
### Basic Check
```
Check for service key leak on https://myapp.example.com
```
### Deep Scan
```
Deep scan for service key exposure on https://myapp.example.com
```
## Output Format
### No Service Key Found (Good)
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
SERVICE KEY CHECK
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Status: โ
No service_role key detected in client code
Scanned:
โโโ HTML source: Clean
โโโ JavaScript bundles: 5 files, 2.3MB analyzed
โโโ Inline scripts: 12 blocks checked
โโโ Source maps: Not exposed (good)
JWT Analysis:
โโโ 1 key found, confirmed role=anon (safe)
Result: PASS - No critical key exposure
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
### Service Key FOUND (Critical)
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ด CRITICAL: SERVICE KEY EXPOSED
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Severity: P0 - CRITICAL
Status: โ service_role key found in client-side code!
โ ๏ธ IMMEDIATE ACTION REQUIRED โ ๏ธ
Exposed Key:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBh
YmFzZSIsInJlZiI6ImFiYzEyM2RlZiIsInJvbGUiOiJzZXJ2aWNlX3
JvbGUiLCJpYXQiOjE2NDAwMDAwMDAsImV4cCI6MTk1NTM2MDAwMH0
.xxxxxxxxxxxxx
Location:
โโโ /static/js/admin.chunk.js (line 89)
const SUPABASE_KEY = 'eyJhbG...' // Used in createClient()
Decoded Payload:
โโโ role: service_role โ CRITICAL
โโโ ref: abc123def
โโโ exp: 2031-12-20
Impact Assessment:
โโโ ๐ด Full database access possible
โโโ ๐ด All RLS policies bypassed
โโโ ๐ด All user data exposed
โโโ ๐ด All storage buckets accessible
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
IMMEDIATE REMEDIATION STEPS
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
1. ROTATE THE KEY NOW
โ Supabase Dashboard > Settings > API > Regenerate service_role key
2. REMOVE FROM CLIENT CODE
โ Delete the key from your source code
โ Redeploy your application
3. AUDIT FOR ABUSE
โ Check Supabase logs for unauthorized access
โ Review database for unexpected changes
4. USE EDGE FUNCTIONS
โ Move privileged operations to Edge Functions
โ Client calls Edge Function, which uses service key server-side
Documentation:
โ https://supabase.com/docs/guides/api/api-keys
โ https://supabase.com/docs/guides/functions
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
## Context Output
Saved to `.sb-pentest-context.json`:
```json
{
"findings": [
{
"id": "SERVICE_KEY_EXPOSED",
"severity": "P0",
"title": "Service Role Key Exposed in Client Code",
"description": "The service_role key was found in client-side JavaScript",
"location": {
"file": "/static/js/admin.chunk.js",
"line": 89
},
"evidence": {
"key_prefix": "eyJhbGciOiJIUzI1NiI...",
"role": "service_role",
"project_ref": "abc123def"
},
"remediation": {
"immediate": "Rotate key in Supabase Dashboard",
"long_term": "Move to Edge Functions",
"docs": "https://supabase.com/docs/guides/api/api-keys"
}
}
],
"supabase": {
"service_key_exposed": true,
"service_key_location": "/static/js/admin.chunk.js:89"
}
}
```
## Source Maps Check
The skill also checks for exposed source maps that might reveal keys:
```
Source Maps Analysis:
โโโ main.js.map: โ Exposed (may contain secrets)
โโโ vendor.js.map: โ Exposed
โโโ Recommendation: Disable source maps in production
To check source maps content:
โ Add .map to JS URLs: /static/js/main.js.map
```
## Common Causes
| Cause | Solution |
|-------|----------|
| Wrong env variable | Use `NEXT_PUBLIC_` only for anon key |
| Copy-paste error | Double-check which key you're using |
| Debug code left in | Remove before production build |
| Misconfigured bundler | Ensure service key env vars are not included |
## Remediation Code Examples
### Before (Wrong)
```javascript
// โ WRONG - Service key in client
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_SERVICE_KEY // โ NEVER DO THIS
)
```
### After (Correct)
```javascript
// โ
CORRECT - Only anon key in client
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY // โ
Safe for client
)
// For privileged operations, call an Edge Function:
const { data } = await supabase.functions.invoke('admin-action', {
body: { action: 'delete-user', userId: '123' }
})
```
### Edge Function (Server-Side)
```typescript
// supabase/functions/admin-action/index.ts
import { createClient } from '@supabase/supabase-js'
Deno.serve(async (req) => {
// โ
Service key only on server
const supabase = createClient(
Deno.env.get('SUPABASE_URL'),
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') // โ
Safe on server
)
// Perform privileged operation
// ...
})
```
## MANDATORY: Progressive Context File Updates
โ ๏ธ **This skill MUST update tracking files PROGRESSIVELY during execution, NOT just at the end.**
### Critical Rule: Write As You Go
**DO NOT** batch all writes at the end. Instead:
1. **Before starting any action** โ Log the action to `.sb-pentest-audit.log`
2. **After each discovery** โ Immediately update `.sb-pentest-context.json`
3. **After each significant step** โ Log completion to `.sb-pentest-audit.log`
This ensures that if the skill is interrupted, crashes, or times out, all findings up to that point are preserved.
### Required Actions (Progressive)
1. **Update `.sb-pentest-conRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.