vibes-plug 1.0.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/.github/workflows/publish.yml +20 -0
  2. package/AGENTS.md +66 -0
  3. package/BLUEPRINT.md +152 -60
  4. package/CHANGELOG.md +50 -0
  5. package/README.md +346 -194
  6. package/package.json +25 -25
  7. package/plugin.json +1 -1
  8. package/skills/ai-cost-token-optimizer/SKILL.md +52 -0
  9. package/skills/ai-llm-integration-expert/SKILL.md +180 -162
  10. package/skills/api-design-expert/SKILL.md +314 -310
  11. package/skills/app-analyzer-optimizer/SKILL.md +193 -189
  12. package/skills/apple-ecosystem-expert/SKILL.md +142 -0
  13. package/skills/async-queue-temporal-expert/SKILL.md +54 -0
  14. package/skills/authentication-identity-expert/SKILL.md +251 -20
  15. package/skills/auto-doc-updater/SKILL.md +214 -204
  16. package/skills/autonomous-chaos-monkey/SKILL.md +63 -0
  17. package/skills/autonomous-red-teamer/SKILL.md +59 -0
  18. package/skills/autonomous-swarm-director/SKILL.md +69 -0
  19. package/skills/autonomous-tdd-debugger/SKILL.md +65 -0
  20. package/skills/bootstrap-to-modern/SKILL.md +90 -86
  21. package/skills/brainstorming/SKILL.md +373 -353
  22. package/skills/browser-automation-expert/SKILL.md +46 -0
  23. package/skills/ci-cd-devops-architect/SKILL.md +72 -45
  24. package/skills/cloud-hosting-expert/SKILL.md +244 -244
  25. package/skills/coderabbit/SKILL.md +192 -192
  26. package/skills/cron-scheduler-expert/SKILL.md +298 -0
  27. package/skills/data-telemetry-expert/SKILL.md +213 -213
  28. package/skills/database-orm-expert/SKILL.md +294 -294
  29. package/skills/dependency-upgrade-migrator/SKILL.md +295 -0
  30. package/skills/design-system-architect/SKILL.md +27 -10
  31. package/skills/doku-mcp-server/SKILL.md +251 -0
  32. package/skills/doku-payment-gateway/SKILL.md +227 -0
  33. package/skills/e2e-testing-expert/SKILL.md +315 -315
  34. package/skills/edge-serverless-db-expert/SKILL.md +43 -0
  35. package/skills/email-notification-expert/SKILL.md +362 -0
  36. package/skills/error-resilience-expert/SKILL.md +480 -0
  37. package/skills/event-driven-architect/SKILL.md +81 -81
  38. package/skills/feature-flag-analytics-expert/SKILL.md +46 -0
  39. package/skills/file-upload-media-expert/SKILL.md +431 -0
  40. package/skills/form-validation-expert/SKILL.md +401 -0
  41. package/skills/fullstack-expert/SKILL.md +202 -202
  42. package/skills/fullstack-expert/references/api_design_guide.md +466 -466
  43. package/skills/fullstack-expert/references/multi_language_backend.md +528 -528
  44. package/skills/fullstack-expert/scripts/api_contract_validator.py +253 -253
  45. package/skills/fullstack-expert/scripts/architecture_analyzer.py +326 -326
  46. package/skills/gemini-agent-booster/SKILL.md +135 -135
  47. package/skills/global-a11y-i18n-expert/SKILL.md +81 -81
  48. package/skills/glsl-shader-expert/SKILL.md +101 -0
  49. package/skills/go-programming-expert/SKILL.md +295 -295
  50. package/skills/graphql-apollo-expert/SKILL.md +108 -0
  51. package/skills/hig/SKILL.md +188 -188
  52. package/skills/hyper-context-synthesizer/SKILL.md +55 -0
  53. package/skills/js-backend-expert/SKILL.md +34 -9
  54. package/skills/legacy-code-translator/SKILL.md +65 -0
  55. package/skills/llm-cost-arbitrage-router/SKILL.md +59 -0
  56. package/skills/logging-error-tracking-expert/SKILL.md +338 -0
  57. package/skills/mcp-client-orchestrator/SKILL.md +70 -0
  58. package/skills/mcp-server-architect/SKILL.md +194 -194
  59. package/skills/micro-frontend-architect/SKILL.md +106 -0
  60. package/skills/mobile-expo-expert/SKILL.md +186 -186
  61. package/skills/mobile-push-notification-expert/SKILL.md +51 -0
  62. package/skills/monday-design-aesthetic/SKILL.md +67 -67
  63. package/skills/monorepo-architect/SKILL.md +227 -227
  64. package/skills/mpa-orchestrator/SKILL.md +101 -101
  65. package/skills/multi-agent-orchestration/SKILL.md +234 -234
  66. package/skills/multiple-entry-points/SKILL.md +55 -55
  67. package/skills/mvc-expert/SKILL.md +231 -231
  68. package/skills/payment-gateway-expert/SKILL.md +45 -45
  69. package/skills/performance-web-vitals/SKILL.md +332 -332
  70. package/skills/post-quantum-crypto-migrator/SKILL.md +57 -0
  71. package/skills/prd-architect/SKILL.md +201 -191
  72. package/skills/proactive-background-watcher/SKILL.md +62 -0
  73. package/skills/production-ready-hardener/PRODUCTION_READINESS_REPORT.md +67 -0
  74. package/skills/production-ready-hardener/SKILL.md +173 -186
  75. package/skills/production-ready-hardener/references/production_checklist.md +161 -161
  76. package/skills/production-ready-hardener/scripts/production_readiness_scanner.py +881 -875
  77. package/skills/project-context-mapper/SKILL.md +79 -0
  78. package/skills/python-programming-expert/SKILL.md +263 -132
  79. package/skills/rate-limit-abuse-prevention/SKILL.md +371 -0
  80. package/skills/realtime-collaboration-expert/SKILL.md +45 -45
  81. package/skills/rust-programming-expert/SKILL.md +235 -235
  82. package/skills/saas-billing/SKILL.md +377 -377
  83. package/skills/saas-multi-tenant/SKILL.md +251 -237
  84. package/skills/saas-mvp-launcher/SKILL.md +10 -0
  85. package/skills/saas-transformer/SKILL.md +187 -144
  86. package/skills/saas-transformer/references/billing_integration_guide.md +401 -401
  87. package/skills/saas-transformer/references/feature_gating_patterns.md +137 -137
  88. package/skills/saas-transformer/references/saas_transformation_checklist.md +121 -121
  89. package/skills/saas-transformer/scripts/saas_transformation_scanner.py +39 -29
  90. package/skills/scalability-clean-code/SKILL.md +229 -229
  91. package/skills/self-evolving-memory-graph/SKILL.md +75 -0
  92. package/skills/self-healing-cloud-orchestrator/SKILL.md +57 -0
  93. package/skills/senior-frontend/SKILL.md +161 -161
  94. package/skills/senior-fullstack/SKILL.md +167 -167
  95. package/skills/seo/SKILL.md +235 -225
  96. package/skills/seo-geo/SKILL.md +188 -188
  97. package/skills/session-context-loader/SKILL.md +77 -0
  98. package/skills/session-handoff-resume/SKILL.md +158 -158
  99. package/skills/skill_baru/SKILL.md +172 -147
  100. package/skills/spa-orchestrator/SKILL.md +288 -288
  101. package/skills/state-management-expert/SKILL.md +272 -272
  102. package/skills/supabase-security-expert/SKILL.md +243 -243
  103. package/skills/tailwind-expert/SKILL.md +188 -188
  104. package/skills/tanstack-query-expert/SKILL.md +199 -199
  105. package/skills/token-saver/SKILL.md +119 -111
  106. package/skills/typescript-expert/SKILL.md +324 -279
  107. package/skills/ui-components-expert/SKILL.md +263 -46
  108. package/skills/ui-ux-pro-max/SKILL.md +202 -201
  109. package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-310.pyc +0 -0
  110. package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-310.pyc +0 -0
  111. package/skills/ui_ux_expert/SKILL.md +17 -6
  112. package/skills/vector-db-rag-expert/SKILL.md +52 -0
  113. package/skills/vibe-code-gardener/SKILL.md +181 -173
  114. package/skills/visual-qa-vision-agent/SKILL.md +65 -0
  115. package/skills/vue-frontend-expert/SKILL.md +126 -0
  116. package/skills/web-3d-graphics-expert/SKILL.md +131 -0
  117. package/skills/web-game-engine-expert/SKILL.md +96 -0
  118. package/skills/web-scraper/SKILL.md +207 -205
  119. package/skills/website-design-cloner/SKILL.md +174 -0
  120. package/skills/webxr-ar-vr-expert/SKILL.md +117 -0
  121. package/skills/zero-to-prod-orchestrator/SKILL.md +206 -180
  122. package/skills/zero-trust-secret-vault/SKILL.md +40 -0
  123. package/vibes-swarm-demo.gif +0 -0
