@luanpdd/kit-mcp 1.30.2 → 1.32.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 -82
- package/kit/COMANDOS.md +138 -138
- package/kit/COMPATIBILITY.md +5 -0
- package/kit/README.md +76 -76
- package/kit/agents/advisor-researcher.md +107 -106
- package/kit/agents/ai-mutation-tester.md +1 -0
- package/kit/agents/assumptions-analyzer.md +108 -107
- package/kit/agents/audit-log-implementer.md +314 -313
- package/kit/agents/auditor-consistencia-isolamento.md +414 -413
- package/kit/agents/b2b-saas-architect.md +157 -156
- package/kit/agents/burn-rate-forecaster.md +1 -0
- package/kit/agents/cascading-failures-auditor.md +299 -298
- package/kit/agents/codebase-mapper.md +769 -768
- package/kit/agents/crm-pipeline-implementer.md +257 -256
- package/kit/agents/debugger.md +814 -813
- package/kit/agents/detector-tenant-quente.md +338 -337
- package/kit/agents/evolution-go-integrator.md +201 -200
- package/kit/agents/example-reviewer.md +22 -21
- package/kit/agents/executor.md +565 -564
- package/kit/agents/golden-signals-instrumenter.md +1 -0
- package/kit/agents/incident-investigator.md +1 -0
- package/kit/agents/integration-checker.md +201 -200
- package/kit/agents/invite-flow-implementer.md +190 -189
- package/kit/agents/legacy-characterizer.md +369 -368
- package/kit/agents/lgpd-compliance-auditor.md +296 -295
- package/kit/agents/load-shedding-instrumenter.md +1 -0
- package/kit/agents/multi-tenant-isolation-auditor.md +254 -253
- package/kit/agents/multi-tenant-rls-writer.md +341 -340
- package/kit/agents/nyquist-auditor.md +179 -178
- package/kit/agents/observability-coverage-auditor.md +316 -315
- package/kit/agents/observability-instrumenter.md +1 -0
- package/kit/agents/omm-auditor.md +1 -0
- package/kit/agents/org-onboarding-implementer.md +224 -223
- package/kit/agents/payload-capture-instrumenter.md +274 -273
- package/kit/agents/phase-researcher.md +697 -696
- package/kit/agents/plan-checker.md +273 -272
- package/kit/agents/planner.md +923 -922
- package/kit/agents/postmortem-writer.md +1 -0
- package/kit/agents/project-researcher.md +653 -652
- package/kit/agents/prr-conductor.md +1 -0
- package/kit/agents/refactor-safety-auditor.md +405 -404
- package/kit/agents/release-pipeline-auditor.md +1 -0
- package/kit/agents/research-synthesizer.md +246 -245
- package/kit/agents/roadmapper.md +678 -677
- package/kit/agents/schema-checker.md +1 -0
- package/kit/agents/seam-finder.md +360 -359
- package/kit/agents/shotgun-surgery-detector.md +350 -349
- package/kit/agents/slo-engineer.md +1 -0
- package/kit/agents/storytelling-analyst.md +1 -0
- package/kit/agents/supabase-architect.md +1 -0
- package/kit/agents/supabase-auth-bootstrapper.md +16 -1
- package/kit/agents/supabase-auth-hook-writer.md +418 -0
- package/kit/agents/supabase-branching-architect.md +563 -562
- package/kit/agents/supabase-cicd-pipeline-implementer.md +778 -777
- package/kit/agents/supabase-column-privileges-writer.md +400 -399
- package/kit/agents/supabase-edge-fn-tester.md +2 -1
- package/kit/agents/supabase-edge-fn-writer.md +2 -1
- package/kit/agents/supabase-mfa-implementer.md +439 -0
- package/kit/agents/supabase-migration-writer.md +386 -385
- package/kit/agents/supabase-oauth-server-implementer.md +507 -0
- package/kit/agents/supabase-rbac-implementer.md +393 -392
- package/kit/agents/supabase-realtime-implementer.md +364 -363
- package/kit/agents/supabase-rls-hardener.md +522 -521
- package/kit/agents/supabase-rls-writer.md +324 -323
- package/kit/agents/supabase-roles-implementer.md +356 -355
- package/kit/agents/supabase-social-auth-implementer.md +451 -0
- package/kit/agents/supabase-sso-saml-architect.md +549 -0
- package/kit/agents/supabase-storage-implementer.md +1 -0
- package/kit/agents/super-admin-implementer.md +282 -281
- package/kit/agents/toil-auditor.md +1 -0
- package/kit/agents/ui-auditor.md +438 -437
- package/kit/agents/ui-checker.md +303 -302
- package/kit/agents/ui-researcher.md +356 -355
- package/kit/agents/user-profiler.md +176 -175
- package/kit/agents/validador-evolucao-schema.md +336 -335
- package/kit/agents/verifier.md +729 -728
- 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.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 +21 -1
- 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 +100 -84
- 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 +29 -50
- package/kit/hooks/kit-router.cjs +137 -0
- 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 -0
- package/kit/skills/supabase-auth-hooks/SKILL.md +875 -0
- package/kit/skills/supabase-auth-methods/SKILL.md +486 -0
- package/kit/skills/supabase-auth-sessions/SKILL.md +579 -0
- package/kit/skills/supabase-auth-ssr/SKILL.md +60 -14
- 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 +1 -1
- package/kit/skills/supabase-edge-functions-auth/SKILL.md +1 -1
- package/kit/skills/supabase-edge-functions-limits/SKILL.md +1 -1
- package/kit/skills/supabase-edge-functions-mcp-server/SKILL.md +1 -1
- package/kit/skills/supabase-edge-functions-testing/SKILL.md +1 -1
- package/kit/skills/supabase-edge-runtime-builtins/SKILL.md +1 -1
- package/kit/skills/supabase-enterprise-sso-saml/SKILL.md +545 -0
- package/kit/skills/supabase-jwt-signing-keys/SKILL.md +399 -0
- package/kit/skills/supabase-mfa/SKILL.md +488 -0
- 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 -0
- 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 -0
- package/kit/skills/supabase-third-party-auth/SKILL.md +450 -0
- package/kit/skills/super-admin-platform-pattern/SKILL.md +326 -326
- package/kit/skills/tenant-quente-mitigacao/SKILL.md +605 -605
- package/kit/skills/whatsapp-conversation-state-machine/SKILL.md +287 -287
- package/package.json +1 -1
- package/src/core/kit.js +216 -216
- package/src/core/reflect.js +247 -247
- package/src/core/reverse-sync.js +372 -372
- package/src/core/sync.js +437 -418
- package/src/core/watch.js +121 -121
- package/src/mcp-server/index.js +794 -746
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-edge-functions
|
|
3
|
-
description: Use ao escrever Edge Functions Supabase — Deno
|
|
3
|
+
description: Use ao escrever Edge Functions Supabase — Deno, imports versionados npm:/jsr:/node:, env vars JSON dict 2026, per-function deno.json + config.toml, file writes /tmp ou /s3, EdgeRuntime.waitUntil.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Supabase — Edge Functions (Deno) · 2026
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-edge-functions-auth
|
|
3
|
-
description: Use ao autenticar Edge Functions Supabase
|
|
3
|
+
description: Use ao autenticar Edge Functions Supabase 2026 — package @supabase/server, withSupabase({auth}), createSupabaseContext, Authorization JWT vs apikey, toggle verify_jwt por função no config.toml.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Supabase — Edge Functions Auth (`@supabase/server`) · 2026
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-edge-functions-limits
|
|
3
|
-
description: Use ao planejar limites
|
|
3
|
+
description: Use ao planejar limites e retries em Edge Functions Supabase — runtime caps 256MB/2s CPU/wall clock, status codes canônicos, RateLimitError + retryAfterMs, error classes client-side, idempotency.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Supabase — Edge Functions Limits, Status Codes & Rate Limits · 2026
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-edge-functions-mcp-server
|
|
3
|
-
description: Use ao construir MCP server
|
|
3
|
+
description: Use ao construir MCP server em Supabase Edge Functions com mcp-lite — scaffold npm create mcp-lite, dois apps Hono, deno.json, verify_jwt=false + auth no nível MCP, deploy para Claude/Cursor.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Supabase — Edge Functions como MCP Server (`mcp-lite`) · 2026
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-edge-functions-testing
|
|
3
|
-
description: Use ao testar/debugar Edge Functions Supabase localmente —
|
|
3
|
+
description: Use ao testar/debugar Edge Functions Supabase localmente — deno test --allow-all, folder tests/<fn>-test.ts, supabase functions serve, Chrome DevTools --inspect-mode, characterization para legadas.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Supabase — Edge Functions Testing & Local Debug · 2026
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: supabase-edge-runtime-builtins
|
|
3
|
-
description: Use ao usar built-ins do Edge Runtime Supabase —
|
|
3
|
+
description: Use ao usar built-ins do Edge Runtime Supabase — Supabase.ai.Session (embeddings/LLM), file system S3FS /s3 + /tmp, regional via x-region, WebSockets Deno.upgradeWebSocket, Wasm via static_files.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Supabase — Edge Runtime Built-ins · 2026
|
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supabase-enterprise-sso-saml
|
|
3
|
+
description: Use ao configurar Enterprise SSO via SAML 2.0 no Supabase — Okta, Azure AD, Google Workspace, signInWithSSO, attribute mapping e RLS multi-tenant.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Supabase — Enterprise SSO (SAML 2.0)
|
|
7
|
+
|
|
8
|
+
## Quando usar
|
|
9
|
+
|
|
10
|
+
LLM carrega esta skill quando configurar **Single Sign-On empresarial via SAML 2.0** no Supabase, integrando com provedores de identidade (IdP) como Okta, Azure AD/Entra ID, Google Workspace ou PingIdentity.
|
|
11
|
+
|
|
12
|
+
Trigger phrases:
|
|
13
|
+
|
|
14
|
+
- "SAML SSO Supabase", "signInWithSSO"
|
|
15
|
+
- "enterprise single sign-on", "Okta Supabase"
|
|
16
|
+
- "Azure AD SAML", "Entra ID Supabase"
|
|
17
|
+
- "attribute mapping SAML", "multi-tenant SSO"
|
|
18
|
+
- "identity provider Supabase", "SP-initiated flow"
|
|
19
|
+
- "supabase sso add", "sso_provider_id RLS"
|
|
20
|
+
|
|
21
|
+
## Princípio canônico
|
|
22
|
+
|
|
23
|
+
SSO via SAML 2.0 permite que empresas clientes (tenants) façam login com suas credenciais corporativas existentes, sem criar senhas no Supabase. O Supabase atua como **Service Provider (SP)** e o sistema da empresa (Okta, Azure AD, etc.) é o **Identity Provider (IdP)**.
|
|
24
|
+
|
|
25
|
+
**Disponibilidade:** SAML SSO exige plano **Pro ou superior** do Supabase.
|
|
26
|
+
|
|
27
|
+
**Providers SAML suportados (testados):**
|
|
28
|
+
|
|
29
|
+
| Provider | Observação |
|
|
30
|
+
|----------|------------|
|
|
31
|
+
| Okta | Provider mais comum em B2B enterprise |
|
|
32
|
+
| Azure AD / Entra ID | Microsoft identity — integração via app enterprise |
|
|
33
|
+
| Google Workspace | Apenas org-level SSO (não contas pessoais Google) |
|
|
34
|
+
| PingIdentity | Usado em grandes enterprises financeiras |
|
|
35
|
+
| OneLogin | Alternativa frequente em médias empresas |
|
|
36
|
+
| Auth0 (como IdP) | Quando o tenant usa Auth0 para SSO interno |
|
|
37
|
+
|
|
38
|
+
**Quando usar SSO SAML:**
|
|
39
|
+
|
|
40
|
+
- ✅ B2B SaaS com clientes enterprise que exigem login corporativo
|
|
41
|
+
- ✅ Compliance que exige autenticação via IdP central da empresa
|
|
42
|
+
- ✅ Migração de usuários — empresa já tem Okta/Azure com todos os colaboradores
|
|
43
|
+
- ✅ Multi-tenant onde cada tenant tem seu próprio IdP
|
|
44
|
+
|
|
45
|
+
**Quando NÃO usar SSO SAML:**
|
|
46
|
+
|
|
47
|
+
- ❌ Aplicação B2C (usuários comuns) — use OAuth social ou magic link
|
|
48
|
+
- ❌ Plano Free do Supabase — SAML exige Pro+
|
|
49
|
+
- ❌ Poucos usuários que podem usar email/senha — overhead de configuração não compensa
|
|
50
|
+
|
|
51
|
+
## Terminologia SAML
|
|
52
|
+
|
|
53
|
+
| Termo | Significado |
|
|
54
|
+
|-------|-------------|
|
|
55
|
+
| **Identity Provider (IdP)** | Sistema que autentica o usuário (Okta, Azure AD) |
|
|
56
|
+
| **Service Provider (SP)** | Seu aplicativo (Supabase) — confia no IdP |
|
|
57
|
+
| **EntityID** | Identificador único do SP/IdP (geralmente uma URL) |
|
|
58
|
+
| **NameID** | Identificador do usuário no SAML assertion (email ou UUID) |
|
|
59
|
+
| **Assertion** | Documento XML assinado que o IdP envia ao SP após autenticação |
|
|
60
|
+
| **Metadata** | XML descrevendo endpoints, certificados e configurações do SP/IdP |
|
|
61
|
+
| **Certificate** | Certificado X.509 para assinar/verificar assertions |
|
|
62
|
+
| **ACS URL** | Assertion Consumer Service — endpoint do SP que recebe o assertion |
|
|
63
|
+
| **Binding** | Método de transporte (HTTP-POST ou HTTP-Redirect) |
|
|
64
|
+
| **RelayState** | Parâmetro opaco passado pelo SP ao IdP para manter estado (ex: URL de destino) |
|
|
65
|
+
|
|
66
|
+
## URLs SAML do Projeto Supabase
|
|
67
|
+
|
|
68
|
+
O Supabase expõe endpoints SAML padrão para cada projeto:
|
|
69
|
+
|
|
70
|
+
| Endpoint | URL |
|
|
71
|
+
|----------|-----|
|
|
72
|
+
| **Metadata (EntityID)** | `https://<project-ref>.supabase.co/auth/v1/sso/saml/metadata` |
|
|
73
|
+
| **ACS URL** | `https://<project-ref>.supabase.co/auth/v1/sso/saml/acs` |
|
|
74
|
+
|
|
75
|
+
**NameID:** configurar no IdP para enviar `emailAddress` (formato `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`) ou `persistent` (UUID opaco). Prefira `persistent` em ambientes onde o email pode mudar.
|
|
76
|
+
|
|
77
|
+
**Configurar no IdP (exemplo Okta):**
|
|
78
|
+
|
|
79
|
+
1. No Okta Admin Console → Applications → Create App Integration → SAML 2.0
|
|
80
|
+
2. **Single Sign-On URL:** `https://<project-ref>.supabase.co/auth/v1/sso/saml/acs`
|
|
81
|
+
3. **Audience URI (SP Entity ID):** `https://<project-ref>.supabase.co/auth/v1/sso/saml/metadata`
|
|
82
|
+
4. **Name ID format:** `EmailAddress`
|
|
83
|
+
5. Adicionar attribute mappings (ver seção abaixo)
|
|
84
|
+
6. Baixar metadata XML do Okta para usar no `supabase sso add`
|
|
85
|
+
|
|
86
|
+
## Gerenciar Conexões SSO via Supabase CLI
|
|
87
|
+
|
|
88
|
+
**Requisito:** Supabase CLI v1.46.4 ou superior.
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# verificar versão
|
|
92
|
+
supabase --version # deve ser >= 1.46.4
|
|
93
|
+
|
|
94
|
+
# adicionar conexão SSO via metadata URL (Okta/Azure expõem URL de metadata)
|
|
95
|
+
supabase sso add \
|
|
96
|
+
--project-ref <project-ref> \
|
|
97
|
+
--type saml \
|
|
98
|
+
--metadata-url https://okta.example.com/app/xxx/sso/saml/metadata \
|
|
99
|
+
--domains empresa.com,empresa.com.br
|
|
100
|
+
|
|
101
|
+
# adicionar via arquivo XML (quando o IdP não expõe URL pública de metadata)
|
|
102
|
+
supabase sso add \
|
|
103
|
+
--project-ref <project-ref> \
|
|
104
|
+
--type saml \
|
|
105
|
+
--metadata-file ./idp-metadata.xml \
|
|
106
|
+
--domains empresa.com
|
|
107
|
+
|
|
108
|
+
# adicionar com attribute mapping customizado
|
|
109
|
+
supabase sso add \
|
|
110
|
+
--project-ref <project-ref> \
|
|
111
|
+
--type saml \
|
|
112
|
+
--metadata-url https://okta.example.com/.../metadata \
|
|
113
|
+
--domains empresa.com \
|
|
114
|
+
--attribute-mapping-file ./attribute-mapping.json
|
|
115
|
+
|
|
116
|
+
# listar todas as conexões SSO do projeto
|
|
117
|
+
supabase sso list --project-ref <project-ref>
|
|
118
|
+
|
|
119
|
+
# ver detalhes de uma conexão (inclui provider_id)
|
|
120
|
+
supabase sso show --project-ref <project-ref> --sso-provider-id <uuid>
|
|
121
|
+
|
|
122
|
+
# atualizar domains ou metadata de uma conexão
|
|
123
|
+
supabase sso update \
|
|
124
|
+
--project-ref <project-ref> \
|
|
125
|
+
--sso-provider-id <uuid> \
|
|
126
|
+
--domains empresa.com,novodominio.com
|
|
127
|
+
|
|
128
|
+
# remover conexão SSO
|
|
129
|
+
supabase sso remove \
|
|
130
|
+
--project-ref <project-ref> \
|
|
131
|
+
--sso-provider-id <uuid>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Fluxo SP-Initiated (padrão)
|
|
135
|
+
|
|
136
|
+
O fluxo padrão é iniciado pelo SP (seu app) quando o usuário tenta acessar:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { createClient } from '@supabase/supabase-js'
|
|
140
|
+
|
|
141
|
+
const supabase = createClient(
|
|
142
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
143
|
+
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
// SP-initiated: identificar pelo domínio do email do usuário
|
|
147
|
+
const iniciarSSO = async (email: string) => {
|
|
148
|
+
const dominio = email.split('@')[1]
|
|
149
|
+
|
|
150
|
+
const { data, error } = await supabase.auth.signInWithSSO({
|
|
151
|
+
domain: dominio,
|
|
152
|
+
options: {
|
|
153
|
+
redirectTo: `${window.location.origin}/auth/callback`,
|
|
154
|
+
},
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
if (error) {
|
|
158
|
+
console.error('Erro ao iniciar SSO:', error.message)
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (data?.url) {
|
|
163
|
+
// redirecionar para o IdP
|
|
164
|
+
window.location.href = data.url
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Alternativa: identificar pelo sso_provider_id (para multi-tenant com seleção explícita)
|
|
169
|
+
const iniciarSSOPorProvider = async (ssoProviderId: string) => {
|
|
170
|
+
const { data, error } = await supabase.auth.signInWithSSO({
|
|
171
|
+
providerId: ssoProviderId,
|
|
172
|
+
options: {
|
|
173
|
+
redirectTo: `${window.location.origin}/auth/callback`,
|
|
174
|
+
},
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
if (data?.url) window.location.href = data.url
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Callback — trocar code por sessão:**
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
// app/auth/callback/route.ts (Next.js Route Handler)
|
|
185
|
+
import { createServerClient } from '@supabase/ssr'
|
|
186
|
+
import { cookies } from 'next/headers'
|
|
187
|
+
import { NextRequest, NextResponse } from 'next/server'
|
|
188
|
+
|
|
189
|
+
export async function GET(request: NextRequest) {
|
|
190
|
+
const { searchParams } = new URL(request.url)
|
|
191
|
+
const code = searchParams.get('code')
|
|
192
|
+
|
|
193
|
+
if (code) {
|
|
194
|
+
const cookieStore = await cookies()
|
|
195
|
+
const supabase = createServerClient(
|
|
196
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
197
|
+
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
|
|
198
|
+
{
|
|
199
|
+
cookies: {
|
|
200
|
+
getAll: () => cookieStore.getAll(),
|
|
201
|
+
setAll: (cookiesToSet) => {
|
|
202
|
+
cookiesToSet.forEach(({ name, value, options }) =>
|
|
203
|
+
cookieStore.set(name, value, options)
|
|
204
|
+
)
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
}
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
const { error } = await supabase.auth.exchangeCodeForSession(code)
|
|
211
|
+
if (!error) {
|
|
212
|
+
return NextResponse.redirect(new URL('/dashboard', request.url))
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return NextResponse.redirect(new URL('/auth/error', request.url))
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Attribute Mappings
|
|
221
|
+
|
|
222
|
+
Attribute mappings definem como atributos SAML do IdP são mapeados para campos do usuário Supabase. Os dados mapeados ficam em `auth.identities.identity_data` e `auth.users.raw_user_meta_data`.
|
|
223
|
+
|
|
224
|
+
**Formato do arquivo JSON de mapping:**
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"keys": {
|
|
229
|
+
"email": {
|
|
230
|
+
"name": "mail",
|
|
231
|
+
"names": ["email", "mail", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]
|
|
232
|
+
},
|
|
233
|
+
"email_verified": {
|
|
234
|
+
"default": true
|
|
235
|
+
},
|
|
236
|
+
"first_name": {
|
|
237
|
+
"name": "givenName",
|
|
238
|
+
"names": ["firstName", "givenName", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"]
|
|
239
|
+
},
|
|
240
|
+
"last_name": {
|
|
241
|
+
"name": "sn",
|
|
242
|
+
"names": ["lastName", "sn", "surname", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"]
|
|
243
|
+
},
|
|
244
|
+
"department": {
|
|
245
|
+
"name": "department",
|
|
246
|
+
"array": false
|
|
247
|
+
},
|
|
248
|
+
"groups": {
|
|
249
|
+
"name": "groups",
|
|
250
|
+
"array": true
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Campos do mapping:**
|
|
257
|
+
|
|
258
|
+
| Campo | Tipo | Descrição |
|
|
259
|
+
|-------|------|-----------|
|
|
260
|
+
| `name` | string | Nome principal do atributo SAML |
|
|
261
|
+
| `names` | string[] | Aliases (Supabase tenta cada um até encontrar) |
|
|
262
|
+
| `array` | boolean | Se o atributo é multi-valor (ex: grupos) |
|
|
263
|
+
| `default` | any | Valor padrão se o atributo não vier no assertion |
|
|
264
|
+
|
|
265
|
+
**Acessar dados mapeados:**
|
|
266
|
+
|
|
267
|
+
```sql
|
|
268
|
+
-- em RLS policy ou função
|
|
269
|
+
select raw_user_meta_data->>'department' from auth.users where id = auth.uid();
|
|
270
|
+
select raw_user_meta_data->'groups' from auth.users where id = auth.uid();
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
// no cliente
|
|
275
|
+
const { data: { user } } = await supabase.auth.getUser()
|
|
276
|
+
const department = user?.user_metadata?.department
|
|
277
|
+
const groups = user?.user_metadata?.groups // array se configurado como array: true
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Contas SSO — Diferenças Importantes
|
|
281
|
+
|
|
282
|
+
Contas criadas via SSO têm comportamento diferente de contas email/senha:
|
|
283
|
+
|
|
284
|
+
| Aspecto | Conta Email/Senha | Conta SSO |
|
|
285
|
+
|---------|-------------------|-----------|
|
|
286
|
+
| Auto-linking | Supabase pode vincular por email | **Sem auto-linking** — sempre cria nova identidade |
|
|
287
|
+
| Unicidade de email | Emails são únicos por padrão | **Emails NÃO são únicos** — dois IdPs podem ter mesmo email |
|
|
288
|
+
| Identificador seguro | Email | **UUID (`auth.uid()`)** |
|
|
289
|
+
| Sessão máxima | Configurável via JWT TTL | Pode ter duração máxima definida pelo IdP |
|
|
290
|
+
| Senha | Usuário tem senha | **Sem senha** — autenticação apenas via IdP |
|
|
291
|
+
|
|
292
|
+
**Crítico:** nunca usar email como identificador primário em sistemas com SSO. Dois tenants (empresas) diferentes podem ter colaboradores com mesmo email se houver overlap de domínio — situação rara mas válida (ex: empresa A e empresa B ambas têm `joao@empresa.com` em seus diretórios).
|
|
293
|
+
|
|
294
|
+
## RLS para Multi-tenant SSO
|
|
295
|
+
|
|
296
|
+
O `sso_provider_id` no JWT identifica de qual conexão SSO o usuário veio — use como chave de isolamento de tenant:
|
|
297
|
+
|
|
298
|
+
```sql
|
|
299
|
+
-- extrair sso_provider_id do JWT
|
|
300
|
+
-- retorna o UUID do IdP (conexão SSO configurada) ou null se não for SSO
|
|
301
|
+
select auth.jwt()#>>'{amr,0,provider}' as sso_provider_id;
|
|
302
|
+
|
|
303
|
+
-- tabela de configurações por tenant SSO
|
|
304
|
+
create table public.organization_settings (
|
|
305
|
+
id uuid default gen_random_uuid() primary key,
|
|
306
|
+
sso_provider_id uuid not null unique, -- UUID do provider SSO
|
|
307
|
+
organization_name text not null,
|
|
308
|
+
plan text not null default 'pro',
|
|
309
|
+
max_users int not null default 100,
|
|
310
|
+
created_at timestamptz default now()
|
|
311
|
+
);
|
|
312
|
+
comment on table public.organization_settings
|
|
313
|
+
is 'Configurações por tenant SSO — isolamento via sso_provider_id.';
|
|
314
|
+
|
|
315
|
+
-- habilitar RLS
|
|
316
|
+
alter table public.organization_settings enable row level security;
|
|
317
|
+
|
|
318
|
+
-- política RESTRICTIVE — escopo de tenant SSO
|
|
319
|
+
create policy "Tenant SSO só vê sua própria organização" on public.organization_settings
|
|
320
|
+
as restrictive
|
|
321
|
+
for select
|
|
322
|
+
to authenticated
|
|
323
|
+
using (
|
|
324
|
+
sso_provider_id = (auth.jwt()#>>'{amr,0,provider}')::uuid
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
-- política permissiva para leitura
|
|
328
|
+
create policy "Usuários autenticados podem ler config da org" on public.organization_settings
|
|
329
|
+
as permissive
|
|
330
|
+
for select
|
|
331
|
+
to authenticated
|
|
332
|
+
using (true);
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**Tabela de recursos com escopo de tenant:**
|
|
336
|
+
|
|
337
|
+
```sql
|
|
338
|
+
create table public.projetos (
|
|
339
|
+
id uuid default gen_random_uuid() primary key,
|
|
340
|
+
sso_provider_id uuid not null, -- tenant owner
|
|
341
|
+
nome text not null,
|
|
342
|
+
dados jsonb,
|
|
343
|
+
criado_em timestamptz default now()
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
alter table public.projetos enable row level security;
|
|
347
|
+
|
|
348
|
+
-- escopo rígido por tenant SSO
|
|
349
|
+
create policy "Usuário vê apenas projetos do seu tenant" on public.projetos
|
|
350
|
+
as restrictive
|
|
351
|
+
for all
|
|
352
|
+
to authenticated
|
|
353
|
+
using (
|
|
354
|
+
sso_provider_id = (auth.jwt()#>>'{amr,0,provider}')::uuid
|
|
355
|
+
);
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Helper function para uso em múltiplas policies:**
|
|
359
|
+
|
|
360
|
+
```sql
|
|
361
|
+
create or replace function public.sso_provider_id() returns uuid
|
|
362
|
+
language sql stable security definer set search_path = ''
|
|
363
|
+
as $$
|
|
364
|
+
select (auth.jwt()#>>'{amr,0,provider}')::uuid
|
|
365
|
+
$$;
|
|
366
|
+
|
|
367
|
+
-- uso simplificado em policies
|
|
368
|
+
create policy "Tenant isolado" on public.projetos
|
|
369
|
+
as restrictive for all to authenticated
|
|
370
|
+
using ((select public.sso_provider_id()) = sso_provider_id);
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## IdP-Initiated Flow — Caveat PKCE
|
|
374
|
+
|
|
375
|
+
**IdP-initiated flow** é quando o usuário clica em um ícone no portal do IdP (ex: Okta App Dashboard) para acessar o app — sem que o SP inicie o fluxo.
|
|
376
|
+
|
|
377
|
+
**Problema:** IdP-initiated é **incompatível com PKCE** porque não há `state` do SP para validar o `code_verifier`.
|
|
378
|
+
|
|
379
|
+
**Solução — Padrão "Bookmark App":**
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
// 1. Criar um endpoint que inicia o SP-initiated flow
|
|
383
|
+
// app/auth/sso-bookmark/route.ts
|
|
384
|
+
import { NextRequest, NextResponse } from 'next/server'
|
|
385
|
+
import { createServerClient } from '@supabase/ssr'
|
|
386
|
+
import { cookies } from 'next/headers'
|
|
387
|
+
|
|
388
|
+
export async function GET(request: NextRequest) {
|
|
389
|
+
const { searchParams } = new URL(request.url)
|
|
390
|
+
const providerId = searchParams.get('provider_id')
|
|
391
|
+
const tenant = searchParams.get('tenant') // para multi-tenant
|
|
392
|
+
|
|
393
|
+
if (!providerId && !tenant) {
|
|
394
|
+
return NextResponse.redirect(new URL('/auth/error', request.url))
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const cookieStore = await cookies()
|
|
398
|
+
const supabase = createServerClient(
|
|
399
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
400
|
+
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
|
|
401
|
+
{ cookies: { getAll: () => cookieStore.getAll(), setAll: () => {} } }
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
// iniciar SP-initiated (não IdP-initiated)
|
|
405
|
+
const { data, error } = await supabase.auth.signInWithSSO({
|
|
406
|
+
...(providerId ? { providerId } : { domain: `${tenant}.empresa.com` }),
|
|
407
|
+
options: {
|
|
408
|
+
redirectTo: `${process.env.NEXT_PUBLIC_SITE_URL}/auth/callback`,
|
|
409
|
+
},
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
if (data?.url) return NextResponse.redirect(data.url)
|
|
413
|
+
return NextResponse.redirect(new URL('/auth/error', request.url))
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// 2. No Okta/Azure: configurar o ícone do app para apontar para:
|
|
417
|
+
// https://seu-app.com/auth/sso-bookmark?provider_id=<uuid-do-provider>
|
|
418
|
+
// (não para o ACS URL diretamente)
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Multi-Subdomínio com SSO
|
|
422
|
+
|
|
423
|
+
Para apps com subdomínio por tenant (`empresa1.app.com`, `empresa2.app.com`):
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
// detectar tenant pelo subdomínio e redirecionar com callback correto
|
|
427
|
+
const iniciarSSOMultiSubdomain = async (email: string) => {
|
|
428
|
+
const dominio = email.split('@')[1]
|
|
429
|
+
const subdominio = window.location.hostname.split('.')[0] // ex: 'empresa1'
|
|
430
|
+
|
|
431
|
+
const { data, error } = await supabase.auth.signInWithSSO({
|
|
432
|
+
domain: dominio,
|
|
433
|
+
options: {
|
|
434
|
+
// callback no subdomínio correto
|
|
435
|
+
redirectTo: `https://${subdominio}.app.com/auth/callback`,
|
|
436
|
+
},
|
|
437
|
+
})
|
|
438
|
+
|
|
439
|
+
if (data?.url) window.location.href = data.url
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## Regras absolutas
|
|
444
|
+
|
|
445
|
+
1. **SSO exige Supabase CLI v1.46.4+** — versões anteriores não têm o subcomando `sso`.
|
|
446
|
+
2. **Usar UUID (`auth.uid()`), NUNCA email, como identificador de usuário** — emails não são únicos em ambientes multi-IdP SSO.
|
|
447
|
+
3. **IdP-initiated é incompatível com PKCE** — implementar padrão "bookmark app" (endpoint que inicia SP-initiated).
|
|
448
|
+
4. **RLS RESTRICTIVE para escopo de tenant** — isolamento via `sso_provider_id` deve ser política RESTRICTIVE.
|
|
449
|
+
5. **Sem auto-linking SSO** — nunca assumir que dois registros com mesmo email são o mesmo usuário.
|
|
450
|
+
6. **Usar `@supabase/ssr`, nunca `auth-helpers-nextjs`** — pacote legado descontinuado.
|
|
451
|
+
7. **Validar JWT no servidor com `getClaims()`** — nunca confiar apenas no cliente para verificar identidade SSO.
|
|
452
|
+
|
|
453
|
+
## Anti-patterns
|
|
454
|
+
|
|
455
|
+
### Anti-pattern 1: Usar email como chave de usuário SSO
|
|
456
|
+
|
|
457
|
+
**Errado:**
|
|
458
|
+
```sql
|
|
459
|
+
-- assumindo que email é único entre tenants SSO
|
|
460
|
+
create table public.perfis (
|
|
461
|
+
email text primary key, -- ERRADO para SSO
|
|
462
|
+
dados jsonb
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
create policy "Usuário vê próprio perfil" on public.perfis
|
|
466
|
+
as permissive for select to authenticated
|
|
467
|
+
using (email = (auth.jwt()->>'email')); -- ERRADO
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
**Por quê:** se dois IdPs diferentes tiverem um usuário com `joao@empresa.com`, haverá conflito. UUID é o único identificador garantidamente único.
|
|
471
|
+
|
|
472
|
+
**Certo:**
|
|
473
|
+
```sql
|
|
474
|
+
create table public.perfis (
|
|
475
|
+
user_id uuid primary key references auth.users(id) on delete cascade,
|
|
476
|
+
dados jsonb
|
|
477
|
+
);
|
|
478
|
+
|
|
479
|
+
create policy "Usuário vê próprio perfil" on public.perfis
|
|
480
|
+
as permissive for select to authenticated
|
|
481
|
+
using (user_id = auth.uid()); -- UUID sempre único
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Anti-pattern 2: Assumir auto-linking de contas por email
|
|
485
|
+
|
|
486
|
+
**Errado:**
|
|
487
|
+
```ts
|
|
488
|
+
// assumindo que se o email já existe, é o mesmo usuário
|
|
489
|
+
const { data: { user } } = await supabase.auth.getUser()
|
|
490
|
+
const perfil = await supabase.from('perfis')
|
|
491
|
+
.select()
|
|
492
|
+
.eq('email', user.email)
|
|
493
|
+
.single()
|
|
494
|
+
// ERRADO: pode retornar perfil de outro usuário SSO com mesmo email
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**Por quê:** Supabase **não faz auto-linking** por email em SSO. Cada `signInWithSSO` cria uma identidade nova em `auth.identities`, mesmo que o email já exista.
|
|
498
|
+
|
|
499
|
+
**Certo:** usar `auth.uid()` como chave de join, nunca email.
|
|
500
|
+
|
|
501
|
+
### Anti-pattern 3: Esperar IdP-initiated funcionar com PKCE
|
|
502
|
+
|
|
503
|
+
**Errado:**
|
|
504
|
+
```
|
|
505
|
+
// configurando no Okta:
|
|
506
|
+
// Ícone do app → aponta para ACS URL diretamente
|
|
507
|
+
// ACS URL: https://proj.supabase.co/auth/v1/sso/saml/acs
|
|
508
|
+
// Resultado: erro PKCE validation failed
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**Por quê:** quando o IdP inicia, não há `code_verifier` do SP. O PKCE (Proof Key for Code Exchange) exige que o SP inicie o fluxo.
|
|
512
|
+
|
|
513
|
+
**Certo:** configurar o ícone do app no IdP para apontar ao "bookmark app" (endpoint SP-initiated), não ao ACS URL.
|
|
514
|
+
|
|
515
|
+
### Anti-pattern 4: Conexão SSO sem validar domínios
|
|
516
|
+
|
|
517
|
+
**Errado:**
|
|
518
|
+
```bash
|
|
519
|
+
# adicionar SSO sem especificar domains
|
|
520
|
+
supabase sso add \
|
|
521
|
+
--project-ref abc123 \
|
|
522
|
+
--type saml \
|
|
523
|
+
--metadata-url https://idp.exemplo.com/metadata
|
|
524
|
+
# sem --domains → qualquer um pode tentar signInWithSSO com qualquer domínio
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**Por quê:** sem restrição de domínio, `signInWithSSO({ domain: 'qualquer.com' })` pode ser abusado para descoberta de providers.
|
|
528
|
+
|
|
529
|
+
**Certo:** sempre especificar `--domains` com os domínios exatos de email do tenant:
|
|
530
|
+
```bash
|
|
531
|
+
supabase sso add \
|
|
532
|
+
--project-ref abc123 \
|
|
533
|
+
--type saml \
|
|
534
|
+
--metadata-url https://idp.exemplo.com/metadata \
|
|
535
|
+
--domains empresa.com.br,empresa.com
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
## Ver também
|
|
539
|
+
|
|
540
|
+
- [supabase-auth-methods](../supabase-auth-methods/SKILL.md) — outros providers de autenticação (OAuth, magic link, email)
|
|
541
|
+
- [multi-tenant-rls-hierarchy](../multi-tenant-rls-hierarchy/SKILL.md) — RLS hierárquica para multi-tenant complexo
|
|
542
|
+
- [supabase-auth-ssr](../supabase-auth-ssr/SKILL.md) — padrão `@supabase/ssr` com Next.js e cookies
|
|
543
|
+
- [supabase-custom-claims-rbac](../supabase-custom-claims-rbac/SKILL.md) — RBAC via custom claims combinado com SSO
|
|
544
|
+
- [supabase-mfa](../supabase-mfa/SKILL.md) — MFA adicional para usuários SSO (TOTP sobre aal2)
|
|
545
|
+
- [supabase-sso-saml-architect](../../agents/supabase-sso-saml-architect.md) — agente que configura SSO SAML end-to-end
|