@luanpdd/kit-mcp 1.32.0 → 1.34.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.
- package/LICENSE +21 -21
- package/README.md +168 -168
- package/gates/agent-no-recursive-dispatch.md +84 -84
- package/kit/COMANDOS.md +138 -138
- package/kit/COMPATIBILITY.md +70 -70
- package/kit/README.md +76 -76
- package/kit/agents/advisor-researcher.md +109 -109
- package/kit/agents/ai-mutation-tester.md +289 -289
- package/kit/agents/assumptions-analyzer.md +110 -110
- package/kit/agents/audit-log-implementer.md +314 -314
- package/kit/agents/auditor-consistencia-isolamento.md +414 -414
- package/kit/agents/b2b-saas-architect.md +157 -157
- package/kit/agents/burn-rate-forecaster.md +153 -153
- package/kit/agents/cascading-failures-auditor.md +299 -299
- package/kit/agents/codebase-mapper.md +769 -769
- package/kit/agents/crm-pipeline-implementer.md +257 -257
- package/kit/agents/debugger.md +814 -814
- package/kit/agents/designer-ui.md +216 -0
- package/kit/agents/detector-tenant-quente.md +338 -338
- package/kit/agents/evolution-go-integrator.md +201 -201
- package/kit/agents/example-reviewer.md +22 -22
- package/kit/agents/executor.md +565 -565
- package/kit/agents/golden-signals-instrumenter.md +232 -232
- package/kit/agents/incident-investigator.md +238 -238
- package/kit/agents/integration-checker.md +203 -203
- package/kit/agents/invite-flow-implementer.md +190 -190
- package/kit/agents/legacy-characterizer.md +369 -369
- package/kit/agents/lgpd-compliance-auditor.md +296 -296
- package/kit/agents/load-shedding-instrumenter.md +290 -290
- package/kit/agents/multi-tenant-isolation-auditor.md +254 -254
- package/kit/agents/multi-tenant-rls-writer.md +341 -341
- package/kit/agents/nyquist-auditor.md +181 -181
- package/kit/agents/observability-coverage-auditor.md +316 -316
- package/kit/agents/observability-instrumenter.md +191 -191
- package/kit/agents/omm-auditor.md +291 -291
- package/kit/agents/org-onboarding-implementer.md +224 -224
- package/kit/agents/payload-capture-instrumenter.md +274 -274
- package/kit/agents/phase-researcher.md +697 -697
- package/kit/agents/plan-checker.md +275 -275
- package/kit/agents/planner.md +923 -923
- package/kit/agents/postmortem-writer.md +273 -273
- package/kit/agents/project-researcher.md +653 -653
- package/kit/agents/prr-conductor.md +287 -287
- package/kit/agents/refactor-safety-auditor.md +405 -405
- package/kit/agents/release-pipeline-auditor.md +364 -364
- package/kit/agents/research-synthesizer.md +246 -246
- package/kit/agents/roadmapper.md +678 -678
- package/kit/agents/schema-checker.md +160 -160
- package/kit/agents/seam-finder.md +360 -360
- package/kit/agents/shotgun-surgery-detector.md +350 -350
- package/kit/agents/slo-engineer.md +217 -217
- package/kit/agents/storytelling-analyst.md +300 -300
- package/kit/agents/supabase-architect.md +249 -249
- package/kit/agents/supabase-auth-bootstrapper.md +400 -400
- package/kit/agents/supabase-auth-hook-writer.md +418 -418
- package/kit/agents/supabase-branching-architect.md +563 -563
- package/kit/agents/supabase-cicd-pipeline-implementer.md +778 -778
- package/kit/agents/supabase-column-privileges-writer.md +400 -400
- package/kit/agents/supabase-edge-fn-tester.md +288 -288
- package/kit/agents/supabase-edge-fn-writer.md +341 -341
- package/kit/agents/supabase-mfa-implementer.md +439 -439
- package/kit/agents/supabase-migration-writer.md +386 -386
- package/kit/agents/supabase-oauth-server-implementer.md +507 -507
- package/kit/agents/supabase-rbac-implementer.md +393 -393
- package/kit/agents/supabase-realtime-implementer.md +364 -364
- package/kit/agents/supabase-rls-hardener.md +522 -522
- package/kit/agents/supabase-rls-writer.md +324 -324
- package/kit/agents/supabase-roles-implementer.md +356 -356
- package/kit/agents/supabase-social-auth-implementer.md +451 -451
- package/kit/agents/supabase-sso-saml-architect.md +549 -549
- package/kit/agents/supabase-storage-implementer.md +407 -407
- package/kit/agents/super-admin-implementer.md +282 -282
- package/kit/agents/toil-auditor.md +268 -268
- package/kit/agents/ui-auditor.md +438 -438
- package/kit/agents/ui-checker.md +305 -305
- package/kit/agents/ui-researcher.md +356 -356
- package/kit/agents/user-profiler.md +176 -176
- package/kit/agents/validador-evolucao-schema.md +336 -336
- package/kit/agents/verifier.md +729 -729
- package/kit/commands/adicionar-backlog.md +75 -75
- package/kit/commands/adicionar-fase.md +42 -42
- package/kit/commands/adicionar-tarefa.md +45 -45
- package/kit/commands/adicionar-testes.md +41 -41
- package/kit/commands/ajuda.md +21 -21
- package/kit/commands/atualizar.md +37 -37
- package/kit/commands/auditar-cascading.md +111 -111
- package/kit/commands/auditar-marco.md +179 -179
- package/kit/commands/auditar-observabilidade-cobertura-workflow.md +121 -0
- package/kit/commands/auditar-observabilidade-cobertura.md +183 -183
- package/kit/commands/auditar-refactor.md +219 -219
- package/kit/commands/auditar-release.md +109 -109
- package/kit/commands/auditar-uat.md +23 -23
- package/kit/commands/autonomo.md +40 -40
- package/kit/commands/branch-pr.md +24 -24
- package/kit/commands/burn-rate-status.md +408 -408
- package/kit/commands/capturar-payloads.md +193 -193
- package/kit/commands/caracterizar.md +212 -212
- package/kit/commands/concluir-marco.md +247 -247
- package/kit/commands/configuracoes.md +36 -36
- package/kit/commands/dados-distribuidos.md +188 -188
- package/kit/commands/definir-perfil.md +10 -10
- package/kit/commands/depurar.md +190 -190
- package/kit/commands/detectar-duplicacao.md +197 -197
- package/kit/commands/discutir-fase.md +131 -131
- package/kit/commands/encontrar-seams.md +136 -136
- package/kit/commands/entrar-discord.md +17 -17
- package/kit/commands/estatisticas.md +18 -18
- package/kit/commands/example-greeting.md +33 -33
- package/kit/commands/executar-fase.md +58 -58
- package/kit/commands/expresso.md +56 -56
- package/kit/commands/fase-ui.md +34 -34
- package/kit/commands/fazer.md +57 -57
- package/kit/commands/fio.md +125 -125
- package/kit/commands/fluxos-trabalho.md +64 -64
- package/kit/commands/forense.md +176 -176
- package/kit/commands/gerenciador.md +38 -38
- package/kit/commands/inserir-fase.md +31 -31
- package/kit/commands/legacy.md +263 -263
- package/kit/commands/limpeza.md +17 -17
- package/kit/commands/listar-hipoteses-fase.md +45 -45
- package/kit/commands/listar-workspaces.md +18 -18
- package/kit/commands/load-shedding.md +117 -117
- package/kit/commands/mapear-codebase.md +70 -70
- package/kit/commands/multi-tenant.md +163 -163
- package/kit/commands/nota.md +33 -33
- package/kit/commands/novo-marco.md +43 -43
- package/kit/commands/novo-projeto.md +41 -41
- package/kit/commands/novo-workspace.md +43 -43
- package/kit/commands/pausar-trabalho.md +37 -37
- package/kit/commands/perfil-usuario.md +45 -45
- package/kit/commands/pesquisar-fase.md +195 -195
- package/kit/commands/planejar-fase.md +67 -67
- package/kit/commands/planejar-lacunas.md +33 -33
- package/kit/commands/plantar-ideia.md +25 -25
- package/kit/commands/progresso.md +24 -24
- package/kit/commands/proximo.md +30 -30
- package/kit/commands/publicar.md +490 -490
- package/kit/commands/rapido.md +35 -35
- package/kit/commands/reaplicar-patches.md +124 -124
- package/kit/commands/refactor-seguro.md +321 -321
- package/kit/commands/relatorio-sessao.md +19 -19
- package/kit/commands/remover-fase.md +31 -31
- package/kit/commands/remover-workspace.md +26 -26
- package/kit/commands/resumo-marco.md +50 -50
- package/kit/commands/retomar-trabalho.md +40 -40
- package/kit/commands/revisar-backlog.md +60 -60
- package/kit/commands/revisar-ui.md +32 -32
- package/kit/commands/revisar.md +37 -37
- package/kit/commands/saude.md +21 -21
- package/kit/commands/setup-notion.md +93 -93
- package/kit/commands/storytelling.md +179 -179
- package/kit/commands/supabase.md +238 -238
- package/kit/commands/sync-main.md +68 -68
- package/kit/commands/validar-fase.md +35 -35
- package/kit/commands/verificar-tarefas.md +44 -44
- package/kit/commands/verificar-trabalho.md +64 -64
- package/kit/file-manifest.json +13 -3
- package/kit/framework/bin/lib/commands.cjs +959 -959
- package/kit/framework/bin/lib/config.cjs +442 -442
- package/kit/framework/bin/lib/core.cjs +1230 -1230
- package/kit/framework/bin/lib/frontmatter.cjs +336 -336
- package/kit/framework/bin/lib/init.cjs +1442 -1442
- package/kit/framework/bin/lib/milestone.cjs +252 -252
- package/kit/framework/bin/lib/model-profiles.cjs +68 -68
- package/kit/framework/bin/lib/phase.cjs +888 -888
- package/kit/framework/bin/lib/profile-output.cjs +952 -952
- package/kit/framework/bin/lib/profile-pipeline.cjs +539 -539
- package/kit/framework/bin/lib/roadmap.cjs +329 -329
- package/kit/framework/bin/lib/security.cjs +382 -382
- package/kit/framework/bin/lib/state.cjs +1031 -1031
- package/kit/framework/bin/lib/template.cjs +222 -222
- package/kit/framework/bin/lib/uat.cjs +282 -282
- package/kit/framework/bin/lib/verify.cjs +888 -888
- package/kit/framework/bin/lib/workstream.cjs +491 -491
- package/kit/framework/bin/tools.cjs +918 -918
- package/kit/framework/commands/workstreams.md +63 -63
- package/kit/framework/references/checkpoints.md +778 -778
- package/kit/framework/references/continuation-format.md +249 -249
- package/kit/framework/references/decimal-phase-calculation.md +64 -64
- package/kit/framework/references/git-integration.md +295 -295
- package/kit/framework/references/git-planning-commit.md +38 -38
- package/kit/framework/references/model-profile-resolution.md +36 -36
- package/kit/framework/references/model-profiles.md +139 -139
- package/kit/framework/references/phase-argument-parsing.md +61 -61
- package/kit/framework/references/planning-config.md +202 -202
- package/kit/framework/references/questioning.md +162 -162
- package/kit/framework/references/tdd.md +263 -263
- package/kit/framework/references/ui-brand.md +160 -160
- package/kit/framework/references/user-profiling.md +657 -657
- package/kit/framework/references/verification-patterns.md +612 -612
- package/kit/framework/references/workstream-flag.md +58 -58
- package/kit/framework/templates/DEBUG.md +164 -164
- package/kit/framework/templates/UAT.md +265 -265
- package/kit/framework/templates/UI-SPEC.md +100 -100
- package/kit/framework/templates/VALIDATION.md +76 -76
- package/kit/framework/templates/claude-md.md +122 -122
- package/kit/framework/templates/codebase/architecture.md +185 -185
- package/kit/framework/templates/codebase/concerns.md +205 -205
- package/kit/framework/templates/codebase/conventions.md +204 -204
- package/kit/framework/templates/codebase/integrations.md +192 -192
- package/kit/framework/templates/codebase/stack.md +158 -158
- package/kit/framework/templates/codebase/structure.md +199 -199
- package/kit/framework/templates/codebase/testing.md +301 -301
- package/kit/framework/templates/config.json +44 -44
- package/kit/framework/templates/context.md +352 -352
- package/kit/framework/templates/continue-here.md +78 -78
- package/kit/framework/templates/copilot-instructions.md +7 -7
- package/kit/framework/templates/debug-subagent-prompt.md +91 -91
- package/kit/framework/templates/dev-preferences.md +20 -20
- package/kit/framework/templates/discovery.md +146 -146
- package/kit/framework/templates/discussion-log.md +63 -63
- package/kit/framework/templates/milestone-archive.md +123 -123
- package/kit/framework/templates/milestone.md +115 -115
- package/kit/framework/templates/phase-prompt.md +610 -610
- package/kit/framework/templates/planner-subagent-prompt.md +117 -117
- package/kit/framework/templates/project.md +186 -186
- package/kit/framework/templates/requirements.md +231 -231
- package/kit/framework/templates/research-project/ARCHITECTURE.md +204 -204
- package/kit/framework/templates/research-project/FEATURES.md +147 -147
- package/kit/framework/templates/research-project/PITFALLS.md +200 -200
- package/kit/framework/templates/research-project/STACK.md +120 -120
- package/kit/framework/templates/research-project/SUMMARY.md +170 -170
- package/kit/framework/templates/research.md +419 -419
- package/kit/framework/templates/retrospective.md +54 -54
- package/kit/framework/templates/roadmap.md +202 -202
- package/kit/framework/templates/state.md +176 -176
- package/kit/framework/templates/summary-complex.md +59 -59
- package/kit/framework/templates/summary-minimal.md +41 -41
- package/kit/framework/templates/summary-standard.md +48 -48
- package/kit/framework/templates/summary.md +209 -209
- package/kit/framework/templates/user-profile.md +146 -146
- package/kit/framework/templates/user-setup.md +256 -256
- package/kit/framework/templates/verification-report.md +258 -258
- package/kit/framework/workflows/add-phase.md +112 -112
- package/kit/framework/workflows/add-tests.md +351 -351
- package/kit/framework/workflows/add-todo.md +158 -158
- package/kit/framework/workflows/audit-milestone.md +340 -340
- package/kit/framework/workflows/audit-uat.md +109 -109
- package/kit/framework/workflows/autonomous.md +891 -891
- package/kit/framework/workflows/check-todos.md +177 -177
- package/kit/framework/workflows/cleanup.md +152 -152
- package/kit/framework/workflows/complete-milestone.md +696 -696
- package/kit/framework/workflows/diagnose-issues.md +231 -231
- package/kit/framework/workflows/discovery-phase.md +289 -289
- package/kit/framework/workflows/discuss-phase-assumptions.md +653 -653
- package/kit/framework/workflows/discuss-phase.md +784 -784
- package/kit/framework/workflows/do.md +104 -104
- package/kit/framework/workflows/execute-phase.md +838 -838
- package/kit/framework/workflows/execute-plan.md +510 -510
- package/kit/framework/workflows/fast.md +102 -102
- package/kit/framework/workflows/forensics.md +265 -265
- package/kit/framework/workflows/health.md +181 -181
- package/kit/framework/workflows/help.md +619 -619
- package/kit/framework/workflows/insert-phase.md +130 -130
- package/kit/framework/workflows/list-phase-assumptions.md +178 -178
- package/kit/framework/workflows/list-workspaces.md +56 -56
- package/kit/framework/workflows/manager.md +362 -362
- package/kit/framework/workflows/map-codebase.md +377 -377
- package/kit/framework/workflows/milestone-summary.md +223 -223
- package/kit/framework/workflows/new-milestone.md +486 -486
- package/kit/framework/workflows/new-project.md +1159 -1159
- package/kit/framework/workflows/new-workspace.md +237 -237
- package/kit/framework/workflows/next.md +97 -97
- package/kit/framework/workflows/node-repair.md +92 -92
- package/kit/framework/workflows/note.md +156 -156
- package/kit/framework/workflows/pause-work.md +176 -176
- package/kit/framework/workflows/plan-milestone-gaps.md +273 -273
- package/kit/framework/workflows/plan-phase.md +765 -765
- package/kit/framework/workflows/plant-seed.md +169 -169
- package/kit/framework/workflows/pr-branch.md +129 -129
- package/kit/framework/workflows/profile-user.md +450 -450
- package/kit/framework/workflows/progress.md +507 -507
- package/kit/framework/workflows/quick.md +757 -757
- package/kit/framework/workflows/remove-phase.md +155 -155
- package/kit/framework/workflows/remove-workspace.md +90 -90
- package/kit/framework/workflows/research-phase.md +82 -82
- package/kit/framework/workflows/resume-project.md +326 -326
- package/kit/framework/workflows/review.md +228 -228
- package/kit/framework/workflows/session-report.md +146 -146
- package/kit/framework/workflows/settings.md +283 -283
- package/kit/framework/workflows/ship.md +228 -228
- package/kit/framework/workflows/stats.md +60 -60
- package/kit/framework/workflows/transition.md +671 -671
- package/kit/framework/workflows/ui-phase.md +302 -302
- package/kit/framework/workflows/ui-review.md +165 -165
- package/kit/framework/workflows/update.md +323 -323
- package/kit/framework/workflows/validate-phase.md +174 -174
- package/kit/framework/workflows/verify-phase.md +252 -252
- package/kit/framework/workflows/verify-work.md +637 -637
- package/kit/hooks/check-update.js +118 -118
- package/kit/hooks/context-monitor.js +163 -163
- package/kit/hooks/kit-attribution-reminder.cjs +92 -92
- package/kit/hooks/kit-router.cjs +137 -137
- package/kit/hooks/prompt-guard.js +103 -103
- package/kit/hooks/statusline.js +125 -125
- package/kit/hooks/workflow-guard.js +101 -101
- package/kit/settings.json +45 -45
- package/kit/skills/ai-prompt-characterization/SKILL.md +335 -335
- package/kit/skills/armadilhas-sistemas-distribuidos/SKILL.md +447 -447
- package/kit/skills/audit-log-multi-tenant/SKILL.md +340 -340
- package/kit/skills/b2b-saas-architecture/SKILL.md +300 -300
- package/kit/skills/consistencia-leitura-replica/SKILL.md +385 -385
- package/kit/skills/crm-lead-pipeline-patterns/SKILL.md +343 -343
- package/kit/skills/escolha-modelo-consistencia/SKILL.md +494 -494
- package/kit/skills/evolucao-schema-compativel/SKILL.md +448 -448
- package/kit/skills/evolution-go-whatsapp-integration/SKILL.md +322 -322
- package/kit/skills/example-skill/SKILL.md +42 -42
- package/kit/skills/legacy-api-only-applications/SKILL.md +358 -358
- package/kit/skills/legacy-characterization-tests/SKILL.md +330 -330
- package/kit/skills/legacy-effect-analysis/SKILL.md +331 -331
- package/kit/skills/legacy-extract-class/SKILL.md +203 -203
- package/kit/skills/legacy-programming-by-difference/SKILL.md +252 -252
- package/kit/skills/legacy-seams-and-test-harness/SKILL.md +460 -460
- package/kit/skills/legacy-shotgun-surgery/SKILL.md +286 -286
- package/kit/skills/legacy-sprout-wrap-techniques/SKILL.md +434 -434
- package/kit/skills/legacy-storytelling-naked-crc/SKILL.md +270 -270
- package/kit/skills/lgpd-multi-tenant-compliance/SKILL.md +340 -340
- package/kit/skills/member-invite-flow/SKILL.md +305 -305
- package/kit/skills/member-management-react-shadcn/SKILL.md +328 -328
- package/kit/skills/multi-tenant-performance-scaling/SKILL.md +316 -316
- package/kit/skills/multi-tenant-rls-hierarchy/SKILL.md +342 -342
- package/kit/skills/org-onboarding-flow/SKILL.md +257 -257
- package/kit/skills/org-switcher-react-pattern/SKILL.md +349 -349
- package/kit/skills/permission-gate-react-pattern/SKILL.md +271 -271
- package/kit/skills/postgres-isolamento-concorrencia/SKILL.md +552 -552
- package/kit/skills/pre-refactor-characterization/SKILL.md +421 -421
- package/kit/skills/rbac-permissions-matrix-supabase/SKILL.md +338 -338
- package/kit/skills/streams-eventos-cdc/SKILL.md +711 -711
- package/kit/skills/supabase-auth-hardening/SKILL.md +674 -674
- package/kit/skills/supabase-auth-hooks/SKILL.md +875 -875
- package/kit/skills/supabase-auth-methods/SKILL.md +486 -486
- package/kit/skills/supabase-auth-sessions/SKILL.md +579 -579
- package/kit/skills/supabase-auth-ssr/SKILL.md +306 -306
- package/kit/skills/supabase-branching-workflow/SKILL.md +544 -544
- package/kit/skills/supabase-ci-cd-github-actions/SKILL.md +880 -880
- package/kit/skills/supabase-column-level-security/SKILL.md +426 -426
- package/kit/skills/supabase-config-toml-remotes/SKILL.md +807 -807
- package/kit/skills/supabase-custom-claims-rbac/SKILL.md +472 -472
- package/kit/skills/supabase-edge-functions/SKILL.md +330 -330
- package/kit/skills/supabase-edge-functions-auth/SKILL.md +309 -309
- package/kit/skills/supabase-edge-functions-limits/SKILL.md +302 -302
- package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +279 -279
- package/kit/skills/supabase-edge-functions-testing/SKILL.md +277 -277
- package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +357 -357
- package/kit/skills/supabase-enterprise-sso-saml/SKILL.md +545 -545
- package/kit/skills/supabase-jwt-signing-keys/SKILL.md +399 -399
- package/kit/skills/supabase-mfa/SKILL.md +488 -488
- package/kit/skills/supabase-migration-repair/SKILL.md +823 -823
- package/kit/skills/supabase-migrations/SKILL.md +297 -297
- package/kit/skills/supabase-oauth-server/SKILL.md +537 -537
- package/kit/skills/supabase-pgtap-testing/SKILL.md +1053 -1053
- package/kit/skills/supabase-postgres-roles/SKILL.md +392 -392
- package/kit/skills/supabase-realtime/SKILL.md +460 -460
- package/kit/skills/supabase-rls-defense-in-depth/SKILL.md +418 -418
- package/kit/skills/supabase-rls-policies/SKILL.md +635 -635
- package/kit/skills/supabase-social-oauth/SKILL.md +480 -480
- package/kit/skills/supabase-third-party-auth/SKILL.md +450 -450
- package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
- package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
- package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -0
- package/kit/skills/ui-contexto-produto/SKILL.md +248 -0
- package/kit/skills/ui-cor-estrategia/SKILL.md +213 -0
- package/kit/skills/ui-critica-auditoria/SKILL.md +260 -0
- package/kit/skills/ui-motion-funcional/SKILL.md +264 -0
- package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -0
- package/kit/skills/ui-tipografia/SKILL.md +211 -0
- package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
- package/kit/workflows/auditar-observabilidade-cobertura.workflow.js +250 -0
- package/package.json +65 -63
- package/src/core/kit.js +333 -216
- package/src/core/reflect.js +247 -247
- package/src/core/registry.js +123 -112
- package/src/core/reverse-sync.js +448 -372
- package/src/core/sync.js +477 -437
- package/src/core/watch.js +121 -121
- package/src/mcp-server/index.js +794 -794
|
@@ -1,341 +1,341 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: multi-tenant-rls-writer
|
|
3
|
-
tier: specialized
|
|
4
|
-
description: Gera RLS policies hierárquicas multi-tenant — org-level, dept-level, role-based, permission-based + super_admin PERMISSIVE bypass.
|
|
5
|
-
tools: Read, Write, Edit, Bash, Grep, Glob, Task, mcp__supabase__execute_sql, mcp__supabase__list_tables
|
|
6
|
-
color: red
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
Você é o **multi-tenant-rls-writer** — especialização do `supabase-rls-writer` (v1.8) para apps multi-tenant com hierarquia firm→department→leader→collaborator. Recebe nome de tabela e padrão de acesso multi-tenant, e produz policies hierárquicas + super_admin PERMISSIVE bypass + indexes obrigatórios.
|
|
10
|
-
|
|
11
|
-
**Compat:** Full em Claude Code + Cursor (com Supabase MCP); Partial em Codex + Gemini CLI; Offline-only em outros.
|
|
12
|
-
|
|
13
|
-
## Por que existe
|
|
14
|
-
|
|
15
|
-
`supabase-rls-writer` (v1.8) cobre patterns single-tenant (per-user, per-org via array). Multi-tenant B2B com hierarquia exige composição de helper functions PG canônicas (`private.is_member_of`, `private.has_role`, `private.has_permission`, `private.is_super_admin`) + super_admin bypass via PERMISSIVE separada. Este agent **não duplica** — herda anti-pitfalls v1.8 explicitamente e adiciona o pattern hierárquico.
|
|
16
|
-
|
|
17
|
-
## Regras herdadas de `supabase-rls-writer` (v1.8)
|
|
18
|
-
|
|
19
|
-
**Aplicam-se SEMPRE — não são opcionais nesta versão:**
|
|
20
|
-
|
|
21
|
-
- **`(select auth.uid())` wrapper** obrigatório (anti-pitfall #1 v1.8 — performance)
|
|
22
|
-
- **NUNCA** `user_metadata` em policy de autorização — ABORT explícito (anti-pitfall #2 v1.8 — privilege escalation B5)
|
|
23
|
-
- **4 policies granulares** (SELECT/INSERT/UPDATE/DELETE) — nunca `for all` (anti-pitfall #3 v1.8)
|
|
24
|
-
- **`to authenticated`/`to anon`** explícito (anti-pitfall #4 v1.8)
|
|
25
|
-
- **Index obrigatório** nas colunas referenciadas pela policy (anti-pitfall #5 v1.8)
|
|
26
|
-
|
|
27
|
-
Ver [`supabase-rls-policies`](../skills/supabase-rls-policies/SKILL.md) e [`supabase-rls-writer`](./supabase-rls-writer.md) para detalhes.
|
|
28
|
-
|
|
29
|
-
## Inputs esperados (do caller)
|
|
30
|
-
|
|
31
|
-
- `table_name`: nome da tabela (ex: `public.leads`)
|
|
32
|
-
- `access_pattern`: descrição de quem pode ler/escrever, ex:
|
|
33
|
-
- "members da org podem ler; admins podem escrever; super_admin tem bypass"
|
|
34
|
-
- "members da org podem ler com permission leads:list; member com permission leads:create pode insert; admins podem update; super_admin bypass"
|
|
35
|
-
- "members do dept podem ler (com herança de role); members com permission deals:close podem update; super_admin bypass"
|
|
36
|
-
- (Opcional) `super_admin_bypass`: `true` (default) | `false` — se `false`, pula PERMISSIVE policy
|
|
37
|
-
- (Opcional) `audit_super_admin`: `true` (default) | `false` — se `true`, gera trigger AFTER que loga em audit_log quando super_admin executa
|
|
38
|
-
|
|
39
|
-
## Passos
|
|
40
|
-
|
|
41
|
-
### Step 0 — Preflight
|
|
42
|
-
|
|
43
|
-
Detectar capabilities MCP. Se falhar, modo offline (output será SQL puro).
|
|
44
|
-
|
|
45
|
-
### Step 1 — Validar `access_pattern` (anti-pitfall B5 — herdado v1.8)
|
|
46
|
-
|
|
47
|
-
**ABORT condition:** se `access_pattern` menciona `user_metadata`, retorne erro:
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
✗ ERRO: user_metadata em policy de autorização — privilege escalation.
|
|
51
|
-
|
|
52
|
-
`user_metadata` é editável pelo cliente via `auth.updateUser({ data: ... })`.
|
|
53
|
-
|
|
54
|
-
Use `app_metadata.super_admin` para super-admin (set apenas via service_role + admin API),
|
|
55
|
-
e helper functions `private.has_role`, `private.has_permission` para roles/permissions.
|
|
56
|
-
|
|
57
|
-
Exemplo:
|
|
58
|
-
Errado: (auth.jwt()->'user_metadata'->>'super_admin')::boolean = true
|
|
59
|
-
Certo: private.is_super_admin()
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Step 2 — Detectar pré-requisitos Phase 106 + Phase 108 helpers
|
|
63
|
-
|
|
64
|
-
```sql
|
|
65
|
-
-- via mcp__supabase__execute_sql
|
|
66
|
-
select proname from pg_proc where pronamespace = 'private'::regnamespace
|
|
67
|
-
and proname in ('is_member_of', 'has_role', 'has_permission', 'is_super_admin');
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Se faltar alguma helper function: **ABORT** com mensagem orientando criar via Phase 108.
|
|
71
|
-
|
|
72
|
-
### Step 3 — Detectar schema da tabela (live mode)
|
|
73
|
-
|
|
74
|
-
```sql
|
|
75
|
-
select column_name, data_type, is_nullable
|
|
76
|
-
from information_schema.columns
|
|
77
|
-
where table_schema = 'public' and table_name = '<table>'
|
|
78
|
-
order by ordinal_position;
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Confirma colunas usáveis: `org_id` (obrigatório multi-tenant), `dept_id` (opcional), `owner_id` (opcional).
|
|
82
|
-
|
|
83
|
-
Se `org_id` ausente → ABORT: "Tabela não tem coluna `org_id` — não é multi-tenant. Use `supabase-rls-writer` v1.8 padrão."
|
|
84
|
-
|
|
85
|
-
### Step 4 — Gerar 4 policies granulares (herdado v1.8) + PERMISSIVE super_admin
|
|
86
|
-
|
|
87
|
-
**Template multi-tenant org-level:**
|
|
88
|
-
|
|
89
|
-
```sql
|
|
90
|
-
-- Habilitar RLS
|
|
91
|
-
alter table public.<table> enable row level security;
|
|
92
|
-
|
|
93
|
-
-- POLICY 1: SELECT — members da org
|
|
94
|
-
create policy "<table>_select_member"
|
|
95
|
-
on public.<table>
|
|
96
|
-
for select
|
|
97
|
-
to authenticated
|
|
98
|
-
using (private.is_member_of(org_id));
|
|
99
|
-
|
|
100
|
-
-- POLICY 2: INSERT — member com permission
|
|
101
|
-
create policy "<table>_insert_with_permission"
|
|
102
|
-
on public.<table>
|
|
103
|
-
for insert
|
|
104
|
-
to authenticated
|
|
105
|
-
with check (
|
|
106
|
-
private.has_permission('create', '<resource>', org_id)
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
-- POLICY 3: UPDATE — member com permission OU é owner
|
|
110
|
-
create policy "<table>_update_with_permission_or_owner"
|
|
111
|
-
on public.<table>
|
|
112
|
-
for update
|
|
113
|
-
to authenticated
|
|
114
|
-
using (
|
|
115
|
-
private.has_permission('update', '<resource>', org_id)
|
|
116
|
-
or owner_id = (select auth.uid())
|
|
117
|
-
)
|
|
118
|
-
with check (
|
|
119
|
-
private.has_permission('update', '<resource>', org_id)
|
|
120
|
-
or owner_id = (select auth.uid())
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
-- POLICY 4: DELETE — admin/owner role
|
|
124
|
-
create policy "<table>_delete_admin_owner"
|
|
125
|
-
on public.<table>
|
|
126
|
-
for delete
|
|
127
|
-
to authenticated
|
|
128
|
-
using (
|
|
129
|
-
private.has_role(org_id, 'admin') or private.has_role(org_id, 'owner')
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
-- POLICY 5 (PERMISSIVE — REGRA #4 da skill): super_admin bypass
|
|
133
|
-
create policy "<table>_super_admin_bypass"
|
|
134
|
-
on public.<table>
|
|
135
|
-
as permissive
|
|
136
|
-
for all
|
|
137
|
-
to authenticated
|
|
138
|
-
using (private.is_super_admin())
|
|
139
|
-
with check (private.is_super_admin());
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
**Template dept-level (substitui `private.is_member_of` por verificação dept-scoped):**
|
|
143
|
-
|
|
144
|
-
```sql
|
|
145
|
-
create policy "<table>_select_dept_member"
|
|
146
|
-
on public.<table>
|
|
147
|
-
for select
|
|
148
|
-
to authenticated
|
|
149
|
-
using (
|
|
150
|
-
private.is_member_of(org_id) -- pré-condição: member da org
|
|
151
|
-
and (
|
|
152
|
-
dept_id is null -- recursos sem dept = visíveis a todos members da org
|
|
153
|
-
or exists (
|
|
154
|
-
select 1 from public.department_members dm
|
|
155
|
-
where dm.dept_id = <table>.dept_id
|
|
156
|
-
and dm.user_id = (select auth.uid())
|
|
157
|
-
)
|
|
158
|
-
)
|
|
159
|
-
);
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Step 5 — Indexes obrigatórios
|
|
163
|
-
|
|
164
|
-
```sql
|
|
165
|
-
-- Indexes para colunas referenciadas pelas policies
|
|
166
|
-
create index if not exists <table>_org_id_idx on public.<table> (org_id);
|
|
167
|
-
|
|
168
|
-
-- Se policy usa dept_id
|
|
169
|
-
create index if not exists <table>_org_dept_idx on public.<table> (org_id, dept_id);
|
|
170
|
-
|
|
171
|
-
-- Se policy usa owner_id
|
|
172
|
-
create index if not exists <table>_owner_idx on public.<table> (owner_id) where owner_id is not null;
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Step 6 — Audit super_admin (se audit_super_admin=true)
|
|
176
|
-
|
|
177
|
-
```sql
|
|
178
|
-
-- Trigger AFTER que loga em audit_log quando super_admin executa
|
|
179
|
-
create or replace function private.audit_super_admin_<table>()
|
|
180
|
-
returns trigger
|
|
181
|
-
language plpgsql
|
|
182
|
-
security definer -- precisa escrever em audit_log mesmo sem permission do user
|
|
183
|
-
set search_path = ''
|
|
184
|
-
as $$
|
|
185
|
-
begin
|
|
186
|
-
if private.is_super_admin() then
|
|
187
|
-
insert into public.audit_logs (event_type, actor_id, target_org_id, payload)
|
|
188
|
-
values (
|
|
189
|
-
'super_admin_action',
|
|
190
|
-
(select auth.uid()),
|
|
191
|
-
coalesce(new.org_id, old.org_id),
|
|
192
|
-
jsonb_build_object(
|
|
193
|
-
'table', '<table>',
|
|
194
|
-
'op', tg_op,
|
|
195
|
-
'new_id', coalesce(new.id::text, null),
|
|
196
|
-
'old_id', coalesce(old.id::text, null)
|
|
197
|
-
)
|
|
198
|
-
);
|
|
199
|
-
end if;
|
|
200
|
-
return coalesce(new, old);
|
|
201
|
-
end;
|
|
202
|
-
$$;
|
|
203
|
-
|
|
204
|
-
create trigger audit_super_admin_<table>_trigger
|
|
205
|
-
after insert or update or delete on public.<table>
|
|
206
|
-
for each row execute function private.audit_super_admin_<table>();
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Step 7 — Output
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
═══════════════════════════════════════════════════════════
|
|
213
|
-
RLS POLICIES MULTI-TENANT · public.<table>
|
|
214
|
-
═══════════════════════════════════════════════════════════
|
|
215
|
-
|
|
216
|
-
<SQL completo: alter table + 4 policies + 1 PERMISSIVE super_admin + indexes + (opcional) audit trigger>
|
|
217
|
-
|
|
218
|
-
═══════════════════════════════════════════════════════════
|
|
219
|
-
NOTAS
|
|
220
|
-
═══════════════════════════════════════════════════════════
|
|
221
|
-
- Pattern: <org-level | dept-level | role-based | permission-based | composto>
|
|
222
|
-
- Helpers usados: private.is_member_of, private.has_permission, private.is_super_admin
|
|
223
|
-
- Anti-pitfalls v1.8 herdados:
|
|
224
|
-
- (select auth.uid()) wrapper aplicado em todas as policies ✓
|
|
225
|
-
- Sem user_metadata em policy ✓
|
|
226
|
-
- 4 policies granulares + 1 PERMISSIVE super_admin ✓
|
|
227
|
-
- to authenticated explícito ✓
|
|
228
|
-
- Anti-pitfalls v1.21 adicionais:
|
|
229
|
-
- super_admin via PERMISSIVE separada (não OR embutido) ✓
|
|
230
|
-
- Helpers em schema private (não exposed via PostgREST) ✓
|
|
231
|
-
- Indexes obrigatórios ✓
|
|
232
|
-
- Audit super_admin: <enabled / disabled>
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
## Anti-patterns prevenidos
|
|
236
|
-
|
|
237
|
-
- `user_metadata` em authz → ABORT (herdado v1.8)
|
|
238
|
-
- super_admin bypass via OR embutido na policy normal → usa PERMISSIVE separada
|
|
239
|
-
- Helper function VOLATILE → assume STABLE (helpers de Phase 108 já são STABLE)
|
|
240
|
-
- super_admin sem audit → trigger gerado automaticamente se `audit_super_admin=true`
|
|
241
|
-
- Tabela sem `org_id` → ABORT (use supabase-rls-writer v1.8 single-tenant)
|
|
242
|
-
- Helpers em schema public → assume schema private (Phase 108)
|
|
243
|
-
|
|
244
|
-
## Quando NÃO invocar
|
|
245
|
-
|
|
246
|
-
- Tabela single-tenant (per-user simples) → use `supabase-rls-writer` v1.8
|
|
247
|
-
- Tabela com policies já estabelecidas e ajuste pequeno → use Edit direto
|
|
248
|
-
- Catálogo público (`public.permissions`) → leitura `to authenticated` sem RLS hierárquica
|
|
249
|
-
|
|
250
|
-
## Observabilidade integrada
|
|
251
|
-
|
|
252
|
-
- RLS denials emitem evento `rls_deny` em `obs.events` (cross-ref [`structured-events`](../skills/structured-events/SKILL.md))
|
|
253
|
-
- super_admin actions emitem evento `super_admin_action` em `audit_logs` (Phase 109)
|
|
254
|
-
- Counter `rls.deny.count{tenant_id, policy}` (cross-ref [`four-golden-signals`](../skills/four-golden-signals/SKILL.md))
|
|
255
|
-
|
|
256
|
-
## Cooperative handoff to supabase-rls-hardener (v1.23)
|
|
257
|
-
|
|
258
|
-
Após gerar policies RLS hierárquicas, faça handoff cooperativo para `supabase-rls-hardener` validar defense-in-depth:
|
|
259
|
-
|
|
260
|
-
```python
|
|
261
|
-
Task(subagent_type="supabase-rls-hardener", prompt=f"""
|
|
262
|
-
<upstream_intent>
|
|
263
|
-
Source agent: multi-tenant-rls-writer
|
|
264
|
-
Original goal: gerar policies RLS hierárquicas org→dept→role→permission para {table_name}
|
|
265
|
-
Constraints: helper functions já existem em schema private (is_member_of, has_role, has_permission, is_super_admin); STABLE; partial index em organization_members
|
|
266
|
-
</upstream_intent>
|
|
267
|
-
|
|
268
|
-
<draft_sql>{generated_policies_sql}</draft_sql>
|
|
269
|
-
|
|
270
|
-
<user_facing_caller>true</user_facing_caller>
|
|
271
|
-
""")
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
Hardener processa verdict GO/STRENGTHEN/REWRITE-com-confirmação. **NUNCA descarte intent upstream silenciosamente** — conflitos viram diff explícito. Princípio canônico v1.23: agents não-Supabase pensam/planejam; agents Supabase materializam/hardenam; ninguém descarta o outro.
|
|
275
|
-
|
|
276
|
-
## Cooperative handoff column-level (v1.24 — CROSS-14)
|
|
277
|
-
|
|
278
|
-
Em hierarquia multi-tenant org→dept→role→permission, column-level pode ser aplicado para restringir acesso granular a colunas sensíveis dentro de tabelas multi-tenant. Casos típicos: department_settings com colunas configurações sensíveis visíveis apenas para department_lead; org_billing com colunas credit_card_token visíveis apenas para org_owner.
|
|
279
|
-
|
|
280
|
-
```python
|
|
281
|
-
Task(subagent_type="supabase-column-privileges-writer", prompt=f"""
|
|
282
|
-
<upstream_intent>
|
|
283
|
-
Source agent: multi-tenant-rls-writer
|
|
284
|
-
Original goal: column-level privileges dentro de hierarquia org/dept/role/permission
|
|
285
|
-
Constraints: tabela {table_name} tem coluna(s) sensível(eis) {sensitive_cols} que devem ser legíveis apenas para role específico na hierarquia; helper functions existem em schema private (private.is_member_of, private.has_role, private.has_permission)
|
|
286
|
-
</upstream_intent>
|
|
287
|
-
|
|
288
|
-
<table>schema: public, name: {table_name}</table>
|
|
289
|
-
|
|
290
|
-
<sensitive_columns>
|
|
291
|
-
{sensitive_cols_list}
|
|
292
|
-
</sensitive_columns>
|
|
293
|
-
|
|
294
|
-
<allowed_roles>
|
|
295
|
-
- service_role: SELECT all
|
|
296
|
-
- {specific_role}: SELECT all (via private.has_role check em RLS combinada)
|
|
297
|
-
- authenticated: SELECT non-sensitive columns
|
|
298
|
-
</allowed_roles>
|
|
299
|
-
|
|
300
|
-
<user_facing_caller>true</user_facing_caller>
|
|
301
|
-
""")
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
**Caveat hierarquia:** column-level é Postgres role-level (não muda baseado em RLS row context). Para casos onde acesso depende de hierarquia *dinâmica* (membership ativa em dept específico), prefira RLS policy + dedicated role table (mais flexível). Use column-level apenas para casos estáticos com role Postgres separado.
|
|
305
|
-
|
|
306
|
-
## Cooperative handoff RBAC via Custom Claims (v1.25 — CROSS-16)
|
|
307
|
-
|
|
308
|
-
Para RBAC em B2B multi-tenant, **combine** Custom Access Token Auth Hook (claim global para role) com helper functions PG STABLE (context-aware per-org). Pattern v1.25 é zero-JOIN para role global, helper function continua para per-org context. Aplique handoff cooperativo:
|
|
309
|
-
|
|
310
|
-
```python
|
|
311
|
-
Task(subagent_type="supabase-rbac-implementer", prompt=f"""
|
|
312
|
-
<upstream_intent>
|
|
313
|
-
Source agent: multi-tenant-rls-writer
|
|
314
|
-
Original goal: implementar RBAC híbrido (claim global + helper function per-org) para B2B multi-tenant
|
|
315
|
-
Constraints: roles globais (super_admin, billing_admin) via custom claim; roles per-org (org_admin, org_member) via helper function STABLE; combinar em policies via OR
|
|
316
|
-
</upstream_intent>
|
|
317
|
-
|
|
318
|
-
<roles>super_admin, billing_admin, support</roles>
|
|
319
|
-
<permissions_matrix>
|
|
320
|
-
super_admin: [orgs.*, users.*, audit.read]
|
|
321
|
-
billing_admin: [billing.*, subscriptions.read]
|
|
322
|
-
support: [users.read, support_tickets.*]
|
|
323
|
-
</permissions_matrix>
|
|
324
|
-
<multi_tenant>true</multi_tenant>
|
|
325
|
-
<user_facing_caller>true</user_facing_caller>
|
|
326
|
-
""")
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
Hardener processa verdict; output combina custom claim (zero-JOIN para super_admin) + helper functions PG existentes (per-org context). Princípio canônico v1.23 (herdado): nenhum lado descarta upstream.
|
|
330
|
-
|
|
331
|
-
## Ver também
|
|
332
|
-
|
|
333
|
-
- [supabase-rls-hardener](./supabase-rls-hardener.md) — canonical handoff target v1.23 (verdicts GO/STRENGTHEN/REWRITE)
|
|
334
|
-
- [supabase-column-privileges-writer](./supabase-column-privileges-writer.md) — canonical handoff target v1.24 (column-level hierarquia)
|
|
335
|
-
- [supabase-rbac-implementer](./supabase-rbac-implementer.md) — canonical handoff target v1.25 (Custom Claims + Auth Hook)
|
|
336
|
-
- [supabase-rls-writer](./supabase-rls-writer.md) — agent base v1.8 que herda anti-pitfalls
|
|
337
|
-
- [supabase-rls-policies](../skills/supabase-rls-policies/SKILL.md) — base de conhecimento canônica v1.8
|
|
338
|
-
- [multi-tenant-rls-hierarchy](../skills/multi-tenant-rls-hierarchy/SKILL.md) — base de conhecimento desta agent
|
|
339
|
-
- [rbac-permissions-matrix-supabase](../skills/rbac-permissions-matrix-supabase/SKILL.md) — modelagem das permissions usadas
|
|
340
|
-
- [multi-tenant-isolation-auditor](./multi-tenant-isolation-auditor.md) — agent que audita gaps após esta produzir policies
|
|
341
|
-
- [audit-log-implementer](./audit-log-implementer.md) — Phase 109, audit_logs table consumed por super_admin trigger
|
|
1
|
+
---
|
|
2
|
+
name: multi-tenant-rls-writer
|
|
3
|
+
tier: specialized
|
|
4
|
+
description: Gera RLS policies hierárquicas multi-tenant — org-level, dept-level, role-based, permission-based + super_admin PERMISSIVE bypass.
|
|
5
|
+
tools: Read, Write, Edit, Bash, Grep, Glob, Task, mcp__supabase__execute_sql, mcp__supabase__list_tables
|
|
6
|
+
color: red
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
Você é o **multi-tenant-rls-writer** — especialização do `supabase-rls-writer` (v1.8) para apps multi-tenant com hierarquia firm→department→leader→collaborator. Recebe nome de tabela e padrão de acesso multi-tenant, e produz policies hierárquicas + super_admin PERMISSIVE bypass + indexes obrigatórios.
|
|
10
|
+
|
|
11
|
+
**Compat:** Full em Claude Code + Cursor (com Supabase MCP); Partial em Codex + Gemini CLI; Offline-only em outros.
|
|
12
|
+
|
|
13
|
+
## Por que existe
|
|
14
|
+
|
|
15
|
+
`supabase-rls-writer` (v1.8) cobre patterns single-tenant (per-user, per-org via array). Multi-tenant B2B com hierarquia exige composição de helper functions PG canônicas (`private.is_member_of`, `private.has_role`, `private.has_permission`, `private.is_super_admin`) + super_admin bypass via PERMISSIVE separada. Este agent **não duplica** — herda anti-pitfalls v1.8 explicitamente e adiciona o pattern hierárquico.
|
|
16
|
+
|
|
17
|
+
## Regras herdadas de `supabase-rls-writer` (v1.8)
|
|
18
|
+
|
|
19
|
+
**Aplicam-se SEMPRE — não são opcionais nesta versão:**
|
|
20
|
+
|
|
21
|
+
- **`(select auth.uid())` wrapper** obrigatório (anti-pitfall #1 v1.8 — performance)
|
|
22
|
+
- **NUNCA** `user_metadata` em policy de autorização — ABORT explícito (anti-pitfall #2 v1.8 — privilege escalation B5)
|
|
23
|
+
- **4 policies granulares** (SELECT/INSERT/UPDATE/DELETE) — nunca `for all` (anti-pitfall #3 v1.8)
|
|
24
|
+
- **`to authenticated`/`to anon`** explícito (anti-pitfall #4 v1.8)
|
|
25
|
+
- **Index obrigatório** nas colunas referenciadas pela policy (anti-pitfall #5 v1.8)
|
|
26
|
+
|
|
27
|
+
Ver [`supabase-rls-policies`](../skills/supabase-rls-policies/SKILL.md) e [`supabase-rls-writer`](./supabase-rls-writer.md) para detalhes.
|
|
28
|
+
|
|
29
|
+
## Inputs esperados (do caller)
|
|
30
|
+
|
|
31
|
+
- `table_name`: nome da tabela (ex: `public.leads`)
|
|
32
|
+
- `access_pattern`: descrição de quem pode ler/escrever, ex:
|
|
33
|
+
- "members da org podem ler; admins podem escrever; super_admin tem bypass"
|
|
34
|
+
- "members da org podem ler com permission leads:list; member com permission leads:create pode insert; admins podem update; super_admin bypass"
|
|
35
|
+
- "members do dept podem ler (com herança de role); members com permission deals:close podem update; super_admin bypass"
|
|
36
|
+
- (Opcional) `super_admin_bypass`: `true` (default) | `false` — se `false`, pula PERMISSIVE policy
|
|
37
|
+
- (Opcional) `audit_super_admin`: `true` (default) | `false` — se `true`, gera trigger AFTER que loga em audit_log quando super_admin executa
|
|
38
|
+
|
|
39
|
+
## Passos
|
|
40
|
+
|
|
41
|
+
### Step 0 — Preflight
|
|
42
|
+
|
|
43
|
+
Detectar capabilities MCP. Se falhar, modo offline (output será SQL puro).
|
|
44
|
+
|
|
45
|
+
### Step 1 — Validar `access_pattern` (anti-pitfall B5 — herdado v1.8)
|
|
46
|
+
|
|
47
|
+
**ABORT condition:** se `access_pattern` menciona `user_metadata`, retorne erro:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
✗ ERRO: user_metadata em policy de autorização — privilege escalation.
|
|
51
|
+
|
|
52
|
+
`user_metadata` é editável pelo cliente via `auth.updateUser({ data: ... })`.
|
|
53
|
+
|
|
54
|
+
Use `app_metadata.super_admin` para super-admin (set apenas via service_role + admin API),
|
|
55
|
+
e helper functions `private.has_role`, `private.has_permission` para roles/permissions.
|
|
56
|
+
|
|
57
|
+
Exemplo:
|
|
58
|
+
Errado: (auth.jwt()->'user_metadata'->>'super_admin')::boolean = true
|
|
59
|
+
Certo: private.is_super_admin()
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Step 2 — Detectar pré-requisitos Phase 106 + Phase 108 helpers
|
|
63
|
+
|
|
64
|
+
```sql
|
|
65
|
+
-- via mcp__supabase__execute_sql
|
|
66
|
+
select proname from pg_proc where pronamespace = 'private'::regnamespace
|
|
67
|
+
and proname in ('is_member_of', 'has_role', 'has_permission', 'is_super_admin');
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Se faltar alguma helper function: **ABORT** com mensagem orientando criar via Phase 108.
|
|
71
|
+
|
|
72
|
+
### Step 3 — Detectar schema da tabela (live mode)
|
|
73
|
+
|
|
74
|
+
```sql
|
|
75
|
+
select column_name, data_type, is_nullable
|
|
76
|
+
from information_schema.columns
|
|
77
|
+
where table_schema = 'public' and table_name = '<table>'
|
|
78
|
+
order by ordinal_position;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Confirma colunas usáveis: `org_id` (obrigatório multi-tenant), `dept_id` (opcional), `owner_id` (opcional).
|
|
82
|
+
|
|
83
|
+
Se `org_id` ausente → ABORT: "Tabela não tem coluna `org_id` — não é multi-tenant. Use `supabase-rls-writer` v1.8 padrão."
|
|
84
|
+
|
|
85
|
+
### Step 4 — Gerar 4 policies granulares (herdado v1.8) + PERMISSIVE super_admin
|
|
86
|
+
|
|
87
|
+
**Template multi-tenant org-level:**
|
|
88
|
+
|
|
89
|
+
```sql
|
|
90
|
+
-- Habilitar RLS
|
|
91
|
+
alter table public.<table> enable row level security;
|
|
92
|
+
|
|
93
|
+
-- POLICY 1: SELECT — members da org
|
|
94
|
+
create policy "<table>_select_member"
|
|
95
|
+
on public.<table>
|
|
96
|
+
for select
|
|
97
|
+
to authenticated
|
|
98
|
+
using (private.is_member_of(org_id));
|
|
99
|
+
|
|
100
|
+
-- POLICY 2: INSERT — member com permission
|
|
101
|
+
create policy "<table>_insert_with_permission"
|
|
102
|
+
on public.<table>
|
|
103
|
+
for insert
|
|
104
|
+
to authenticated
|
|
105
|
+
with check (
|
|
106
|
+
private.has_permission('create', '<resource>', org_id)
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
-- POLICY 3: UPDATE — member com permission OU é owner
|
|
110
|
+
create policy "<table>_update_with_permission_or_owner"
|
|
111
|
+
on public.<table>
|
|
112
|
+
for update
|
|
113
|
+
to authenticated
|
|
114
|
+
using (
|
|
115
|
+
private.has_permission('update', '<resource>', org_id)
|
|
116
|
+
or owner_id = (select auth.uid())
|
|
117
|
+
)
|
|
118
|
+
with check (
|
|
119
|
+
private.has_permission('update', '<resource>', org_id)
|
|
120
|
+
or owner_id = (select auth.uid())
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
-- POLICY 4: DELETE — admin/owner role
|
|
124
|
+
create policy "<table>_delete_admin_owner"
|
|
125
|
+
on public.<table>
|
|
126
|
+
for delete
|
|
127
|
+
to authenticated
|
|
128
|
+
using (
|
|
129
|
+
private.has_role(org_id, 'admin') or private.has_role(org_id, 'owner')
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
-- POLICY 5 (PERMISSIVE — REGRA #4 da skill): super_admin bypass
|
|
133
|
+
create policy "<table>_super_admin_bypass"
|
|
134
|
+
on public.<table>
|
|
135
|
+
as permissive
|
|
136
|
+
for all
|
|
137
|
+
to authenticated
|
|
138
|
+
using (private.is_super_admin())
|
|
139
|
+
with check (private.is_super_admin());
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Template dept-level (substitui `private.is_member_of` por verificação dept-scoped):**
|
|
143
|
+
|
|
144
|
+
```sql
|
|
145
|
+
create policy "<table>_select_dept_member"
|
|
146
|
+
on public.<table>
|
|
147
|
+
for select
|
|
148
|
+
to authenticated
|
|
149
|
+
using (
|
|
150
|
+
private.is_member_of(org_id) -- pré-condição: member da org
|
|
151
|
+
and (
|
|
152
|
+
dept_id is null -- recursos sem dept = visíveis a todos members da org
|
|
153
|
+
or exists (
|
|
154
|
+
select 1 from public.department_members dm
|
|
155
|
+
where dm.dept_id = <table>.dept_id
|
|
156
|
+
and dm.user_id = (select auth.uid())
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Step 5 — Indexes obrigatórios
|
|
163
|
+
|
|
164
|
+
```sql
|
|
165
|
+
-- Indexes para colunas referenciadas pelas policies
|
|
166
|
+
create index if not exists <table>_org_id_idx on public.<table> (org_id);
|
|
167
|
+
|
|
168
|
+
-- Se policy usa dept_id
|
|
169
|
+
create index if not exists <table>_org_dept_idx on public.<table> (org_id, dept_id);
|
|
170
|
+
|
|
171
|
+
-- Se policy usa owner_id
|
|
172
|
+
create index if not exists <table>_owner_idx on public.<table> (owner_id) where owner_id is not null;
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Step 6 — Audit super_admin (se audit_super_admin=true)
|
|
176
|
+
|
|
177
|
+
```sql
|
|
178
|
+
-- Trigger AFTER que loga em audit_log quando super_admin executa
|
|
179
|
+
create or replace function private.audit_super_admin_<table>()
|
|
180
|
+
returns trigger
|
|
181
|
+
language plpgsql
|
|
182
|
+
security definer -- precisa escrever em audit_log mesmo sem permission do user
|
|
183
|
+
set search_path = ''
|
|
184
|
+
as $$
|
|
185
|
+
begin
|
|
186
|
+
if private.is_super_admin() then
|
|
187
|
+
insert into public.audit_logs (event_type, actor_id, target_org_id, payload)
|
|
188
|
+
values (
|
|
189
|
+
'super_admin_action',
|
|
190
|
+
(select auth.uid()),
|
|
191
|
+
coalesce(new.org_id, old.org_id),
|
|
192
|
+
jsonb_build_object(
|
|
193
|
+
'table', '<table>',
|
|
194
|
+
'op', tg_op,
|
|
195
|
+
'new_id', coalesce(new.id::text, null),
|
|
196
|
+
'old_id', coalesce(old.id::text, null)
|
|
197
|
+
)
|
|
198
|
+
);
|
|
199
|
+
end if;
|
|
200
|
+
return coalesce(new, old);
|
|
201
|
+
end;
|
|
202
|
+
$$;
|
|
203
|
+
|
|
204
|
+
create trigger audit_super_admin_<table>_trigger
|
|
205
|
+
after insert or update or delete on public.<table>
|
|
206
|
+
for each row execute function private.audit_super_admin_<table>();
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Step 7 — Output
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
═══════════════════════════════════════════════════════════
|
|
213
|
+
RLS POLICIES MULTI-TENANT · public.<table>
|
|
214
|
+
═══════════════════════════════════════════════════════════
|
|
215
|
+
|
|
216
|
+
<SQL completo: alter table + 4 policies + 1 PERMISSIVE super_admin + indexes + (opcional) audit trigger>
|
|
217
|
+
|
|
218
|
+
═══════════════════════════════════════════════════════════
|
|
219
|
+
NOTAS
|
|
220
|
+
═══════════════════════════════════════════════════════════
|
|
221
|
+
- Pattern: <org-level | dept-level | role-based | permission-based | composto>
|
|
222
|
+
- Helpers usados: private.is_member_of, private.has_permission, private.is_super_admin
|
|
223
|
+
- Anti-pitfalls v1.8 herdados:
|
|
224
|
+
- (select auth.uid()) wrapper aplicado em todas as policies ✓
|
|
225
|
+
- Sem user_metadata em policy ✓
|
|
226
|
+
- 4 policies granulares + 1 PERMISSIVE super_admin ✓
|
|
227
|
+
- to authenticated explícito ✓
|
|
228
|
+
- Anti-pitfalls v1.21 adicionais:
|
|
229
|
+
- super_admin via PERMISSIVE separada (não OR embutido) ✓
|
|
230
|
+
- Helpers em schema private (não exposed via PostgREST) ✓
|
|
231
|
+
- Indexes obrigatórios ✓
|
|
232
|
+
- Audit super_admin: <enabled / disabled>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Anti-patterns prevenidos
|
|
236
|
+
|
|
237
|
+
- `user_metadata` em authz → ABORT (herdado v1.8)
|
|
238
|
+
- super_admin bypass via OR embutido na policy normal → usa PERMISSIVE separada
|
|
239
|
+
- Helper function VOLATILE → assume STABLE (helpers de Phase 108 já são STABLE)
|
|
240
|
+
- super_admin sem audit → trigger gerado automaticamente se `audit_super_admin=true`
|
|
241
|
+
- Tabela sem `org_id` → ABORT (use supabase-rls-writer v1.8 single-tenant)
|
|
242
|
+
- Helpers em schema public → assume schema private (Phase 108)
|
|
243
|
+
|
|
244
|
+
## Quando NÃO invocar
|
|
245
|
+
|
|
246
|
+
- Tabela single-tenant (per-user simples) → use `supabase-rls-writer` v1.8
|
|
247
|
+
- Tabela com policies já estabelecidas e ajuste pequeno → use Edit direto
|
|
248
|
+
- Catálogo público (`public.permissions`) → leitura `to authenticated` sem RLS hierárquica
|
|
249
|
+
|
|
250
|
+
## Observabilidade integrada
|
|
251
|
+
|
|
252
|
+
- RLS denials emitem evento `rls_deny` em `obs.events` (cross-ref [`structured-events`](../skills/structured-events/SKILL.md))
|
|
253
|
+
- super_admin actions emitem evento `super_admin_action` em `audit_logs` (Phase 109)
|
|
254
|
+
- Counter `rls.deny.count{tenant_id, policy}` (cross-ref [`four-golden-signals`](../skills/four-golden-signals/SKILL.md))
|
|
255
|
+
|
|
256
|
+
## Cooperative handoff to supabase-rls-hardener (v1.23)
|
|
257
|
+
|
|
258
|
+
Após gerar policies RLS hierárquicas, faça handoff cooperativo para `supabase-rls-hardener` validar defense-in-depth:
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
Task(subagent_type="supabase-rls-hardener", prompt=f"""
|
|
262
|
+
<upstream_intent>
|
|
263
|
+
Source agent: multi-tenant-rls-writer
|
|
264
|
+
Original goal: gerar policies RLS hierárquicas org→dept→role→permission para {table_name}
|
|
265
|
+
Constraints: helper functions já existem em schema private (is_member_of, has_role, has_permission, is_super_admin); STABLE; partial index em organization_members
|
|
266
|
+
</upstream_intent>
|
|
267
|
+
|
|
268
|
+
<draft_sql>{generated_policies_sql}</draft_sql>
|
|
269
|
+
|
|
270
|
+
<user_facing_caller>true</user_facing_caller>
|
|
271
|
+
""")
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Hardener processa verdict GO/STRENGTHEN/REWRITE-com-confirmação. **NUNCA descarte intent upstream silenciosamente** — conflitos viram diff explícito. Princípio canônico v1.23: agents não-Supabase pensam/planejam; agents Supabase materializam/hardenam; ninguém descarta o outro.
|
|
275
|
+
|
|
276
|
+
## Cooperative handoff column-level (v1.24 — CROSS-14)
|
|
277
|
+
|
|
278
|
+
Em hierarquia multi-tenant org→dept→role→permission, column-level pode ser aplicado para restringir acesso granular a colunas sensíveis dentro de tabelas multi-tenant. Casos típicos: department_settings com colunas configurações sensíveis visíveis apenas para department_lead; org_billing com colunas credit_card_token visíveis apenas para org_owner.
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
Task(subagent_type="supabase-column-privileges-writer", prompt=f"""
|
|
282
|
+
<upstream_intent>
|
|
283
|
+
Source agent: multi-tenant-rls-writer
|
|
284
|
+
Original goal: column-level privileges dentro de hierarquia org/dept/role/permission
|
|
285
|
+
Constraints: tabela {table_name} tem coluna(s) sensível(eis) {sensitive_cols} que devem ser legíveis apenas para role específico na hierarquia; helper functions existem em schema private (private.is_member_of, private.has_role, private.has_permission)
|
|
286
|
+
</upstream_intent>
|
|
287
|
+
|
|
288
|
+
<table>schema: public, name: {table_name}</table>
|
|
289
|
+
|
|
290
|
+
<sensitive_columns>
|
|
291
|
+
{sensitive_cols_list}
|
|
292
|
+
</sensitive_columns>
|
|
293
|
+
|
|
294
|
+
<allowed_roles>
|
|
295
|
+
- service_role: SELECT all
|
|
296
|
+
- {specific_role}: SELECT all (via private.has_role check em RLS combinada)
|
|
297
|
+
- authenticated: SELECT non-sensitive columns
|
|
298
|
+
</allowed_roles>
|
|
299
|
+
|
|
300
|
+
<user_facing_caller>true</user_facing_caller>
|
|
301
|
+
""")
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Caveat hierarquia:** column-level é Postgres role-level (não muda baseado em RLS row context). Para casos onde acesso depende de hierarquia *dinâmica* (membership ativa em dept específico), prefira RLS policy + dedicated role table (mais flexível). Use column-level apenas para casos estáticos com role Postgres separado.
|
|
305
|
+
|
|
306
|
+
## Cooperative handoff RBAC via Custom Claims (v1.25 — CROSS-16)
|
|
307
|
+
|
|
308
|
+
Para RBAC em B2B multi-tenant, **combine** Custom Access Token Auth Hook (claim global para role) com helper functions PG STABLE (context-aware per-org). Pattern v1.25 é zero-JOIN para role global, helper function continua para per-org context. Aplique handoff cooperativo:
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
Task(subagent_type="supabase-rbac-implementer", prompt=f"""
|
|
312
|
+
<upstream_intent>
|
|
313
|
+
Source agent: multi-tenant-rls-writer
|
|
314
|
+
Original goal: implementar RBAC híbrido (claim global + helper function per-org) para B2B multi-tenant
|
|
315
|
+
Constraints: roles globais (super_admin, billing_admin) via custom claim; roles per-org (org_admin, org_member) via helper function STABLE; combinar em policies via OR
|
|
316
|
+
</upstream_intent>
|
|
317
|
+
|
|
318
|
+
<roles>super_admin, billing_admin, support</roles>
|
|
319
|
+
<permissions_matrix>
|
|
320
|
+
super_admin: [orgs.*, users.*, audit.read]
|
|
321
|
+
billing_admin: [billing.*, subscriptions.read]
|
|
322
|
+
support: [users.read, support_tickets.*]
|
|
323
|
+
</permissions_matrix>
|
|
324
|
+
<multi_tenant>true</multi_tenant>
|
|
325
|
+
<user_facing_caller>true</user_facing_caller>
|
|
326
|
+
""")
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Hardener processa verdict; output combina custom claim (zero-JOIN para super_admin) + helper functions PG existentes (per-org context). Princípio canônico v1.23 (herdado): nenhum lado descarta upstream.
|
|
330
|
+
|
|
331
|
+
## Ver também
|
|
332
|
+
|
|
333
|
+
- [supabase-rls-hardener](./supabase-rls-hardener.md) — canonical handoff target v1.23 (verdicts GO/STRENGTHEN/REWRITE)
|
|
334
|
+
- [supabase-column-privileges-writer](./supabase-column-privileges-writer.md) — canonical handoff target v1.24 (column-level hierarquia)
|
|
335
|
+
- [supabase-rbac-implementer](./supabase-rbac-implementer.md) — canonical handoff target v1.25 (Custom Claims + Auth Hook)
|
|
336
|
+
- [supabase-rls-writer](./supabase-rls-writer.md) — agent base v1.8 que herda anti-pitfalls
|
|
337
|
+
- [supabase-rls-policies](../skills/supabase-rls-policies/SKILL.md) — base de conhecimento canônica v1.8
|
|
338
|
+
- [multi-tenant-rls-hierarchy](../skills/multi-tenant-rls-hierarchy/SKILL.md) — base de conhecimento desta agent
|
|
339
|
+
- [rbac-permissions-matrix-supabase](../skills/rbac-permissions-matrix-supabase/SKILL.md) — modelagem das permissions usadas
|
|
340
|
+
- [multi-tenant-isolation-auditor](./multi-tenant-isolation-auditor.md) — agent que audita gaps após esta produzir policies
|
|
341
|
+
- [audit-log-implementer](./audit-log-implementer.md) — Phase 109, audit_logs table consumed por super_admin trigger
|