@@ -1,243 +1,243 @@
1
- ---
2
- name: supabase-security-expert
3
- description: "Supabase security expert to audit RLS (Row Level Security), RBAC, relational databases, prevent data leakage, and utilize Supabase Linter / Ahli keamanan Supabase untuk audit RLS (Row Level Security), RBAC, database relasional, pencegahan kebocoran data, dan pemanfaatan Supabase Linter."
4
- author: "Roedy Rustam"
5
- ---
6
-
7
- # Supabase Security Expert (2026 Edition — Auth v3 / PKCE)
8
-
9
- [English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
10
-
11
- ---
12
-
13
- <a name="english"></a>
14
- ## English
15
-
16
- ### Description
17
- Expert guide for auditing and hardening Supabase applications. Covers Row Level Security (RLS), Supabase Auth v3 (PKCE flow), API key hygiene, data leakage prevention, Supabase Linter, and production security checklists.
18
-
19
- ### Trigger Conditions
20
- - Auditing RLS policies for correctness and security gaps.
21
- - Setting up Supabase Auth v3 with PKCE flow (replaces implicit flow).
22
- - Reviewing API key usage (anon key vs. service role key).
23
- - Preventing data leakage from misconfigured policies.
24
- - Running Supabase Linter (`supabase lint`) for automated security checks.
25
- - Implementing user roles and access control in a Supabase project.
26
-
27
- ### Supabase Auth v3 — PKCE Flow (2026 Default)
28
-
29
- Supabase Auth v3 now uses **PKCE (Proof Key for Code Exchange)** as the default flow for all OAuth and magic link authentication — replacing the older implicit flow:
30
-
31
- ```typescript
32
- // supabase/client.ts — v3 client setup
33
- import { createBrowserClient } from '@supabase/ssr';
34
-
35
- export const supabase = createBrowserClient(
36
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
37
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
38
- {
39
- auth: {
40
- flowType: 'pkce', // Default in Auth v3
41
- autoRefreshToken: true,
42
- persistSession: true,
43
- detectSessionInUrl: true,
44
- }
45
- }
46
- );
47
- ```
48
-
49
- ```typescript
50
- // Server-side session handling (Next.js App Router)
51
- import { createServerClient } from '@supabase/ssr';
52
- import { cookies } from 'next/headers';
53
-
54
- export async function createSupabaseServerClient() {
55
- const cookieStore = await cookies();
56
- return createServerClient(
57
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
58
- process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
59
- {
60
- cookies: {
61
- getAll: () => cookieStore.getAll(),
62
- setAll: (cookiesToSet) => {
63
- cookiesToSet.forEach(({ name, value, options }) =>
64
- cookieStore.set(name, value, options)
65
- );
66
- },
67
- },
68
- }
69
- );
70
- }
71
- ```
72
-
73
- ### API Key Security
74
-
75
- | Key Type | Purpose | Where to Use |
76
- |---|---|---|
77
- | `anon` key | Public client access — restricted by RLS | Frontend (browser) |
78
- | `service_role` key | Bypasses ALL RLS | Backend only (server) |
79
-
80
- > ⚠️ **NEVER** expose `service_role` key to the frontend. If it leaks, an attacker can read/write all data in your database, bypassing RLS completely.
81
-
82
- ```typescript
83
- // ✅ CORRECT: service_role used only in server-side code
84
- // app/api/admin/route.ts (only accessible at admin.domain.com)
85
- import { createClient } from '@supabase/supabase-js';
86
-
87
- const adminClient = createClient(
88
- process.env.NEXT_PUBLIC_SUPABASE_URL!,
89
- process.env.SUPABASE_SERVICE_ROLE_KEY!, // NOT exposed to client
90
- );
91
-
92
- // 🔴 WRONG: service_role in client-side code
93
- const publicClient = createBrowserClient(url, process.env.SUPABASE_SERVICE_ROLE_KEY!);
94
- ```
95
-
96
- ### RLS Policy Audit Checklist
97
-
98
- #### Common RLS Mistakes
99
- ```sql
100
- -- 🔴 INSECURE: auth.uid() is not validated — returns null if not authenticated
101
- CREATE POLICY "users can see own data" ON profiles
102
- FOR SELECT USING (user_id = auth.uid());
103
- -- If user is unauthenticated, auth.uid() returns null, which means
104
- -- NULL = NULL is NULL (falsy in SQL) — so this IS secure... but next one isn't:
105
-
106
- -- 🔴 DANGEROUS: Using 'true' without auth check
107
- CREATE POLICY "all can read" ON public_posts
108
- FOR SELECT USING (true); -- Anyone, including anonymous, can read
109
-
110
- -- ✅ SECURE: Explicit authentication requirement
111
- CREATE POLICY "only authenticated users can read" ON sensitive_data
112
- FOR SELECT USING (auth.role() = 'authenticated');
113
-
114
- -- ✅ SECURE: Workspace isolation with auth check
115
- CREATE POLICY "workspace isolation" ON projects
116
- FOR ALL USING (
117
- workspace_id IN (
118
- SELECT workspace_id FROM workspace_members
119
- WHERE user_id = auth.uid()
120
- )
121
- );
122
- ```
123
-
124
- #### RLS Audit SQL Queries
125
- ```sql
126
- -- Find tables WITHOUT RLS enabled
127
- SELECT schemaname, tablename
128
- FROM pg_tables
129
- WHERE schemaname = 'public'
130
- AND tablename NOT IN (
131
- SELECT tablename FROM pg_policies WHERE schemaname = 'public'
132
- );
133
-
134
- -- Find tables with RLS enabled but NO policies (effectively blocks all access)
135
- SELECT c.relname AS table_name, c.relrowsecurity AS rls_enabled
136
- FROM pg_class c
137
- JOIN pg_namespace n ON n.oid = c.relnamespace
138
- WHERE n.nspname = 'public'
139
- AND c.relkind = 'r'
140
- AND c.relrowsecurity = true
141
- AND NOT EXISTS (
142
- SELECT 1 FROM pg_policies p
143
- WHERE p.tablename = c.relname AND p.schemaname = n.nspname
144
- );
145
- ```
146
-
147
- ### Supabase Linter
148
- Run automated security checks:
149
- ```bash
150
- # Install Supabase CLI
151
- npm install -g supabase
152
-
153
- # Run the linter against your project
154
- supabase db lint --project-id <your-project-id>
155
-
156
- # Common lint checks:
157
- # - Tables with RLS disabled
158
- # - Policies using mutable functions (NOW(), RANDOM())
159
- # - Security definer functions without search_path
160
- # - Auth functions used incorrectly
161
- ```
162
-
163
- ### Storage Security
164
- ```typescript
165
- // Create a private storage bucket (files not publicly accessible by URL)
166
- const { data, error } = await supabase.storage.createBucket('user-uploads', {
167
- public: false, // Private — requires signed URLs
168
- fileSizeLimit: 10 * 1024 * 1024, // 10MB
169
- allowedMimeTypes: ['image/jpeg', 'image/png', 'application/pdf'],
170
- });
171
-
172
- // Generate a signed URL (expires in 1 hour)
173
- const { data: { signedUrl } } = await supabase.storage
174
- .from('user-uploads')
175
- .createSignedUrl(`${userId}/${filename}`, 3600);
176
- ```
177
-
178
- ```sql
179
- -- Storage RLS: users can only access their own files
180
- CREATE POLICY "users can manage own files"
181
- ON storage.objects FOR ALL
182
- USING (bucket_id = 'user-uploads' AND auth.uid()::text = (storage.foldername(name))[1]);
183
- ```
184
-
185
- ### Production Security Checklist
186
- - [ ] All tables in `public` schema have RLS enabled.
187
- - [ ] `service_role` key is only in server-side environment variables.
188
- - [ ] PKCE flow enabled (`flowType: 'pkce'`) in Auth v3 client.
189
- - [ ] Storage buckets are private by default.
190
- - [ ] JWT expiry set appropriately (recommended: 1 hour + refresh tokens).
191
- - [ ] Email confirmations required for new signups.
192
- - [ ] Supabase Linter (`supabase db lint`) passes with no critical issues.
193
- - [ ] MFA (Multi-Factor Authentication) enabled for admin users.
194
- - [ ] Realtime subscriptions restricted — filter by authenticated user.
195
- - [ ] Custom `auth.uid()` policies tested with anonymous/different user sessions.
196
-
197
- ---
198
-
199
- <a name="bahasa-indonesia"></a>
200
- ## Bahasa Indonesia
201
-
202
- ### Deskripsi
203
- Panduan ahli untuk mengaudit dan mengeraskan aplikasi Supabase. Mencakup Row Level Security (RLS), Supabase Auth v3 (PKCE flow), kebersihan API key, pencegahan kebocoran data, Supabase Linter, dan checklist keamanan produksi.
204
-
205
- ### Kondisi Pemicu
206
- - Mengaudit kebijakan RLS untuk kebenaran dan celah keamanan.
207
- - Menyiapkan Supabase Auth v3 dengan PKCE flow (menggantikan implicit flow).
208
- - Meninjau penggunaan API key (anon key vs. service role key).
209
- - Mencegah kebocoran data dari kebijakan yang salah konfigurasi.
210
- - Menjalankan Supabase Linter untuk pemeriksaan keamanan otomatis.
211
-
212
- ### Supabase Auth v3 — PKCE Flow (Default 2026)
213
-
214
- Supabase Auth v3 menggunakan **PKCE** sebagai alur default untuk semua OAuth dan magic link — menggantikan implicit flow yang lama. Konfigurasikan dengan `flowType: 'pkce'` di klien browser dan gunakan `@supabase/ssr` untuk penanganan sesi sisi server di Next.js App Router.
215
-
216
- ### Keamanan API Key
217
-
218
- | Tipe Key | Tujuan | Tempat Penggunaan |
219
- |---|---|---|
220
- | `anon` key | Akses klien publik — dibatasi RLS | Frontend (browser) |
221
- | `service_role` key | Melewati SEMUA RLS | Hanya backend (server) |
222
-
223
- > ⚠️ **JANGAN PERNAH** mengekspos `service_role` key ke frontend. Jika bocor, penyerang dapat membaca/menulis semua data di database Anda, melewati RLS sepenuhnya.
224
-
225
- ### Audit Kebijakan RLS
226
-
227
- Kesalahan RLS umum: menggunakan `USING (true)` tanpa pemeriksaan autentikasi (siapa saja, termasuk anonim, dapat membaca). Selalu verifikasi dengan `auth.role() = 'authenticated'` atau cek `auth.uid()` eksplisit.
228
-
229
- Gunakan query audit SQL untuk menemukan tabel tanpa RLS dan tabel dengan RLS aktif tetapi tanpa kebijakan (memblokir semua akses).
230
-
231
- ### Supabase Linter
232
- Jalankan `supabase db lint` untuk pemeriksaan keamanan otomatis: tabel dengan RLS dinonaktifkan, kebijakan menggunakan fungsi yang dapat dimutasi, fungsi security definer tanpa `search_path`.
233
-
234
- ### Keamanan Storage
235
- Buat bucket penyimpanan privat (`public: false`) dengan batasan ukuran file dan tipe MIME yang diizinkan. Gunakan URL bertanda tangan (signed URL) untuk memberikan akses sementara ke file privat. Terapkan RLS di `storage.objects` untuk memastikan pengguna hanya dapat mengakses file mereka sendiri.
236
-
237
- ### Checklist Keamanan Produksi
238
- - Semua tabel di schema `public` mengaktifkan RLS.
239
- - `service_role` key hanya di variabel lingkungan sisi server.
240
- - PKCE flow diaktifkan di klien Auth v3.
241
- - Bucket storage privat secara default.
242
- - Supabase Linter tidak ada isu kritis.
243
- - MFA diaktifkan untuk pengguna admin.
1
+ ---
2
+ name: supabase-security-expert
3
+ description: "Supabase security expert to audit RLS (Row Level Security), RBAC, relational databases, prevent data leakage, and utilize Supabase Linter / Ahli keamanan Supabase untuk audit RLS (Row Level Security), RBAC, database relasional, pencegahan kebocoran data, dan pemanfaatan Supabase Linter."
4
+ author: "Roedy Rustam"
5
+ ---
6
+
7
+ # Supabase Security Expert (2026 Edition — Auth v3 / PKCE)
8
+
9
+ [English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
10
+
11
+ ---
12
+
13
+ <a name="english"></a>
14
+ ## English
15
+
16
+ ### Description
17
+ Expert guide for auditing and hardening Supabase applications. Covers Row Level Security (RLS), Supabase Auth v3 (PKCE flow), API key hygiene, data leakage prevention, Supabase Linter, and production security checklists.
18
+
19
+ ### Trigger Conditions
20
+ - Auditing RLS policies for correctness and security gaps.
21
+ - Setting up Supabase Auth v3 with PKCE flow (replaces implicit flow).
22
+ - Reviewing API key usage (anon key vs. service role key).
23
+ - Preventing data leakage from misconfigured policies.
24
+ - Running Supabase Linter (`supabase lint`) for automated security checks.
25
+ - Implementing user roles and access control in a Supabase project.
26
+
27
+ ### Supabase Auth v3 — PKCE Flow (2026 Default)
28
+
29
+ Supabase Auth v3 now uses **PKCE (Proof Key for Code Exchange)** as the default flow for all OAuth and magic link authentication — replacing the older implicit flow:
30
+
31
+ ```typescript
32
+ // supabase/client.ts — v3 client setup
33
+ import { createBrowserClient } from '@supabase/ssr';
34
+
35
+ export const supabase = createBrowserClient(
36
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
37
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
38
+ {
39
+ auth: {
40
+ flowType: 'pkce', // Default in Auth v3
41
+ autoRefreshToken: true,
42
+ persistSession: true,
43
+ detectSessionInUrl: true,
44
+ }
45
+ }
46
+ );
47
+ ```
48
+
49
+ ```typescript
50
+ // Server-side session handling (Next.js App Router)
51
+ import { createServerClient } from '@supabase/ssr';
52
+ import { cookies } from 'next/headers';
53
+
54
+ export async function createSupabaseServerClient() {
55
+ const cookieStore = await cookies();
56
+ return createServerClient(
57
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
58
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
59
+ {
60
+ cookies: {
61
+ getAll: () => cookieStore.getAll(),
62
+ setAll: (cookiesToSet) => {
63
+ cookiesToSet.forEach(({ name, value, options }) =>
64
+ cookieStore.set(name, value, options)
65
+ );
66
+ },
67
+ },
68
+ }
69
+ );
70
+ }
71
+ ```
72
+
73
+ ### API Key Security
74
+
75
+ | Key Type | Purpose | Where to Use |
76
+ |---|---|---|
77
+ | `anon` key | Public client access — restricted by RLS | Frontend (browser) |
78
+ | `service_role` key | Bypasses ALL RLS | Backend only (server) |
79
+
80
+ > ⚠️ **NEVER** expose `service_role` key to the frontend. If it leaks, an attacker can read/write all data in your database, bypassing RLS completely.
81
+
82
+ ```typescript
83
+ // ✅ CORRECT: service_role used only in server-side code
84
+ // app/api/admin/route.ts (only accessible at admin.domain.com)
85
+ import { createClient } from '@supabase/supabase-js';
86
+
87
+ const adminClient = createClient(
88
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
89
+ process.env.SUPABASE_SERVICE_ROLE_KEY!, // NOT exposed to client
90
+ );
91
+
92
+ // 🔴 WRONG: service_role in client-side code
93
+ const publicClient = createBrowserClient(url, process.env.SUPABASE_SERVICE_ROLE_KEY!);
94
+ ```
95
+
96
+ ### RLS Policy Audit Checklist
97
+
98
+ #### Common RLS Mistakes
99
+ ```sql
100
+ -- 🔴 INSECURE: auth.uid() is not validated — returns null if not authenticated
101
+ CREATE POLICY "users can see own data" ON profiles
102
+ FOR SELECT USING (user_id = auth.uid());
103
+ -- If user is unauthenticated, auth.uid() returns null, which means
104
+ -- NULL = NULL is NULL (falsy in SQL) — so this IS secure... but next one isn't:
105
+
106
+ -- 🔴 DANGEROUS: Using 'true' without auth check
107
+ CREATE POLICY "all can read" ON public_posts
108
+ FOR SELECT USING (true); -- Anyone, including anonymous, can read
109
+
110
+ -- ✅ SECURE: Explicit authentication requirement
111
+ CREATE POLICY "only authenticated users can read" ON sensitive_data
112
+ FOR SELECT USING (auth.role() = 'authenticated');
113
+
114
+ -- ✅ SECURE: Workspace isolation with auth check
115
+ CREATE POLICY "workspace isolation" ON projects
116
+ FOR ALL USING (
117
+ workspace_id IN (
118
+ SELECT workspace_id FROM workspace_members
119
+ WHERE user_id = auth.uid()
120
+ )
121
+ );
122
+ ```
123
+
124
+ #### RLS Audit SQL Queries
125
+ ```sql
126
+ -- Find tables WITHOUT RLS enabled
127
+ SELECT schemaname, tablename
128
+ FROM pg_tables
129
+ WHERE schemaname = 'public'
130
+ AND tablename NOT IN (
131
+ SELECT tablename FROM pg_policies WHERE schemaname = 'public'
132
+ );
133
+
134
+ -- Find tables with RLS enabled but NO policies (effectively blocks all access)
135
+ SELECT c.relname AS table_name, c.relrowsecurity AS rls_enabled
136
+ FROM pg_class c
137
+ JOIN pg_namespace n ON n.oid = c.relnamespace
138
+ WHERE n.nspname = 'public'
139
+ AND c.relkind = 'r'
140
+ AND c.relrowsecurity = true
141
+ AND NOT EXISTS (
142
+ SELECT 1 FROM pg_policies p
143
+ WHERE p.tablename = c.relname AND p.schemaname = n.nspname
144
+ );
145
+ ```
146
+
147
+ ### Supabase Linter
148
+ Run automated security checks:
149
+ ```bash
150
+ # Install Supabase CLI
151
+ npm install -g supabase
152
+
153
+ # Run the linter against your project
154
+ supabase db lint --project-id <your-project-id>
155
+
156
+ # Common lint checks:
157
+ # - Tables with RLS disabled
158
+ # - Policies using mutable functions (NOW(), RANDOM())
159
+ # - Security definer functions without search_path
160
+ # - Auth functions used incorrectly
161
+ ```
162
+
163
+ ### Storage Security
164
+ ```typescript
165
+ // Create a private storage bucket (files not publicly accessible by URL)
166
+ const { data, error } = await supabase.storage.createBucket('user-uploads', {
167
+ public: false, // Private — requires signed URLs
168
+ fileSizeLimit: 10 * 1024 * 1024, // 10MB
169
+ allowedMimeTypes: ['image/jpeg', 'image/png', 'application/pdf'],
170
+ });
171
+
172
+ // Generate a signed URL (expires in 1 hour)
173
+ const { data: { signedUrl } } = await supabase.storage
174
+ .from('user-uploads')
175
+ .createSignedUrl(`${userId}/${filename}`, 3600);
176
+ ```
177
+
178
+ ```sql
179
+ -- Storage RLS: users can only access their own files
180
+ CREATE POLICY "users can manage own files"
181
+ ON storage.objects FOR ALL
182
+ USING (bucket_id = 'user-uploads' AND auth.uid()::text = (storage.foldername(name))[1]);
183
+ ```
184
+
185
+ ### Production Security Checklist
186
+ - [ ] All tables in `public` schema have RLS enabled.
187
+ - [ ] `service_role` key is only in server-side environment variables.
188
+ - [ ] PKCE flow enabled (`flowType: 'pkce'`) in Auth v3 client.
189
+ - [ ] Storage buckets are private by default.
190
+ - [ ] JWT expiry set appropriately (recommended: 1 hour + refresh tokens).
191
+ - [ ] Email confirmations required for new signups.
192
+ - [ ] Supabase Linter (`supabase db lint`) passes with no critical issues.
193
+ - [ ] MFA (Multi-Factor Authentication) enabled for admin users.
194
+ - [ ] Realtime subscriptions restricted — filter by authenticated user.
195
+ - [ ] Custom `auth.uid()` policies tested with anonymous/different user sessions.
196
+
197
+ ---
198
+
199
+ <a name="bahasa-indonesia"></a>
200
+ ## Bahasa Indonesia
201
+
202
+ ### Deskripsi
203
+ Panduan ahli untuk mengaudit dan mengeraskan aplikasi Supabase. Mencakup Row Level Security (RLS), Supabase Auth v3 (PKCE flow), kebersihan API key, pencegahan kebocoran data, Supabase Linter, dan checklist keamanan produksi.
204
+
205
+ ### Kondisi Pemicu
206
+ - Mengaudit kebijakan RLS untuk kebenaran dan celah keamanan.
207
+ - Menyiapkan Supabase Auth v3 dengan PKCE flow (menggantikan implicit flow).
208
+ - Meninjau penggunaan API key (anon key vs. service role key).
209
+ - Mencegah kebocoran data dari kebijakan yang salah konfigurasi.
210
+ - Menjalankan Supabase Linter untuk pemeriksaan keamanan otomatis.
211
+
212
+ ### Supabase Auth v3 — PKCE Flow (Default 2026)
213
+
214
+ Supabase Auth v3 menggunakan **PKCE** sebagai alur default untuk semua OAuth dan magic link — menggantikan implicit flow yang lama. Konfigurasikan dengan `flowType: 'pkce'` di klien browser dan gunakan `@supabase/ssr` untuk penanganan sesi sisi server di Next.js App Router.
215
+
216
+ ### Keamanan API Key
217
+
218
+ | Tipe Key | Tujuan | Tempat Penggunaan |
219
+ |---|---|---|
220
+ | `anon` key | Akses klien publik — dibatasi RLS | Frontend (browser) |
221
+ | `service_role` key | Melewati SEMUA RLS | Hanya backend (server) |
222
+
223
+ > ⚠️ **JANGAN PERNAH** mengekspos `service_role` key ke frontend. Jika bocor, penyerang dapat membaca/menulis semua data di database Anda, melewati RLS sepenuhnya.
224
+
225
+ ### Audit Kebijakan RLS
226
+
227
+ Kesalahan RLS umum: menggunakan `USING (true)` tanpa pemeriksaan autentikasi (siapa saja, termasuk anonim, dapat membaca). Selalu verifikasi dengan `auth.role() = 'authenticated'` atau cek `auth.uid()` eksplisit.
228
+
229
+ Gunakan query audit SQL untuk menemukan tabel tanpa RLS dan tabel dengan RLS aktif tetapi tanpa kebijakan (memblokir semua akses).
230
+
231
+ ### Supabase Linter
232
+ Jalankan `supabase db lint` untuk pemeriksaan keamanan otomatis: tabel dengan RLS dinonaktifkan, kebijakan menggunakan fungsi yang dapat dimutasi, fungsi security definer tanpa `search_path`.
233
+
234
+ ### Keamanan Storage
235
+ Buat bucket penyimpanan privat (`public: false`) dengan batasan ukuran file dan tipe MIME yang diizinkan. Gunakan URL bertanda tangan (signed URL) untuk memberikan akses sementara ke file privat. Terapkan RLS di `storage.objects` untuk memastikan pengguna hanya dapat mengakses file mereka sendiri.
236
+
237
+ ### Checklist Keamanan Produksi
238
+ - Semua tabel di schema `public` mengaktifkan RLS.
239
+ - `service_role` key hanya di variabel lingkungan sisi server.
240
+ - PKCE flow diaktifkan di klien Auth v3.
241
+ - Bucket storage privat secara default.
242
+ - Supabase Linter tidak ada isu kritis.
243
+ - MFA diaktifkan untuk pengguna admin.