Skip to content

feat(sso): remove sso_enabled flag, always show SSO section#2013

Merged
Dalanir merged 6 commits into
mainfrom
remove-sso-flag
May 2, 2026
Merged

feat(sso): remove sso_enabled flag, always show SSO section#2013
Dalanir merged 6 commits into
mainfrom
remove-sso-flag

Conversation

@Dalanir
Copy link
Copy Markdown
Contributor

@Dalanir Dalanir commented May 1, 2026

Summary

  • Retire le flag sso_enabled (colonne Capgo-managed sur orgs) qui cachait entièrement la section SSO dans les paramètres organisation
  • La section SSO est désormais visible pour tous les membres super-admin : les orgs enterprise voient directement le formulaire SSO, les autres voient une incitation à upgrader
  • La migration supprime la colonne et met à jour toutes les fonctions DB concernées (check_domain_sso, get_sso_enforcement_by_domain, generate_org_on_user_create, get_orgs_v7)

Fichiers modifiés

  • Security.vue — retire && currentOrganization?.sso_enabled du v-if
  • providers.ts — retire la vérification sso_enabled (le gate requireEnterprisePlan suffit)
  • migrations/20260501120000_remove_sso_enabled_flag.sql — migration de suppression complète
  • src/types/supabase.types.ts + supabase/functions/_backend/utils/supabase.types.ts — types mis à jour
  • tests/sso.test.ts + tests/organization-put-stripe-sync.unit.test.ts — références retirées

Note

Après cette migration, tout org avec un provider SSO actif aura SSO actif — comportement attendu puisque le gate enterprise dans providers.ts garantit qu'on ne peut créer un provider que si on est enterprise.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor
    • SSO settings now appear for any org where you have settings permission; SSO availability is determined by active provider configuration instead of a legacy flag. Domain-based SSO detection and org-creation flows now rely on provider-driven logic.
  • Tests
    • Test fixtures and SSO-related tests updated to remove the deprecated SSO flag.

Dalanir and others added 2 commits May 1, 2026 22:14
SSO settings are now visible to all org members with super-admin
permissions. Enterprise orgs see the configuration form directly;
non-enterprise orgs see an upgrade prompt. The Capgo-managed
sso_enabled column is dropped from orgs and all related DB functions
are updated accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

This PR removes the sso_enabled boolean from the organizations schema and migrates SSO availability detection to active sso_providers rows. Types, DB functions/migration, backend SSO endpoints, UI rendering guard, and test fixtures are updated to reflect the removal.

Changes

SSO Enablement Detection Refactor

Layer / File(s) Summary
Data Shape / Types
src/types/supabase.types.ts, supabase/functions/_backend/utils/supabase.types.ts
Removed sso_enabled from orgs Row/Insert/Update and from both get_orgs_v7() return schemas.
Database Schema & Logic
supabase/migrations/20260501200000_remove_sso_enabled_flag.sql
Dropped public.orgs.sso_enabled; recreated check_domain_sso(p_domain) and get_sso_enforcement_by_domain(p_domain) to derive SSO from active sso_providers joined to orgs; updated generate_org_on_user_create() trigger to use active providers/domain for org creation gating; dropped and recreated both get_orgs_v7() overloads without sso_enabled in RETURNS.
Backend Implementation
supabase/functions/_backend/private/sso/providers.ts
Removed lookup of orgs.sso_enabled and removed related 404/403 guard checks; proceeds from permission/plan checks to create provider and insert sso_providers row; removed supabaseAdmin import usage.
UI Wiring
src/pages/settings/organization/Security.vue
SSO configuration panel now renders when user has org.update_settings permission (no longer requires currentOrganization?.sso_enabled); internal content remains plan-gated (Enterprise vs upgrade prompt).
Tests / Fixtures
tests/organization-put-stripe-sync.unit.test.ts, tests/sso.test.ts
Removed sso_enabled field from org fixtures/inserts across SSO-related tests and test helpers.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UI as Settings UI
  participant Backend as SSO Function
  participant DB as Postgres (sso_providers & orgs)
  participant Auth as Auth System

  User->>UI: open Organization Security settings
  UI->>Backend: request SSO config (requires org.update_settings)
  Backend->>Auth: validate permissions & plan
  Backend->>DB: query/insert into sso_providers (no orgs.sso_enabled check)
  DB-->>Backend: return provider / org info
  Backend-->>UI: return SSO config / upgrade prompt
  UI-->>User: render SSO configuration section
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A flag removed from rows I tend,
Now providers weave the SSO thread,
Domains whisper where logins bend,
No more booleans to be read,
Hop, patch, and sprint — integration fed.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description is incomplete. It lacks a Test plan section and Screenshots section that are specified in the template. Add a Test plan section describing how to verify the SSO section visibility and functionality. Include Screenshots section or note that it's not applicable for backend changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: removing the sso_enabled flag and making the SSO section always visible to authorized users.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch remove-sso-flag

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 SQLFluff (4.1.0)
supabase/migrations/20260501200000_remove_sso_enabled_flag.sql

