
Supabase Audit Tables List
- 318 installs
- 60 repo stars
- Updated January 31, 2026
- yoanbernabeu/supabase-pentest-skills
supabase-audit-tables-list is a security reconnaissance skill that enumerates all database tables exposed through the Supabase PostgREST API for developers who need to identify overly permissive table access during a pen
About
supabase-audit-tables-list is a Supabase pentest skill that discovers every database table reachable via the PostgREST API and records findings as the first database reconnaissance step in a security audit. Like its bucket counterpart, it mandates progressive writes to `.sb-pentest-context.json` after each table discovery and operation logging to `.sb-pentest-audit.log` before and after every action so crashes do not lose prior results. Developers use supabase-audit-tables-list when reviewing RLS coverage, hunting exposed tables, or building a structured Supabase attack-surface report. It fits the yoanbernabeu/supabase-pentest-skills workflow alongside bucket and policy audit skills.
- Discovers all tables accessible through Supabase PostgREST API
- Progressive logging to .sb-pentest-context.json and .sb-pentest-audit.log
- Foundational reconnaissance for deeper penetration testing
- Part of the 24-skill Supabase pentest toolkit
- 236 installs and passed Gen Agent Trust Hub, Socket, and Snyk audits
Supabase Audit Tables List by the numbers
- 318 all-time installs (skills.sh)
- +15 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #619 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-audit-tables-listAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 318 |
|---|---|
| repo stars | ★ 60 |
| Last updated | January 31, 2026 |
| Repository | yoanbernabeu/supabase-pentest-skills ↗ |
How do you find tables exposed via Supabase PostgREST API?
Enumerate all database tables exposed via Supabase PostgREST API to identify overly permissive table access during security reconnaissance.
Who is it for?
Developers or security engineers mapping Supabase database exposure through PostgREST before tightening RLS policies.
Skip if: Developers designing Postgres schemas or writing migrations without a security reconnaissance goal.
When should I use this skill?
User asks to audit Supabase tables, enumerate PostgREST exposure, list exposed tables, or start supabase-pentest database reconnaissance.
What you get
A PostgREST table inventory in `.sb-pentest-context.json` plus a chronological audit log in `.sb-pentest-audit.log`.
- .sb-pentest-context.json table inventory
- .sb-pentest-audit.log operation trace
By the numbers
- Writes progressively to `.sb-pentest-context.json` and `.sb-pentest-audit.log` on every table discovery
Files
List Exposed Tables
🔴 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 discovers all database tables exposed through the Supabase PostgREST API.
When to Use This Skill
- To understand the API attack surface
- Before testing RLS policies
- To inventory exposed data models
- As part of a comprehensive security audit
Prerequisites
- Supabase URL extracted (auto-invokes if needed)
- Anon key extracted (auto-invokes if needed)
How It Works
Supabase exposes tables via PostgREST at:
https://[project-ref].supabase.co/rest/v1/The skill uses the OpenAPI schema endpoint to enumerate tables:
https://[project-ref].supabase.co/rest/v1/?apikey=[anon-key]What Gets Exposed
By default, Supabase exposes tables in the public schema. Tables are exposed when:
1. They exist in an exposed schema (default: public) 2. No explicit REVOKE has been done 3. PostgREST can see them
Usage
Basic Table List
List tables exposed on my Supabase projectWith Schema Information
List all exposed tables with column detailsOutput Format
═══════════════════════════════════════════════════════════
EXPOSED TABLES
═══════════════════════════════════════════════════════════
Project: abc123def.supabase.co
Schema: public
Tables Found: 8
─────────────────────────────────────────────────────────
Table Inventory
─────────────────────────────────────────────────────────
1. users
├── Columns: id, email, name, avatar_url, created_at
├── Primary Key: id (uuid)
├── RLS Status: Unknown (test with supabase-audit-rls)
└── Risk: ⚠️ Contains user PII
2. profiles
├── Columns: id, user_id, bio, website, social_links
├── Primary Key: id (uuid)
├── Foreign Key: user_id → auth.users
└── Risk: ⚠️ Contains user PII
3. posts
├── Columns: id, author_id, title, content, published, created_at
├── Primary Key: id (uuid)
└── Risk: ℹ️ Content data
4. comments
├── Columns: id, post_id, user_id, content, created_at
├── Primary Key: id (uuid)
└── Risk: ℹ️ Content data
5. orders
├── Columns: id, user_id, total, status, items, created_at
├── Primary Key: id (uuid)
└── Risk: 🔴 Contains financial/transaction data
6. products
├── Columns: id, name, description, price, stock, image_url
├── Primary Key: id (uuid)
└── Risk: ℹ️ Public catalog data
7. settings
├── Columns: id, key, value, updated_at
├── Primary Key: id (uuid)
└── Risk: ⚠️ May contain sensitive configuration
8. api_keys
├── Columns: id, user_id, key_hash, name, last_used
├── Primary Key: id (uuid)
└── Risk: 🔴 Contains secrets
─────────────────────────────────────────────────────────
Summary
─────────────────────────────────────────────────────────
Total Tables: 8
High Risk: 2 (orders, api_keys)
Medium Risk: 3 (users, profiles, settings)
Low Risk: 3 (posts, comments, products)
Next Steps:
├── Run supabase-audit-tables-read to test actual data access
├── Run supabase-audit-rls to verify RLS policies
└── Review high-risk tables first
═══════════════════════════════════════════════════════════Risk Classification
Tables are classified by likely content:
| Risk | Table Patterns | Examples |
|---|---|---|
| 🔴 High | Financial, secrets, auth | orders, payments, api_keys, secrets |
| ⚠️ Medium | User PII, config | users, profiles, settings, preferences |
| ℹ️ Low | Public content | posts, products, categories, tags |
Context Output
{
"tables": {
"count": 8,
"list": [
{
"name": "users",
"schema": "public",
"columns": ["id", "email", "name", "avatar_url", "created_at"],
"primary_key": "id",
"risk_level": "medium",
"risk_reason": "Contains user PII"
},
{
"name": "orders",
"schema": "public",
"columns": ["id", "user_id", "total", "status", "items", "created_at"],
"primary_key": "id",
"risk_level": "high",
"risk_reason": "Contains financial data"
}
],
"by_risk": {
"high": ["orders", "api_keys"],
"medium": ["users", "profiles", "settings"],
"low": ["posts", "comments", "products"]
}
}
}Hidden Tables
Some tables may not appear in the OpenAPI schema:
═══════════════════════════════════════════════════════════
ADDITIONAL DISCOVERY
═══════════════════════════════════════════════════════════
Common Tables Not in Schema (testing existence):
├── _prisma_migrations: ❌ Not found
├── schema_migrations: ❌ Not found
├── audit_log: ✅ EXISTS but not in OpenAPI
└── internal_config: ❌ Not found
Note: 'audit_log' exists but may have restricted access.
Test with supabase-audit-tables-read.
═══════════════════════════════════════════════════════════Schema Analysis
The skill also checks for non-public schemas:
Schema Exposure Check:
├── public: ✅ Exposed (8 tables)
├── auth: ❌ Not directly exposed (expected)
├── storage: ❌ Not directly exposed (expected)
├── extensions: ❌ Not exposed (good)
└── custom_schema: ⚠️ Exposed (3 tables) - Review if intentionalCommon Issues
❌ Problem: No tables found ✅ Solution:
- Check if anon key is valid
- Verify project URL is correct
- The API may be disabled in project settings
❌ Problem: Too many tables listed ✅ Solution: This may indicate overly permissive schema exposure. Consider:
-- Restrict exposed schemas
ALTER ROLE anon SET search_path TO public;❌ Problem: Sensitive tables exposed ✅ Solution: Either remove from public schema or implement strict RLS.
Recommendations by Table Type
User Tables
-- Ensure RLS is enabled
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
-- Users can only see their own data
CREATE POLICY "Users see own data" ON users
FOR SELECT USING (auth.uid() = id);Order/Payment Tables
-- Strict RLS for financial data
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users see own orders" ON orders
FOR SELECT USING (auth.uid() = user_id);
-- No public access even for admins via API
-- Use Edge Functions for admin operationsSecret Tables
-- Consider not exposing at all
REVOKE ALL ON TABLE api_keys FROM anon, authenticated;
-- Or use views that hide sensitive columns
CREATE VIEW public.api_keys_safe AS
SELECT id, name, last_used FROM api_keys;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 table discovered → 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 results:
{
"tables": {
"count": 8,
"list": [ ... ],
"by_risk": { "high": [], "medium": [], "low": [] }
}
}2. Log to `.sb-pentest-audit.log`:
[TIMESTAMP] [supabase-audit-tables-list] [START] Listing exposed tables
[TIMESTAMP] [supabase-audit-tables-list] [SUCCESS] Found 8 tables
[TIMESTAMP] [supabase-audit-tables-list] [CONTEXT_UPDATED] .sb-pentest-context.json updated3. 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/03-api-audit/tables/
Evidence Files to Create
| File | Content |
|---|---|
tables-list.json | Complete list of exposed tables |
tables-metadata.json | Column details and types per table |
openapi-schema.json | Raw OpenAPI/PostgREST schema |
Evidence Format
{
"evidence_id": "API-TBL-001",
"timestamp": "2025-01-31T10:15:00Z",
"category": "api-audit",
"type": "table_enumeration",
"request": {
"method": "GET",
"url": "https://abc123def.supabase.co/rest/v1/",
"headers": {
"apikey": "[REDACTED]"
},
"curl_command": "curl -s 'https://abc123def.supabase.co/rest/v1/' -H 'apikey: $ANON_KEY'"
},
"tables_found": [
{
"name": "users",
"schema": "public",
"columns": ["id", "email", "name", "created_at"],
"primary_key": "id",
"risk_level": "high",
"risk_reason": "Contains PII"
},
{
"name": "orders",
"schema": "public",
"columns": ["id", "user_id", "total", "status"],
"primary_key": "id",
"risk_level": "high",
"risk_reason": "Financial data"
}
],
"summary": {
"total_tables": 8,
"high_risk": 2,
"medium_risk": 3,
"low_risk": 3
}
}Add to curl-commands.sh
# === TABLE ENUMERATION ===
# List all exposed tables via OpenAPI schema
curl -s "$SUPABASE_URL/rest/v1/" -H "apikey: $ANON_KEY"Related Skills
supabase-audit-tables-read— Test actual data accesssupabase-audit-rls— Verify RLS policiessupabase-audit-rpc— Check exposed functions
Related skills
How it compares
Pick this over manual SQL catalog queries when the audit must trace PostgREST exposure and feed a standardized Supabase pentest context file.
FAQ
What API does supabase-audit-tables-list use to find exposed tables?
supabase-audit-tables-list enumerates tables exposed through the Supabase PostgREST API, surfacing which database relations are reachable via the project's REST layer during security reconnaissance.
How does supabase-audit-tables-list preserve findings if interrupted?
supabase-audit-tables-list writes each table to `.sb-pentest-context.json` immediately after discovery and logs to `.sb-pentest-audit.log` before and after every operation, so partial audit results are not lost on crash.