supabase-extract-anon-key
Extract the Supabase anon/public API key from client-side code. This key is expected in client apps but important for RLS testing.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install yoanbernabeu-supabase-pentest-skills-supabase-extract-anon-key
Repository
Skill path: skills/extraction/supabase-extract-anon-key
Extract the Supabase anon/public API key from client-side code. This key is expected in client apps but important for RLS testing.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack, Backend, Testing.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: yoanbernabeu.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install supabase-extract-anon-key into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/yoanbernabeu/supabase-pentest-skills before adding supabase-extract-anon-key to shared team environments
- Use supabase-extract-anon-key for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: supabase-extract-anon-key
description: Extract the Supabase anon/public API key from client-side code. This key is expected in client apps but important for RLS testing.
---
# Supabase Anon Key Extraction
> π΄ **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 extracts the Supabase anonymous (public) API key from client-side code.
## When to Use This Skill
- After extracting the Supabase URL, to get the API key for testing
- To verify that only the anon key (not service key) is exposed
- Before running API audit skills that require authentication
## Prerequisites
- Supabase URL extracted (or will auto-invoke `supabase-extract-url`)
- Target application accessible
## Understanding Anon Keys
The **anon key** (also called public key) is:
- β
**Expected** to be in client-side code
- β
**Safe** when RLS (Row Level Security) is properly configured
- β οΈ **Risky** if RLS is missing or misconfigured
- β **Not the same** as the service_role key (which should NEVER be in client code)
### Key Format
Supabase anon keys are JWTs:
```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiYzEyMyIsInJvbGUiOiJhbm9uIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE5NTUzNjAwMDB9.xxxx
```
Key characteristics:
- Starts with `eyJ` (base64 encoded `{"alg":`)
- Contains `"role":"anon"` in payload
- Project reference in `"ref"` claim
## Extraction Patterns
The skill searches for:
### 1. Direct Key Assignment
```javascript
const SUPABASE_KEY = 'eyJhbGci...'
const SUPABASE_ANON_KEY = 'eyJhbGci...'
```
### 2. Client Initialization
```javascript
createClient(url, 'eyJhbGci...')
createClient(url, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY)
```
### 3. Environment Variable Patterns
```javascript
NEXT_PUBLIC_SUPABASE_ANON_KEY
VITE_SUPABASE_ANON_KEY
REACT_APP_SUPABASE_KEY
SUPABASE_KEY
```
## Usage
### Basic Extraction
```
Extract Supabase anon key from https://myapp.example.com
```
### If URL Already Known
```
Extract anon key for project abc123def
```
## Output Format
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ANON KEY EXTRACTED
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Type: anon (public)
Severity: βΉοΈ Expected (verify RLS configuration)
Key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJz
dXBhYmFzZSIsInJlZiI6ImFiYzEyM2RlZiIsInJvbGUiOiJhbm
9uIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE5NTUzNjAwMDB9
.xxxxxxxxxxxxx
Decoded Payload:
βββ iss: supabase
βββ ref: abc123def
βββ role: anon
βββ iat: 2021-12-20T00:00:00Z
βββ exp: 2031-12-20T00:00:00Z
Found in:
βββ /static/js/main.js (line 1253)
createClient('https://abc123def.supabase.co', 'eyJhbGci...')
Next Steps:
βββ Run supabase-audit-rls to test if RLS protects your data
βββ Run supabase-audit-tables-read to see what's accessible
βββ Run supabase-extract-service-key to check for critical leaks
Context updated: .sb-pentest-context.json
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
## Key Validation
The skill validates the extracted key:
```
Validation:
βββ Format: β
Valid JWT structure
βββ Decode: β
Payload readable
βββ Role: β
Confirmed "anon" role
βββ Project: β
Matches extracted URL (abc123def)
βββ Expiry: β
Not expired (expires 2031-12-20)
```
## Multiple Keys
If multiple keys are found:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
MULTIPLE KEYS FOUND
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β οΈ 2 potential Supabase keys detected
1. Anon Key (confirmed)
βββ Role: anon, Project: abc123def
2. Unknown Key
βββ Role: service_role β οΈ SEE supabase-extract-service-key
This may be a CRITICAL security issue!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
## Context Output
Saved to `.sb-pentest-context.json`:
```json
{
"supabase": {
"anon_key": "eyJhbGci...",
"anon_key_decoded": {
"iss": "supabase",
"ref": "abc123def",
"role": "anon",
"iat": 1640000000,
"exp": 1955360000
},
"anon_key_sources": [
{
"file": "/static/js/main.js",
"line": 1253
}
]
}
}
```
## Security Assessment
| Finding | Severity | Description |
|---------|----------|-------------|
| Anon key in client | βΉοΈ Info | Expected, but test RLS |
| Anon key expired | β οΈ P2 | Key should be rotated |
| Multiple anon keys | β οΈ P2 | May indicate key rotation issues |
| Role is not "anon" | π΄ P0 | Wrong key type exposed! |
## Common Issues
β **Problem:** Key found but won't decode
β
**Solution:** May be obfuscated or split. Try:
```
Extract anon key with deobfuscation from https://myapp.example.com
```
β **Problem:** Key doesn't match URL project
β
**Solution:** App may use multiple Supabase projects. Both keys are recorded.
β **Problem:** No key found but Supabase detected
β
**Solution:** Key may be fetched at runtime. Check network requests:
```
Monitor network for anon key on https://myapp.example.com
```
## Best Practices Reminder
For developers reading this report:
1. **Anon key in client is normal** β It's designed for this
2. **RLS is critical** β The anon key relies on RLS for security
3. **Never use service_role in client** β Use Edge Functions instead
4. **Rotate keys periodically** β Available in Supabase Dashboard
## 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-context.json`** with extracted data:
```json
{
"supabase": {
"anon_key": "eyJhbGci...",
"anon_key_decoded": { ... },
"anon_key_sources": [ ... ]
}
}
```
2. **Log to `.sb-pentest-audit.log`**:
```
[TIMESTAMP] [supabase-extract-anon-key] [START] Beginning anon key extraction
[TIMESTAMP] [supabase-extract-anon-key] [SUCCESS] Anon key extracted
[TIMESTAMP] [supabase-extract-anon-key] [CONTEXT_UPDATED] .sb-pentest-context.json updated
```
3. **If files don't exist**, create them before writing.
**FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.**
## MANDATORY: Evidence Collection
π **Evidence Directory:** `.sb-pentest-evidence/02-extraction/`
### Evidence Files to Create
| File | Content |
|------|---------|
| `extracted-anon-key.json` | Anon key with decoded JWT payload |
### Evidence Format
```json
{
"evidence_id": "EXT-ANON-001",
"timestamp": "2025-01-31T10:07:00Z",
"category": "extraction",
"type": "anon_key",
"severity": "info",
"key_data": {
"key_prefix": "eyJhbGciOiJIUzI1NiI...",
"key_suffix": "...xxxx",
"full_key_length": 256
},
"decoded_payload": {
"iss": "supabase",
"ref": "abc123def",
"role": "anon",
"iat": "2021-12-20T00:00:00Z",
"exp": "2031-12-20T00:00:00Z"
},
"source": {
"file": "/static/js/main.js",
"line": 1253,
"context": "createClient('https://abc123def.supabase.co', 'eyJhbGci...')"
},
"validation": {
"format_valid": true,
"role_confirmed": "anon",
"project_matches": true,
"expired": false
}
}
```
## Related Skills
- `supabase-extract-url` β Get URL first (auto-invoked if needed)
- `supabase-extract-service-key` β Check for critical service key leak
- `supabase-audit-rls` β Test if RLS protects your data
- `supabase-audit-tables-read` β See what data is accessible with this key