User Error: No dialect was specified. You must configure a dialect or specify one on the command line using --dialect after the command. Available dialects:
ansi, athena, bigquery, clickhouse, databricks, db2, doris, duckdb, exasol, flink, greenplum, hive, impala, mariadb, materialize, mysql, oracle, postgres, redshift, snowflake, soql, sparksql, sqlite, starrocks, teradata, trino, tsql, vertica


Review rate limit: 3/5 reviews remaining, refill in 21 minutes and 58 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented May 1, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks


Comparing remove-sso-flag (d1467ae) with main (4f583d7)

Open in CodSpeed

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
supabase/migrations/20260501120000_remove_sso_enabled_flag.sql (1)

59-85: ⚡ Quick win

Set the recreated trigger owner explicitly.

generate_org_on_user_create() is recreated as SECURITY DEFINER, but unlike the callable functions above and below it, the migration never pins its owner. Add an explicit ALTER FUNCTION public.generate_org_on_user_create() OWNER TO postgres; after the definition so the definer role stays deterministic across environments.

Suggested fix
 CREATE OR REPLACE FUNCTION "public"."generate_org_on_user_create" () RETURNS "trigger" LANGUAGE "plpgsql"
 SET
   search_path = '' SECURITY DEFINER AS $$
 ...
     RETURN NEW;
 END $$;
+
+ALTER FUNCTION public.generate_org_on_user_create() OWNER TO postgres;

As per coding guidelines "Apply explicit REVOKE ALL and GRANT statements for function permissioning; start from deny-by-default and grant only required roles; set OWNER explicitly" and based on learnings "do not require REVOKE ALL ON FUNCTION ... FROM PUBLIC for PostgreSQL trigger functions."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@supabase/migrations/20260501120000_remove_sso_enabled_flag.sql` around lines
59 - 85, The migration recreates the SECURITY DEFINER trigger function
generate_org_on_user_create but does not set an explicit owner; add a statement
after the function definition that sets the function owner to postgres (e.g.,
run ALTER FUNCTION public.generate_org_on_user_create() OWNER TO postgres) so
the definer role is deterministic across environments and matches the pattern
used for other functions; ensure you place this ALTER immediately after the
CREATE OR REPLACE FUNCTION block and follow existing permissioning conventions
for other trigger functions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@supabase/migrations/20260501120000_remove_sso_enabled_flag.sql`:
- Around line 79-82: The INSERT into public.orgs is only guarded against sso:*
providers, so email-auth users on domains with active SSO (has_sso) will still
get a personal org; update the IF condition used around the INSERT (the check
that references user_provider, has_sso, and the INSERT INTO public.orgs that
sets org_record) so it also treats email logins as SSO-managed: change the
predicate to consider either sso providers or email (e.g., (user_provider ~
'^sso:' OR user_provider = 'email') AND has_sso) and keep the INSERT only when
that combined condition is false.

---

Nitpick comments:
In `@supabase/migrations/20260501120000_remove_sso_enabled_flag.sql`:
- Around line 59-85: The migration recreates the SECURITY DEFINER trigger
function generate_org_on_user_create but does not set an explicit owner; add a
statement after the function definition that sets the function owner to postgres
(e.g., run ALTER FUNCTION public.generate_org_on_user_create() OWNER TO
postgres) so the definer role is deterministic across environments and matches
the pattern used for other functions; ensure you place this ALTER immediately
after the CREATE OR REPLACE FUNCTION block and follow existing permissioning
conventions for other trigger functions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6013ddf5-40e9-4d3d-904f-a24b49c3f063

📥 Commits

Reviewing files that changed from the base of the PR and between 4f583d7 and 9c0ea88.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • src/pages/settings/organization/Security.vue
  • src/types/supabase.types.ts
  • supabase/functions/_backend/private/sso/providers.ts
  • supabase/functions/_backend/utils/supabase.types.ts
  • supabase/migrations/20260501120000_remove_sso_enabled_flag.sql
  • tests/organization-put-stripe-sync.unit.test.ts
  • tests/sso.test.ts
💤 Files with no reviewable changes (3)
  • tests/organization-put-stripe-sync.unit.test.ts
  • src/types/supabase.types.ts
  • supabase/functions/_backend/utils/supabase.types.ts

Comment thread supabase/migrations/20260501120000_remove_sso_enabled_flag.sql
Dalanir and others added 2 commits May 1, 2026 22:32
…tion

