@appsforgood/next-supabase-kit 0.4.1 → 0.4.3
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.
- package/CHANGELOG.md +15 -0
- package/README.md +2 -1
- package/UPGRADE.md +23 -0
- package/USER_GUIDE.html +14 -7
- package/USER_GUIDE.md +6 -5
- package/agents/app-engineer/agent.md +2 -0
- package/dist/index.js +319 -242
- package/dist/index.js.map +1 -1
- package/examples/next-supabase-installed/.agent-kit/manifest.json +25 -25
- package/examples/next-supabase-installed/.antigravity/runtime-skills/deslop/SKILL.md +7 -1
- package/examples/next-supabase-installed/.antigravity/runtime-skills/frontend-design/SKILL.md +3 -1
- package/examples/next-supabase-installed/.antigravity/runtime-skills/nextjs-app-router/SKILL.md +29 -9
- package/examples/next-supabase-installed/.antigravity/runtime-skills/owasp-security-review/SKILL.md +31 -9
- package/examples/next-supabase-installed/.antigravity/runtime-skills/planning/SKILL.md +11 -5
- package/examples/next-supabase-installed/.antigravity/runtime-skills/postgres-migrations/SKILL.md +25 -7
- package/examples/next-supabase-installed/.antigravity/runtime-skills/supabase-auth-rls/SKILL.md +41 -9
- package/examples/next-supabase-installed/.antigravity/runtime-skills/testing-qa/SKILL.md +5 -3
- package/examples/next-supabase-installed/.claude/agents/app-engineer.md +2 -0
- package/examples/next-supabase-installed/.codex/agents/app-engineer.toml +2 -0
- package/examples/next-supabase-installed/.cursor/agents/app-engineer.md +2 -0
- package/examples/next-supabase-installed/.cursor/skills/deslop/SKILL.md +7 -1
- package/examples/next-supabase-installed/.cursor/skills/frontend-design/SKILL.md +3 -1
- package/examples/next-supabase-installed/.cursor/skills/nextjs-app-router/SKILL.md +29 -9
- package/examples/next-supabase-installed/.cursor/skills/owasp-security-review/SKILL.md +31 -9
- package/examples/next-supabase-installed/.cursor/skills/planning/SKILL.md +11 -5
- package/examples/next-supabase-installed/.cursor/skills/postgres-migrations/SKILL.md +25 -7
- package/examples/next-supabase-installed/.cursor/skills/supabase-auth-rls/SKILL.md +41 -9
- package/examples/next-supabase-installed/.cursor/skills/testing-qa/SKILL.md +5 -3
- package/examples/next-supabase-installed/USER_GUIDE.html +14 -7
- package/examples/next-supabase-installed/USER_GUIDE.md +6 -5
- package/examples/next-supabase-installed/skills/deslop/SKILL.md +7 -1
- package/examples/next-supabase-installed/skills/frontend-design/SKILL.md +3 -1
- package/examples/next-supabase-installed/skills/nextjs-app-router/SKILL.md +29 -9
- package/examples/next-supabase-installed/skills/owasp-security-review/SKILL.md +31 -9
- package/examples/next-supabase-installed/skills/planning/SKILL.md +11 -5
- package/examples/next-supabase-installed/skills/postgres-migrations/SKILL.md +25 -7
- package/examples/next-supabase-installed/skills/supabase-auth-rls/SKILL.md +41 -9
- package/examples/next-supabase-installed/skills/testing-qa/SKILL.md +5 -3
- package/package.json +1 -1
- package/research/agent-skill-gap-report.md +4 -0
- package/skills/deslop/SKILL.md +7 -1
- package/skills/frontend-design/SKILL.md +3 -1
- package/skills/nextjs-app-router/SKILL.md +29 -9
- package/skills/owasp-security-review/SKILL.md +31 -9
- package/skills/planning/SKILL.md +11 -5
- package/skills/postgres-migrations/SKILL.md +25 -7
- package/skills/supabase-auth-rls/SKILL.md +41 -9
- package/skills/testing-qa/SKILL.md +5 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 3,
|
|
3
3
|
"packageName": "@appsforgood/next-supabase-kit",
|
|
4
|
-
"packageVersion": "0.4.
|
|
4
|
+
"packageVersion": "0.4.2",
|
|
5
5
|
"stack": "next-supabase",
|
|
6
6
|
"installedAt": "2026-09-06T01:00:41.569Z",
|
|
7
7
|
"docs": [
|
|
@@ -22,34 +22,34 @@
|
|
|
22
22
|
},
|
|
23
23
|
"assetHashes": {
|
|
24
24
|
"AGENTS.md": "d5b570847e7e283a4603055445d6b8cf87dd6e041305c6a3909fa7cde327db81",
|
|
25
|
-
"USER_GUIDE.md": "
|
|
25
|
+
"USER_GUIDE.md": "0c7c8e543a52503299d7819a9359d4d635f32e3ab6ca0f8eaadf034b26798c32",
|
|
26
26
|
".cursor/rules/cursor-agent-kit.mdc": "850026beea86067d95925eea15eb447365d6a956e0f7f475ebd7fef89043d44b",
|
|
27
27
|
"CLAUDE.md": "d5095edff182babe5c13717bb16cadcd95569d9e4abd37ceb307bb1448b65557",
|
|
28
28
|
".cursor/agents/planner.md": "90676313078391848072fd3a4dc24d8479a7911aa8e7f68a38f46b73074aa6d4",
|
|
29
|
-
".cursor/agents/app-engineer.md": "
|
|
29
|
+
".cursor/agents/app-engineer.md": "e37f6a4f03eb4f66021b5a599657468e9cb33d11abd86a83df02fe198e471b12",
|
|
30
30
|
".cursor/agents/security.md": "d71de67a6c66198c02db47357b9a91d86601659c843835ecb481e9edc651a238",
|
|
31
31
|
".cursor/agents/design.md": "04277841a61c9b3f0ea970a14319fe7c1c199a6be5483d5e69b65c231f8764f8",
|
|
32
32
|
".cursor/agents/qa.md": "a4f77a26ee91d0065d5ef9f7a48ebe9f4466b2d17a2d63cb0ffcbc4bc24b9a73",
|
|
33
33
|
".cursor/agents/copy.md": "11e7df36d16221d71e3290dc5ba07711df7320895ad2215eeebec5afcf43bf21",
|
|
34
|
-
".cursor/skills/planning/SKILL.md": "
|
|
35
|
-
".cursor/skills/nextjs-app-router/SKILL.md": "
|
|
36
|
-
".cursor/skills/supabase-auth-rls/SKILL.md": "
|
|
37
|
-
".cursor/skills/postgres-migrations/SKILL.md": "
|
|
38
|
-
".cursor/skills/owasp-security-review/SKILL.md": "
|
|
34
|
+
".cursor/skills/planning/SKILL.md": "f4f19899f9feb8a32f614e078791bad915bf4fa41e778e27389495c36166c54d",
|
|
35
|
+
".cursor/skills/nextjs-app-router/SKILL.md": "79f5ef6cccf5d675cc8ee6a95dc2e98d86b92b2b60edbc759b7017506d7c9c44",
|
|
36
|
+
".cursor/skills/supabase-auth-rls/SKILL.md": "dc449f156b74a59110f5fc49a684ecf061b757a4805b3849b10771a92972f914",
|
|
37
|
+
".cursor/skills/postgres-migrations/SKILL.md": "453245cd5b4e3d652fe7e5e84fcfb24e64f26ff5da4fd2309c1692c7e6de763e",
|
|
38
|
+
".cursor/skills/owasp-security-review/SKILL.md": "a3bcc4702be5c8d5ca51097671f658030791a24e8c4e4019489b44ffbfece1c5",
|
|
39
39
|
".cursor/skills/frontend-design/SKILL.md": "2fb0c3a9a637af2c0dda28aef1991ee8f30ef2113f02445d9c7403208578d04f",
|
|
40
40
|
".cursor/skills/accessibility-wcag/SKILL.md": "1199b4852c2ad9981834a03dcc86edd1f68d8337d25aa13d3c4ad5518343a520",
|
|
41
41
|
".cursor/skills/browser-qa/SKILL.md": "c04e2fa549d9ef6a7c91280859a6394ac59273e6866d537de879d1f1b5fcff1a",
|
|
42
|
-
".cursor/skills/testing-qa/SKILL.md": "
|
|
42
|
+
".cursor/skills/testing-qa/SKILL.md": "534b9d29f5ca26cba70eb1e037d8da0e414ad0c49159739fedae9dfb4ca6b618",
|
|
43
43
|
".cursor/skills/product-copy/SKILL.md": "2f1982ac949ed32690046f516dfefa1ca85bfb51318b403822696bd12bb982c4",
|
|
44
44
|
".cursor/skills/ship/SKILL.md": "ac426092a1868dd1deb01689dc2f5591dbe40acb2fceec559adce41602bb8d6f",
|
|
45
45
|
".claude/agents/planner.md": "90676313078391848072fd3a4dc24d8479a7911aa8e7f68a38f46b73074aa6d4",
|
|
46
|
-
".claude/agents/app-engineer.md": "
|
|
46
|
+
".claude/agents/app-engineer.md": "e37f6a4f03eb4f66021b5a599657468e9cb33d11abd86a83df02fe198e471b12",
|
|
47
47
|
".claude/agents/security.md": "d71de67a6c66198c02db47357b9a91d86601659c843835ecb481e9edc651a238",
|
|
48
48
|
".claude/agents/design.md": "04277841a61c9b3f0ea970a14319fe7c1c199a6be5483d5e69b65c231f8764f8",
|
|
49
49
|
".claude/agents/qa.md": "a4f77a26ee91d0065d5ef9f7a48ebe9f4466b2d17a2d63cb0ffcbc4bc24b9a73",
|
|
50
50
|
".claude/agents/copy.md": "11e7df36d16221d71e3290dc5ba07711df7320895ad2215eeebec5afcf43bf21",
|
|
51
51
|
".codex/agents/planner.toml": "f55f218778ae76942e6c7ea9a159e89dc5c13466b0effa0c43935b29d8182d11",
|
|
52
|
-
".codex/agents/app-engineer.toml": "
|
|
52
|
+
".codex/agents/app-engineer.toml": "f76f6f9a531974becdd863bfb4a0bf1b6810e966d31b7fb6a4f41f8791a8fb59",
|
|
53
53
|
".codex/agents/security.toml": "9e202a8125ddce38d84487a59d7c7cd7328acb8c441704f670b8331042be15f0",
|
|
54
54
|
".codex/agents/design.toml": "6b9114c3ab55db610cc38632939930d966282a427ba0fba4c4c6178f43d10725",
|
|
55
55
|
".codex/agents/qa.toml": "07f53a37d896203707bcb28d19e5a502194a3276faa387bff3739e8d876af564",
|
|
@@ -63,32 +63,32 @@
|
|
|
63
63
|
".antigravity/agent-kit/commands/copy.toml": "40ad093163915a9f000bf8344e49c37dc2d735ab404e84430323502af0bf031e",
|
|
64
64
|
".antigravity/agent-kit/commands/test.toml": "238f3d670c0ecabeab38204fe0a42b32fc5cbdad885b706715f17075c855c9d7",
|
|
65
65
|
".antigravity/agent-kit/commands/ship.toml": "dfa8a6bc654e7bfbf06ad1af59f122a8b116b84008b5ab9325ce21eba3eab9ef",
|
|
66
|
-
".antigravity/runtime-skills/planning/SKILL.md": "
|
|
67
|
-
".antigravity/runtime-skills/nextjs-app-router/SKILL.md": "
|
|
68
|
-
".antigravity/runtime-skills/supabase-auth-rls/SKILL.md": "
|
|
69
|
-
".antigravity/runtime-skills/postgres-migrations/SKILL.md": "
|
|
70
|
-
".antigravity/runtime-skills/owasp-security-review/SKILL.md": "
|
|
66
|
+
".antigravity/runtime-skills/planning/SKILL.md": "f4f19899f9feb8a32f614e078791bad915bf4fa41e778e27389495c36166c54d",
|
|
67
|
+
".antigravity/runtime-skills/nextjs-app-router/SKILL.md": "79f5ef6cccf5d675cc8ee6a95dc2e98d86b92b2b60edbc759b7017506d7c9c44",
|
|
68
|
+
".antigravity/runtime-skills/supabase-auth-rls/SKILL.md": "dc449f156b74a59110f5fc49a684ecf061b757a4805b3849b10771a92972f914",
|
|
69
|
+
".antigravity/runtime-skills/postgres-migrations/SKILL.md": "453245cd5b4e3d652fe7e5e84fcfb24e64f26ff5da4fd2309c1692c7e6de763e",
|
|
70
|
+
".antigravity/runtime-skills/owasp-security-review/SKILL.md": "a3bcc4702be5c8d5ca51097671f658030791a24e8c4e4019489b44ffbfece1c5",
|
|
71
71
|
".antigravity/runtime-skills/frontend-design/SKILL.md": "2fb0c3a9a637af2c0dda28aef1991ee8f30ef2113f02445d9c7403208578d04f",
|
|
72
72
|
".antigravity/runtime-skills/accessibility-wcag/SKILL.md": "1199b4852c2ad9981834a03dcc86edd1f68d8337d25aa13d3c4ad5518343a520",
|
|
73
73
|
".antigravity/runtime-skills/browser-qa/SKILL.md": "c04e2fa549d9ef6a7c91280859a6394ac59273e6866d537de879d1f1b5fcff1a",
|
|
74
|
-
".antigravity/runtime-skills/testing-qa/SKILL.md": "
|
|
74
|
+
".antigravity/runtime-skills/testing-qa/SKILL.md": "534b9d29f5ca26cba70eb1e037d8da0e414ad0c49159739fedae9dfb4ca6b618",
|
|
75
75
|
".antigravity/runtime-skills/product-copy/SKILL.md": "2f1982ac949ed32690046f516dfefa1ca85bfb51318b403822696bd12bb982c4",
|
|
76
76
|
".antigravity/runtime-skills/ship/SKILL.md": "ac426092a1868dd1deb01689dc2f5591dbe40acb2fceec559adce41602bb8d6f",
|
|
77
|
-
"skills/planning/SKILL.md": "
|
|
78
|
-
"skills/nextjs-app-router/SKILL.md": "
|
|
79
|
-
"skills/supabase-auth-rls/SKILL.md": "
|
|
80
|
-
"skills/postgres-migrations/SKILL.md": "
|
|
81
|
-
"skills/owasp-security-review/SKILL.md": "
|
|
77
|
+
"skills/planning/SKILL.md": "f4f19899f9feb8a32f614e078791bad915bf4fa41e778e27389495c36166c54d",
|
|
78
|
+
"skills/nextjs-app-router/SKILL.md": "79f5ef6cccf5d675cc8ee6a95dc2e98d86b92b2b60edbc759b7017506d7c9c44",
|
|
79
|
+
"skills/supabase-auth-rls/SKILL.md": "dc449f156b74a59110f5fc49a684ecf061b757a4805b3849b10771a92972f914",
|
|
80
|
+
"skills/postgres-migrations/SKILL.md": "453245cd5b4e3d652fe7e5e84fcfb24e64f26ff5da4fd2309c1692c7e6de763e",
|
|
81
|
+
"skills/owasp-security-review/SKILL.md": "a3bcc4702be5c8d5ca51097671f658030791a24e8c4e4019489b44ffbfece1c5",
|
|
82
82
|
"skills/frontend-design/SKILL.md": "2fb0c3a9a637af2c0dda28aef1991ee8f30ef2113f02445d9c7403208578d04f",
|
|
83
83
|
"skills/accessibility-wcag/SKILL.md": "1199b4852c2ad9981834a03dcc86edd1f68d8337d25aa13d3c4ad5518343a520",
|
|
84
84
|
"skills/browser-qa/SKILL.md": "c04e2fa549d9ef6a7c91280859a6394ac59273e6866d537de879d1f1b5fcff1a",
|
|
85
|
-
"skills/testing-qa/SKILL.md": "
|
|
85
|
+
"skills/testing-qa/SKILL.md": "534b9d29f5ca26cba70eb1e037d8da0e414ad0c49159739fedae9dfb4ca6b618",
|
|
86
86
|
"skills/product-copy/SKILL.md": "2f1982ac949ed32690046f516dfefa1ca85bfb51318b403822696bd12bb982c4",
|
|
87
87
|
"skills/ship/SKILL.md": "ac426092a1868dd1deb01689dc2f5591dbe40acb2fceec559adce41602bb8d6f",
|
|
88
|
-
"USER_GUIDE.html": "
|
|
88
|
+
"USER_GUIDE.html": "7781238feb3e87b2fa539ac7a74a735632542e02c6f3dfed10846246a7bada96",
|
|
89
89
|
".cursor/skills/deslop/SKILL.md": "ca328ee5d66335639d608059ea9aabef17f70188931d46077dde11583969dea0",
|
|
90
90
|
".antigravity/runtime-skills/deslop/SKILL.md": "ca328ee5d66335639d608059ea9aabef17f70188931d46077dde11583969dea0",
|
|
91
91
|
"skills/deslop/SKILL.md": "ca328ee5d66335639d608059ea9aabef17f70188931d46077dde11583969dea0"
|
|
92
92
|
},
|
|
93
|
-
"updatedAt": "2026-09-
|
|
93
|
+
"updatedAt": "2026-09-09T05:16:37.821Z"
|
|
94
94
|
}
|
|
@@ -38,7 +38,7 @@ Second pass: re-read the rewrite. If the same tell remains, rewrite the paragrap
|
|
|
38
38
|
|
|
39
39
|
## Visual P0s — fail if still on screen
|
|
40
40
|
|
|
41
|
-
These are the 2026
|
|
41
|
+
These are the 2026 flat AI/SaaS chrome cluster (same family as accent-border cards, glow rails, and card soup). One is a smell. Two or more is a reject. A pick-list row or status well with a left stroke is already a fail.
|
|
42
42
|
|
|
43
43
|
- Purple-to-blue (or indigo) gradient hero, or gradient-clipped headline type
|
|
44
44
|
- Inter / Roboto / default shadcn zinc as the whole identity
|
|
@@ -48,6 +48,12 @@ These are the 2026 convergence cluster. One is a smell. Two or more is a reject.
|
|
|
48
48
|
- Acid green or neon vermilion on near-black used as decoration, not meaning
|
|
49
49
|
- Lucide Sparkles / Zap as the product metaphor
|
|
50
50
|
- Fake dashboard metrics or DiceBear avatars
|
|
51
|
+
- Left accent bars / left-hand borderlines on selected rows, list items, cards, or success/error/warn wells (the “colored stroke on the left edge” pattern)
|
|
52
|
+
- Thick one-sided colored borders, glow rails, neon strokes, or gradient borders used as the main state cue
|
|
53
|
+
|
|
54
|
+
Selection must use radio/checkbox + light row tint (or weight/space) only. Status wells may use a flat tint fill. No `border-left` accent, no inset bar, no vertical rail as decoration. Keep one accent for the primary CTA, not as a row edge.
|
|
55
|
+
|
|
56
|
+
**Acceptance fixture:** a pick-list row and a “verified” well must pass with **zero** left border accents. If screenshots show a blue/green/amber left stroke, deslop fails.
|
|
51
57
|
|
|
52
58
|
Copy does not restyle the page. It lists the P0s from the screenshot and sends them to Design.
|
|
53
59
|
|
package/examples/next-supabase-installed/.antigravity/runtime-skills/frontend-design/SKILL.md
CHANGED
|
@@ -77,7 +77,9 @@ One family, or two that are obviously different (display vs mono). Inter + syste
|
|
|
77
77
|
- Mobile (~390): the primary CTA still fits above the fold.
|
|
78
78
|
- Hierarchy from size, weight, and space — not from cards.
|
|
79
79
|
- Landing and marketing pages take a full direction. App chrome (settings, tables) stays quiet and dense.
|
|
80
|
-
-
|
|
80
|
+
- Do not mark selection or severity with a left edge stroke. That pattern reads as default AI/SaaS chrome even on flat full-bleed sheets.
|
|
81
|
+
- Prefer: radio + tint, check + tint, or typography/weight. Keep one accent for the primary CTA, not as a row edge.
|
|
82
|
+
- Reject: centered hero + two pills + three icon cards; glass navbar; four-column empty footer; fake metrics; broadsheet hairlines + dense newsprint columns (that look is itself a 2026 default); left selection rails; callouts whose only cue is a thick left border.
|
|
81
83
|
|
|
82
84
|
## Motion
|
|
83
85
|
|
package/examples/next-supabase-installed/.antigravity/runtime-skills/nextjs-app-router/SKILL.md
CHANGED
|
@@ -1,23 +1,43 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: nextjs-app-router
|
|
3
|
-
description: Use for Next.js App Router
|
|
3
|
+
description: Use for Next.js App Router — Server vs Client, Server Actions, Route Handlers, async params/cookies, caching, and proxy.ts. Smoke the changed route in the browser.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Next.js App Router
|
|
7
7
|
|
|
8
|
+
Scan 2026-09-09 (structure only, no bodies copied): Next.js App Router docs, Next.js 16 async request APIs and `proxy.ts` rename. This pack’s auth is **Supabase**, not a marketplace auth vendor.
|
|
9
|
+
|
|
8
10
|
## Use when
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
`app/` routes, layouts, Server Components, Client Components, Server Actions, Route Handlers, `params` / `searchParams`, `cookies()` / `headers()`, caching, or request interception (`proxy.ts` / legacy `middleware.ts`).
|
|
13
|
+
|
|
14
|
+
## Do
|
|
15
|
+
|
|
16
|
+
1. Read the existing `app/` tree and match its conventions (`src/app` vs `app`).
|
|
17
|
+
2. Keep the work on the **server** unless the browser must hold state, events, or Web APIs.
|
|
18
|
+
3. Put mutations in Server Actions (forms) or Route Handlers (HTTP). Validate every input.
|
|
19
|
+
4. After a user-visible change, open the running route before handing to QA.
|
|
11
20
|
|
|
12
21
|
## Checks
|
|
13
22
|
|
|
14
|
-
- Server Components are the default.
|
|
15
|
-
- Secrets never enter client
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
23
|
+
- Server Components are the default. `"use client"` is only for browser-only behavior (event handlers, local state, browser APIs).
|
|
24
|
+
- Secrets, service-role keys, and privileged fetches never enter a Client Component or a client bundle.
|
|
25
|
+
- `cookies()`, `headers()`, `params`, and `searchParams` are **awaited** (Next.js 15+/16).
|
|
26
|
+
- Navigation uses `next/navigation`, not `next/router`. Metadata uses `metadata` / `generateMetadata`, not `next/head`.
|
|
27
|
+
- Pages Router APIs (`getServerSideProps`, `getStaticProps`, `pages/api`) stay out of new work.
|
|
28
|
+
- Next.js 16 request interception lives in `proxy.ts` (`proxy()`). If the repo still has `middleware.ts`, migrate or document why it stays.
|
|
29
|
+
- User-specific data is not stored in a shared/public cache. Tag invalidation uses the current two-argument `revalidateTag` API when tags are used.
|
|
30
|
+
- Route params, query strings, form fields, and JSON bodies are validated with a schema. Do not trust the URL or the client.
|
|
31
|
+
- `loading.tsx`, `error.tsx`, empty, and success exist for the changed route when the user can wait or fail.
|
|
32
|
+
- Authorization is enforced on the server **and** in RLS (`supabase-auth-rls`). Hiding a button is not access control.
|
|
33
|
+
|
|
34
|
+
## Reject
|
|
35
|
+
|
|
36
|
+
- “It’s a Client Component so we can use hooks” when the data could load on the server.
|
|
37
|
+
- Importing `@supabase/supabase-js` with the service-role key in a file that has `"use client"`.
|
|
38
|
+
- Switching this pack to Clerk / Auth0 / NextAuth as the default. Auth here is Supabase.
|
|
39
|
+
- Shipping a route from the diff without opening it.
|
|
20
40
|
|
|
21
41
|
## Done when
|
|
22
42
|
|
|
23
|
-
The server/client boundary is explicit and the changed route
|
|
43
|
+
The server/client boundary is explicit, failure paths are named, and the changed route was opened in the running app. User-visible work then goes to QA with `browser-qa`.
|
package/examples/next-supabase-installed/.antigravity/runtime-skills/owasp-security-review/SKILL.md
CHANGED
|
@@ -1,23 +1,45 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: owasp-security-review
|
|
3
|
-
description: Use when reviewing auth,
|
|
3
|
+
description: Use when reviewing auth, Server Actions, Route Handlers, uploads, webhooks, SSRF, secrets, or data mutations in a Next.js + Supabase app.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OWASP Security Review
|
|
7
7
|
|
|
8
|
+
Scan 2026-09-09: OWASP Top 10 mapped onto this pack (App Router + Supabase). Pair with `supabase-auth-rls`. Do not treat a UI walkthrough as access control.
|
|
9
|
+
|
|
8
10
|
## Use when
|
|
9
11
|
|
|
10
|
-
Auth,
|
|
12
|
+
Auth, RLS, Server Actions, Route Handlers, uploads, webhooks, server-side `fetch`, new dependencies, or any mutation.
|
|
11
13
|
|
|
12
14
|
## Checks
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
Map each change to a concrete control. Skip rows that do not apply; do not skip access control when data is involved.
|
|
17
|
+
|
|
18
|
+
| Risk | In this pack |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| Broken access control / IDOR | RLS + server checks. Object IDs in params/body cannot reach another user’s row. |
|
|
21
|
+
| Cryptographic failures | No secrets in git, logs, or client bundles. Service role is server-only. |
|
|
22
|
+
| Injection | Schema-validate inputs. Parameterized queries / Supabase client. No string-built SQL. |
|
|
23
|
+
| Insecure design | Abuse case named (anon, other user, stolen cookie, replayed action). |
|
|
24
|
+
| Misconfiguration | CORS, env, debug flags, Storage public/private. |
|
|
25
|
+
| Vulnerable components | New deps reviewed; no known critical CVE waved through. |
|
|
26
|
+
| Auth failures | Login, logout, refresh, denied. `getUser()` on the server. |
|
|
27
|
+
| Integrity | Lockfile + CI. No postinstall scripts from untrusted packages. |
|
|
28
|
+
| Logging | Privileged actions log without tokens, cookies, or PII dumps. |
|
|
29
|
+
| SSRF | Server `fetch` / webhook URLs are allowlisted or parsed; no user-controlled hostname to cloud metadata. |
|
|
30
|
+
|
|
31
|
+
## Server Actions And Route Handlers
|
|
32
|
+
|
|
33
|
+
- Every mutation validates origin/input. Do not trust hidden form fields for `user_id` or `role`.
|
|
34
|
+
- CSRF: cookie-session apps use SameSite and origin checks on state-changing POST.
|
|
35
|
+
- File uploads: type, size, and Storage policy. Do not serve user files from a privileged bucket via a guessable path.
|
|
36
|
+
|
|
37
|
+
## Reject
|
|
38
|
+
|
|
39
|
+
- “RLS is enabled” without a policy that names the owner or tenant.
|
|
40
|
+
- Findings with no severity, no affected behavior, and no fix.
|
|
41
|
+
- Closing a user-visible auth bug from the SQL file alone (needs `browser-qa` for login/denied).
|
|
20
42
|
|
|
21
43
|
## Done when
|
|
22
44
|
|
|
23
|
-
Each finding has severity, affected behavior, and a concrete fix. User-visible auth failures were seen in the browser.
|
|
45
|
+
Each finding has severity, affected behavior, and a concrete fix. Access control is in Postgres or the server, not only the UI. User-visible auth failures were seen in the browser.
|
|
@@ -11,15 +11,21 @@ Planning, roadmaps, “what should we do,” or any request that needs an owner.
|
|
|
11
11
|
|
|
12
12
|
## Steps
|
|
13
13
|
|
|
14
|
-
1. Read enough of the repo to name affected routes and
|
|
14
|
+
1. Read enough of the repo to name affected routes, tables, and auth boundaries.
|
|
15
15
|
2. Pick one owner: `app-engineer`, `security`, `design`, `qa`, or `copy`.
|
|
16
|
-
3.
|
|
17
|
-
|
|
16
|
+
3. Name the skill that owner must run first:
|
|
17
|
+
- App engineer: `nextjs-app-router` and, if data/auth, `supabase-auth-rls` / `postgres-migrations`
|
|
18
|
+
- Security: `owasp-security-review` + `supabase-auth-rls`
|
|
19
|
+
- Design: `frontend-design`
|
|
20
|
+
- QA: `browser-qa` (screens) and `testing-qa` (commands)
|
|
21
|
+
- Copy: `product-copy` then `deslop` last
|
|
22
|
+
4. Add extra reviewers: Security for auth/data/secrets, Design for UI, QA for behavior/UI, Copy for public words.
|
|
23
|
+
5. If the change is user-visible, list the desktop and mobile screenshots QA must capture.
|
|
18
24
|
|
|
19
25
|
## Done when
|
|
20
26
|
|
|
21
|
-
Owner, extra reviewers, preserved behavior, and required screenshots are explicit. No product code was written.
|
|
27
|
+
Owner, extra reviewers, required skills, preserved behavior, and required screenshots are explicit. No product code was written.
|
|
22
28
|
|
|
23
29
|
## Reject
|
|
24
30
|
|
|
25
|
-
Implementing in the planning pass. Asking one chat to play every role.
|
|
31
|
+
Implementing in the planning pass. Asking one chat to play every role. Skipping `supabase-auth-rls` because “it’s just a table.” Skipping `nextjs-app-router` because the route is small.
|
package/examples/next-supabase-installed/.antigravity/runtime-skills/postgres-migrations/SKILL.md
CHANGED
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: postgres-migrations
|
|
3
|
-
description: Use for schema
|
|
3
|
+
description: Use for schema, constraints, indexes, RLS in the same change, generated types, and rollback risk.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Postgres Migrations
|
|
7
7
|
|
|
8
|
+
Scan 2026-09-09 (structure only, no bodies copied): Supabase migration + RLS docs. Pair every user-data table with `supabase-auth-rls`.
|
|
9
|
+
|
|
8
10
|
## Use when
|
|
9
11
|
|
|
10
|
-
Creating or changing tables, constraints, indexes, functions, triggers, or seed data.
|
|
12
|
+
Creating or changing tables, columns, constraints, indexes, functions, triggers, views, or seed data.
|
|
13
|
+
|
|
14
|
+
## Do
|
|
15
|
+
|
|
16
|
+
1. Name the migration, the tables, and whether existing rows must keep working.
|
|
17
|
+
2. Prefer additive changes. Destructive steps need an explicit rollback (or an expand/contract plan).
|
|
18
|
+
3. If the table holds user or tenant data, **RLS lands in this change**, not a later ticket.
|
|
19
|
+
4. Refresh generated DB types after the schema change.
|
|
11
20
|
|
|
12
21
|
## Checks
|
|
13
22
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
23
|
+
- Constraints protect integrity (PK, FK, unique, `NOT NULL` where the product requires it).
|
|
24
|
+
- Indexes match real `WHERE` / join paths, not speculative columns.
|
|
25
|
+
- `ENABLE ROW LEVEL SECURITY` + policies ship with the table when it is user-owned, tenant-owned, or privileged.
|
|
26
|
+
- `GRANT` is not a substitute for RLS. Revoking grants from `anon` / `authenticated` without policies is still incomplete if the service role is exposed.
|
|
27
|
+
- Functions that run as definer are listed and justified. Prefer invoker + RLS.
|
|
28
|
+
- Seed data does not insert other users’ rows as the current user.
|
|
29
|
+
- Migration order is safe on a non-empty database (backfill before `NOT NULL`, rename in steps).
|
|
30
|
+
|
|
31
|
+
## Reject
|
|
32
|
+
|
|
33
|
+
- “We’ll add RLS after launch.”
|
|
34
|
+
- Dropping a column or table in the same release that still reads it, with no expand/contract.
|
|
35
|
+
- Editing production by hand instead of a numbered migration.
|
|
18
36
|
|
|
19
37
|
## Done when
|
|
20
38
|
|
|
21
|
-
Migration order and rollback risk are named. User data is not left unprotected.
|
|
39
|
+
Migration order and rollback risk are named. User data is not left unprotected. Types used by the app match the new schema.
|
package/examples/next-supabase-installed/.antigravity/runtime-skills/supabase-auth-rls/SKILL.md
CHANGED
|
@@ -1,23 +1,55 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-auth-rls
|
|
3
|
-
description: Use for Supabase Auth, SSR clients,
|
|
3
|
+
description: Use for Supabase Auth, SSR clients, session refresh, RLS, Storage policies, and keeping the service role server-only. UI checks are not authorization.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Supabase Auth And RLS
|
|
7
7
|
|
|
8
|
+
Scan 2026-09-09 (structure only, no bodies copied): Supabase SSR Auth, RLS, and Storage policy docs. Do not replace this pack with a non-Supabase auth vendor.
|
|
9
|
+
|
|
8
10
|
## Use when
|
|
9
11
|
|
|
10
|
-
Supabase Auth, SSR clients, middleware
|
|
12
|
+
Supabase Auth, cookie/SSR clients, `proxy.ts` / middleware session refresh, RLS, Storage, service-role usage, or any table that stores user or tenant data.
|
|
13
|
+
|
|
14
|
+
## Do
|
|
15
|
+
|
|
16
|
+
1. Name the table or bucket and who may read or write a row.
|
|
17
|
+
2. Use the **anon/user SSR client** in user requests. Use the **service role** only in a server-only module that never imports into Client Components.
|
|
18
|
+
3. Enable RLS and write policies in the **same change** as the table (`postgres-migrations`).
|
|
19
|
+
4. Prove a negative: another user (or anon) cannot read or write the row.
|
|
20
|
+
|
|
21
|
+
## Clients
|
|
22
|
+
|
|
23
|
+
| Client | Where | Key |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| Browser / `'use client'` | Components that must talk to Supabase in the browser | `NEXT_PUBLIC_SUPABASE_ANON_KEY` only |
|
|
26
|
+
| SSR / Server Components / Actions / Route Handlers | Cookie session, `createServerClient` | Anon key + cookies |
|
|
27
|
+
| Service role | Server-only jobs, webhooks, migrations | `SUPABASE_SERVICE_ROLE_KEY` — never `NEXT_PUBLIC_` |
|
|
28
|
+
|
|
29
|
+
Auth decisions use `getUser()` (or equivalent server verification), not a client-trusted `getSession()` JWT.
|
|
30
|
+
|
|
31
|
+
If the app intercepts requests, refresh the session there (`proxy.ts` or existing `middleware.ts`) so Server Components see a current user.
|
|
32
|
+
|
|
33
|
+
## RLS And Storage
|
|
34
|
+
|
|
35
|
+
- `ENABLE ROW LEVEL SECURITY` on every user-owned, tenant-owned, or privileged table.
|
|
36
|
+
- Policies name ownership (`auth.uid()`) and tenant boundaries. An “authenticated” role is not ownership.
|
|
37
|
+
- Storage buckets have explicit policies. A private bucket with a public URL is a finding.
|
|
38
|
+
- Privileged bypass (service role, `security definer`) is listed, server-only, and as narrow as the job.
|
|
11
39
|
|
|
12
40
|
## Checks
|
|
13
41
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
- Service
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
42
|
+
- IDOR is tested at the **policy** (and server) boundary: object IDs in the URL or body cannot reach another user’s row.
|
|
43
|
+
- Login, logout, expired session, and denied are exercised when those states exist. User-visible ones need `browser-qa`.
|
|
44
|
+
- `.env.example` documents public anon URL/key placeholders only. Service role stays unnamed in client files.
|
|
45
|
+
|
|
46
|
+
## Reject
|
|
47
|
+
|
|
48
|
+
- “The button is hidden, so they cannot hit the API.”
|
|
49
|
+
- RLS deferred to a follow-up PR while the table is already queryable.
|
|
50
|
+
- Service role in `NEXT_PUBLIC_*`, in a Client Component, or in a file imported by one.
|
|
51
|
+
- Trusting `user_id` from the request body instead of `auth.uid()`.
|
|
20
52
|
|
|
21
53
|
## Done when
|
|
22
54
|
|
|
23
|
-
A
|
|
55
|
+
A second user (or anon) cannot read or write the protected row. UI checks are not treated as authorization. Hand user-visible auth states to QA with `browser-qa`.
|
|
@@ -14,14 +14,16 @@ Adding or reviewing tests, smoke checks, or regression coverage.
|
|
|
14
14
|
- Core logic has unit tests.
|
|
15
15
|
- Preserved behavior has regression tests.
|
|
16
16
|
- Critical flows have Playwright or equivalent smoke tests.
|
|
17
|
-
- Auth and mutation paths are prioritized.
|
|
17
|
+
- Auth, RLS, and mutation paths are prioritized (other-user / anon cannot pass).
|
|
18
18
|
- Network failure, empty, and error behavior is covered.
|
|
19
19
|
- Gaps are named when infrastructure is missing.
|
|
20
20
|
|
|
21
|
+
If the change is App Router, Auth/RLS, or a migration, tests must cover those contracts. This skill does not replace `nextjs-app-router`, `supabase-auth-rls`, `postgres-migrations`, or `owasp-security-review`. Visual proof of a screen still uses `browser-qa`.
|
|
22
|
+
|
|
21
23
|
## Visual proof
|
|
22
24
|
|
|
23
|
-
User-visible screens also require `browser-qa`. This skill does not replace screenshots.
|
|
25
|
+
User-visible screens also require `browser-qa`. This skill does not replace screenshots. Passing `toBeVisible` is not image review.
|
|
24
26
|
|
|
25
27
|
## Done when
|
|
26
28
|
|
|
27
|
-
Commands run, results, and residual gaps are listed.
|
|
29
|
+
Commands run, results, and residual gaps are listed. RLS/auth tests fail closed when another user can read the row.
|
|
@@ -23,6 +23,8 @@ Code-only “it should work” is incomplete for anything the user can see or cl
|
|
|
23
23
|
|
|
24
24
|
`nextjs-app-router`, `supabase-auth-rls`, `postgres-migrations`.
|
|
25
25
|
|
|
26
|
+
Run those skills. Do not treat a small route, form, or table as exempt.
|
|
27
|
+
|
|
26
28
|
Available skills: `catalog.json` and the skill table in `USER_GUIDE.md`. Start with the skills named above. Use another listed skill when this job needs it.
|
|
27
29
|
|
|
28
30
|
## Handoff
|
|
@@ -28,6 +28,8 @@ Code-only “it should work” is incomplete for anything the user can see or cl
|
|
|
28
28
|
|
|
29
29
|
`nextjs-app-router`, `supabase-auth-rls`, `postgres-migrations`.
|
|
30
30
|
|
|
31
|
+
Run those skills. Do not treat a small route, form, or table as exempt.
|
|
32
|
+
|
|
31
33
|
Available skills: `catalog.json` and the skill table in `USER_GUIDE.md`. Start with the skills named above. Use another listed skill when this job needs it.
|
|
32
34
|
|
|
33
35
|
## Handoff
|
|
@@ -23,6 +23,8 @@ Code-only “it should work” is incomplete for anything the user can see or cl
|
|
|
23
23
|
|
|
24
24
|
`nextjs-app-router`, `supabase-auth-rls`, `postgres-migrations`.
|
|
25
25
|
|
|
26
|
+
Run those skills. Do not treat a small route, form, or table as exempt.
|
|
27
|
+
|
|
26
28
|
Available skills: `catalog.json` and the skill table in `USER_GUIDE.md`. Start with the skills named above. Use another listed skill when this job needs it.
|
|
27
29
|
|
|
28
30
|
## Handoff
|
|
@@ -38,7 +38,7 @@ Second pass: re-read the rewrite. If the same tell remains, rewrite the paragrap
|
|
|
38
38
|
|
|
39
39
|
## Visual P0s — fail if still on screen
|
|
40
40
|
|
|
41
|
-
These are the 2026
|
|
41
|
+
These are the 2026 flat AI/SaaS chrome cluster (same family as accent-border cards, glow rails, and card soup). One is a smell. Two or more is a reject. A pick-list row or status well with a left stroke is already a fail.
|
|
42
42
|
|
|
43
43
|
- Purple-to-blue (or indigo) gradient hero, or gradient-clipped headline type
|
|
44
44
|
- Inter / Roboto / default shadcn zinc as the whole identity
|
|
@@ -48,6 +48,12 @@ These are the 2026 convergence cluster. One is a smell. Two or more is a reject.
|
|
|
48
48
|
- Acid green or neon vermilion on near-black used as decoration, not meaning
|
|
49
49
|
- Lucide Sparkles / Zap as the product metaphor
|
|
50
50
|
- Fake dashboard metrics or DiceBear avatars
|
|
51
|
+
- Left accent bars / left-hand borderlines on selected rows, list items, cards, or success/error/warn wells (the “colored stroke on the left edge” pattern)
|
|
52
|
+
- Thick one-sided colored borders, glow rails, neon strokes, or gradient borders used as the main state cue
|
|
53
|
+
|
|
54
|
+
Selection must use radio/checkbox + light row tint (or weight/space) only. Status wells may use a flat tint fill. No `border-left` accent, no inset bar, no vertical rail as decoration. Keep one accent for the primary CTA, not as a row edge.
|
|
55
|
+
|
|
56
|
+
**Acceptance fixture:** a pick-list row and a “verified” well must pass with **zero** left border accents. If screenshots show a blue/green/amber left stroke, deslop fails.
|
|
51
57
|
|
|
52
58
|
Copy does not restyle the page. It lists the P0s from the screenshot and sends them to Design.
|
|
53
59
|
|
|
@@ -77,7 +77,9 @@ One family, or two that are obviously different (display vs mono). Inter + syste
|
|
|
77
77
|
- Mobile (~390): the primary CTA still fits above the fold.
|
|
78
78
|
- Hierarchy from size, weight, and space — not from cards.
|
|
79
79
|
- Landing and marketing pages take a full direction. App chrome (settings, tables) stays quiet and dense.
|
|
80
|
-
-
|
|
80
|
+
- Do not mark selection or severity with a left edge stroke. That pattern reads as default AI/SaaS chrome even on flat full-bleed sheets.
|
|
81
|
+
- Prefer: radio + tint, check + tint, or typography/weight. Keep one accent for the primary CTA, not as a row edge.
|
|
82
|
+
- Reject: centered hero + two pills + three icon cards; glass navbar; four-column empty footer; fake metrics; broadsheet hairlines + dense newsprint columns (that look is itself a 2026 default); left selection rails; callouts whose only cue is a thick left border.
|
|
81
83
|
|
|
82
84
|
## Motion
|
|
83
85
|
|
|
@@ -1,23 +1,43 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: nextjs-app-router
|
|
3
|
-
description: Use for Next.js App Router
|
|
3
|
+
description: Use for Next.js App Router — Server vs Client, Server Actions, Route Handlers, async params/cookies, caching, and proxy.ts. Smoke the changed route in the browser.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Next.js App Router
|
|
7
7
|
|
|
8
|
+
Scan 2026-09-09 (structure only, no bodies copied): Next.js App Router docs, Next.js 16 async request APIs and `proxy.ts` rename. This pack’s auth is **Supabase**, not a marketplace auth vendor.
|
|
9
|
+
|
|
8
10
|
## Use when
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
`app/` routes, layouts, Server Components, Client Components, Server Actions, Route Handlers, `params` / `searchParams`, `cookies()` / `headers()`, caching, or request interception (`proxy.ts` / legacy `middleware.ts`).
|
|
13
|
+
|
|
14
|
+
## Do
|
|
15
|
+
|
|
16
|
+
1. Read the existing `app/` tree and match its conventions (`src/app` vs `app`).
|
|
17
|
+
2. Keep the work on the **server** unless the browser must hold state, events, or Web APIs.
|
|
18
|
+
3. Put mutations in Server Actions (forms) or Route Handlers (HTTP). Validate every input.
|
|
19
|
+
4. After a user-visible change, open the running route before handing to QA.
|
|
11
20
|
|
|
12
21
|
## Checks
|
|
13
22
|
|
|
14
|
-
- Server Components are the default.
|
|
15
|
-
- Secrets never enter client
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
23
|
+
- Server Components are the default. `"use client"` is only for browser-only behavior (event handlers, local state, browser APIs).
|
|
24
|
+
- Secrets, service-role keys, and privileged fetches never enter a Client Component or a client bundle.
|
|
25
|
+
- `cookies()`, `headers()`, `params`, and `searchParams` are **awaited** (Next.js 15+/16).
|
|
26
|
+
- Navigation uses `next/navigation`, not `next/router`. Metadata uses `metadata` / `generateMetadata`, not `next/head`.
|
|
27
|
+
- Pages Router APIs (`getServerSideProps`, `getStaticProps`, `pages/api`) stay out of new work.
|
|
28
|
+
- Next.js 16 request interception lives in `proxy.ts` (`proxy()`). If the repo still has `middleware.ts`, migrate or document why it stays.
|
|
29
|
+
- User-specific data is not stored in a shared/public cache. Tag invalidation uses the current two-argument `revalidateTag` API when tags are used.
|
|
30
|
+
- Route params, query strings, form fields, and JSON bodies are validated with a schema. Do not trust the URL or the client.
|
|
31
|
+
- `loading.tsx`, `error.tsx`, empty, and success exist for the changed route when the user can wait or fail.
|
|
32
|
+
- Authorization is enforced on the server **and** in RLS (`supabase-auth-rls`). Hiding a button is not access control.
|
|
33
|
+
|
|
34
|
+
## Reject
|
|
35
|
+
|
|
36
|
+
- “It’s a Client Component so we can use hooks” when the data could load on the server.
|
|
37
|
+
- Importing `@supabase/supabase-js` with the service-role key in a file that has `"use client"`.
|
|
38
|
+
- Switching this pack to Clerk / Auth0 / NextAuth as the default. Auth here is Supabase.
|
|
39
|
+
- Shipping a route from the diff without opening it.
|
|
20
40
|
|
|
21
41
|
## Done when
|
|
22
42
|
|
|
23
|
-
The server/client boundary is explicit and the changed route
|
|
43
|
+
The server/client boundary is explicit, failure paths are named, and the changed route was opened in the running app. User-visible work then goes to QA with `browser-qa`.
|
|
@@ -1,23 +1,45 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: owasp-security-review
|
|
3
|
-
description: Use when reviewing auth,
|
|
3
|
+
description: Use when reviewing auth, Server Actions, Route Handlers, uploads, webhooks, SSRF, secrets, or data mutations in a Next.js + Supabase app.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# OWASP Security Review
|
|
7
7
|
|
|
8
|
+
Scan 2026-09-09: OWASP Top 10 mapped onto this pack (App Router + Supabase). Pair with `supabase-auth-rls`. Do not treat a UI walkthrough as access control.
|
|
9
|
+
|
|
8
10
|
## Use when
|
|
9
11
|
|
|
10
|
-
Auth,
|
|
12
|
+
Auth, RLS, Server Actions, Route Handlers, uploads, webhooks, server-side `fetch`, new dependencies, or any mutation.
|
|
11
13
|
|
|
12
14
|
## Checks
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
Map each change to a concrete control. Skip rows that do not apply; do not skip access control when data is involved.
|
|
17
|
+
|
|
18
|
+
| Risk | In this pack |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| Broken access control / IDOR | RLS + server checks. Object IDs in params/body cannot reach another user’s row. |
|
|
21
|
+
| Cryptographic failures | No secrets in git, logs, or client bundles. Service role is server-only. |
|
|
22
|
+
| Injection | Schema-validate inputs. Parameterized queries / Supabase client. No string-built SQL. |
|
|
23
|
+
| Insecure design | Abuse case named (anon, other user, stolen cookie, replayed action). |
|
|
24
|
+
| Misconfiguration | CORS, env, debug flags, Storage public/private. |
|
|
25
|
+
| Vulnerable components | New deps reviewed; no known critical CVE waved through. |
|
|
26
|
+
| Auth failures | Login, logout, refresh, denied. `getUser()` on the server. |
|
|
27
|
+
| Integrity | Lockfile + CI. No postinstall scripts from untrusted packages. |
|
|
28
|
+
| Logging | Privileged actions log without tokens, cookies, or PII dumps. |
|
|
29
|
+
| SSRF | Server `fetch` / webhook URLs are allowlisted or parsed; no user-controlled hostname to cloud metadata. |
|
|
30
|
+
|
|
31
|
+
## Server Actions And Route Handlers
|
|
32
|
+
|
|
33
|
+
- Every mutation validates origin/input. Do not trust hidden form fields for `user_id` or `role`.
|
|
34
|
+
- CSRF: cookie-session apps use SameSite and origin checks on state-changing POST.
|
|
35
|
+
- File uploads: type, size, and Storage policy. Do not serve user files from a privileged bucket via a guessable path.
|
|
36
|
+
|
|
37
|
+
## Reject
|
|
38
|
+
|
|
39
|
+
- “RLS is enabled” without a policy that names the owner or tenant.
|
|
40
|
+
- Findings with no severity, no affected behavior, and no fix.
|
|
41
|
+
- Closing a user-visible auth bug from the SQL file alone (needs `browser-qa` for login/denied).
|
|
20
42
|
|
|
21
43
|
## Done when
|
|
22
44
|
|
|
23
|
-
Each finding has severity, affected behavior, and a concrete fix. User-visible auth failures were seen in the browser.
|
|
45
|
+
Each finding has severity, affected behavior, and a concrete fix. Access control is in Postgres or the server, not only the UI. User-visible auth failures were seen in the browser.
|