- Renamed 20260501120000 → 20260501200000 (must be > latest on main: 20260501162433)
- Added ALTER FUNCTION generate_org_on_user_create() OWNER TO postgres

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@supabase/migrations/20260501200000_remove_sso_enabled_flag.sql`:
- Around line 79-82: The IF guard is not NULL-safe because "user_provider ~
'^sso:'" yields NULL when user_provider IS NULL, causing the whole condition to
be NULL and skipping org creation; update the condition to explicitly handle
NULL (e.g., change the IF to use an explicit NULL check or COALESCE), for
example replace the current IF with: IF NOT ((user_provider IS NOT NULL AND
user_provider ~ '^sso:') AND has_sso) THEN ... so the regex test is only
evaluated when user_provider is non-NULL and has_sso is true before skipping the
INSERT into public.orgs (the INSERT INTO public.orgs ... RETURNING * INTO
org_record remains unchanged).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a6c1bd5-e6d4-46a1-8b93-b13d8ea03684

📥 Commits

Reviewing files that changed from the base of the PR and between 9c0ea88 and fb601c0.

📒 Files selected for processing (1)
  • supabase/migrations/20260501200000_remove_sso_enabled_flag.sql

Comment thread supabase/migrations/20260501200000_remove_sso_enabled_flag.sql
Dalanir and others added 2 commits May 2, 2026 15:12
Per CodeRabbit review: email signups on domains with an active SSO
provider are handled by provision-user.ts and should not receive an
auto-created personal org, same as genuine SAML SSO logins.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Dalanir
Copy link
Copy Markdown
Contributor Author

Dalanir commented May 2, 2026

Re: CodeRabbit inline comment on generate_org_on_user_create (email users on SSO domains)

Ce comportement est intentionnel et préservé volontairement.

La migration originale (20260317160518) documente explicitement la décision :

"Email, phone, and OAuth providers (e.g. google, github) always get a personal org, even when their email domain matches an active SSO provider."

La raison : un utilisateur qui s'inscrit avec email/password sur un domaine SSO (ex: @company.com) n'est pas nécessairement un utilisateur SSO géré par l'entreprise. Le laisser sans org serait une régression — il se retrouverait dans un état cassé. Seuls les logins SAML genuins (provider ~ '^sso:') sont identifiés par Supabase comme sessions SSO d'entreprise et traités par provision-user.ts.

Changer la condition pour inclure user_provider = 'email' modifierait un invariant délibéré du système et sortirait du scope de cette PR.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
supabase/migrations/20260501200000_remove_sso_enabled_flag.sql (1)

80-82: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make the SSO login guard NULL-safe before deciding org creation.

Line 80 still has a tri-valued boolean bug: if user_provider is NULL, user_provider ~ '^sso:' is NULL, so NOT (NULL AND has_sso) is NULL, and the IF body does not run. That can wrongly skip org creation.

Suggested fix
-    IF NOT (user_provider ~ '^sso:' AND has_sso) THEN
+    IF NOT ((COALESCE(user_provider, '') ~ '^sso:') AND has_sso) THEN
       INSERT INTO public.orgs (created_by, name, management_email) values (NEW.id, format('%s organization', NEW.first_name), NEW.email) RETURNING * INTO org_record;
     END IF;
In PostgreSQL PL/pgSQL, what does NOT (NULL AND TRUE) evaluate to, and does IF execute the THEN branch when the condition is NULL?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@supabase/migrations/20260501200000_remove_sso_enabled_flag.sql` around lines
80 - 82, The IF condition using "user_provider ~ '^sso:' AND has_sso" is not
NULL-safe so a NULL user_provider can produce NULL and prevent the THEN block
from running; update the guard to a boolean-safe form such as using COALESCE or
explicit IS TRUE checks — e.g., replace the condition in the IF that references
user_provider and has_sso with something like "NOT (COALESCE(user_provider, '')
~ '^sso:' AND has_sso)" or "NOT ((user_provider ~ '^sso:') IS TRUE AND has_sso
IS TRUE)" so org creation executes predictably when user_provider is NULL.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@supabase/migrations/20260501200000_remove_sso_enabled_flag.sql`:
- Around line 80-82: The IF condition using "user_provider ~ '^sso:' AND
has_sso" is not NULL-safe so a NULL user_provider can produce NULL and prevent
the THEN block from running; update the guard to a boolean-safe form such as
using COALESCE or explicit IS TRUE checks — e.g., replace the condition in the
IF that references user_provider and has_sso with something like "NOT
(COALESCE(user_provider, '') ~ '^sso:' AND has_sso)" or "NOT ((user_provider ~
'^sso:') IS TRUE AND has_sso IS TRUE)" so org creation executes predictably when
user_provider is NULL.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5495423d-5447-46d4-8648-29a67798b8be

📥 Commits

Reviewing files that changed from the base of the PR and between c41b125 and d1467ae.

📒 Files selected for processing (1)
  • supabase/migrations/20260501200000_remove_sso_enabled_flag.sql

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 2, 2026

@Dalanir Dalanir merged commit c0b92be into main May 2, 2026
50 checks passed
@Dalanir Dalanir deleted the remove-sso-flag branch May 2, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant