Skip to content

Sso 01 schema#1597

Closed
jokabuyasina wants to merge 32 commits into
Cap-go:mainfrom
jokabuyasina:sso-01-schema
Closed

Sso 01 schema#1597
jokabuyasina wants to merge 32 commits into
Cap-go:mainfrom
jokabuyasina:sso-01-schema

Conversation

@jokabuyasina
Copy link
Copy Markdown

@jokabuyasina jokabuyasina commented Feb 7, 2026

Consolidated SSO SAML schema migration.

Schema includes:

Tables: org_saml_connections, saml_domain_mappings, sso_audit_logs
Functions: check_org_sso_configured, lookup_sso_provider_, auto_join_
Triggers: auto_join_sso_user_trigger, check_sso_domain_on_signup_trigger
RLS policies for all tables
Indexes for performance
Single SSO per org constraint (UNIQUE org_id, entity_id)
auto_join_enabled flag for controlling enrollment
This is PR #1 of the SSO feature split (schema foundation only). No backend endpoints, no frontend, no tests included yet.

Related: feature/sso-saml-authentication

Summary by CodeRabbit

  • New Features

    • Added SSO/SAML single sign-on support with configuration management
    • Implemented auto-enrollment of SSO users across organizations
    • Added domain-based SSO provider mapping
  • Improvements

    • Organizations now filtered based on 2FA enforcement status
    • Sensitive organization data redacted for users non-compliant with password policies
    • Enhanced SSO audit logging for security tracking

jonthan kabuya and others added 30 commits January 7, 2026 17:29
Consolidates 12 incremental SSO migrations (20251224022658 through 20260106000000) into a single comprehensive migration.

Schema includes:
- Tables: org_saml_connections, saml_domain_mappings, sso_audit_logs
- Functions: check_org_sso_configured, lookup_sso_provider_*, auto_join_*
- Triggers: auto_join_sso_user_trigger, check_sso_domain_on_signup_trigger
- RLS policies for all tables
- Indexes for performance
- Single SSO per org constraint (UNIQUE org_id, entity_id)
- auto_join_enabled flag for controlling enrollment

This is PR #1 of the SSO feature split (schema foundation only).
No backend endpoints, no frontend, no tests included yet.

Related: feature/sso-saml-authentication
- Add auth.uid() validation to auto_enroll_sso_user and auto_join_user_to_orgs_by_email
- Add email verification against auth.users to prevent user spoofing
- Add auto_join_enabled check to domain-mapping loop (join org_saml_connections)
- Remove overly permissive audit log INSERT policy (SECURITY DEFINER functions bypass RLS)
Join org_saml_connections via sso_connection_id foreign key instead of org_id
to check auto_join_enabled on the specific SSO connection referenced by the
domain mapping, not just any connection for the org.
…ants

- Remove auth.identities check from BEFORE INSERT trigger (identities don't
  exist yet at that point, created AFTER user insert)
- Rely exclusively on metadata-based SSO validation (sso_provider_id in
  raw_user_meta_data)
- Remove EXECUTE grants to authenticated role for trigger functions
  (trigger_auto_join_on_user_create, trigger_auto_join_on_user_update)
- These should only be callable by postgres/supabase_auth_admin in trigger
  context, not by regular authenticated users
- Remove unused v_provider_count variable
- Add cleanup_old_sso_audit_logs() function to delete logs >90 days
- Anonymize email addresses for deleted users (user_id IS NULL)
- Register daily cron task at 3 AM UTC for automated cleanup
- Addresses GDPR/CCPA data retention requirements
- Email anonymization format: deleted-user-{uuid}@anonymized.local
…scan pages

- Move getDaysInCurrentMonth call from prop default to computed property to avoid initialization issues
- Add @ts-expect-error for packages without TypeScript definitions (qrcode, @capacitor/barcode-scanner)
- Remove unused MeteredData import from stripe_event.ts
…_tasks

- Remove INSERT into cron_tasks table per Capgo convention
- Add SSO audit cleanup logic directly to process_all_cron_tasks() function
- Runs daily at 3:00 AM UTC (hour == 3, minute < 5)
- PERFORM cleanup_old_sso_audit_logs() with error handling
- Follows existing cron pattern for time-based conditional execution
- Add SECURITY DEFINER to validate_sso_configuration() function
- Set search_path = public, pg_temp for safe function execution
- Grant INSERT on sso_audit_logs to postgres role for trigger function
- Ensures audit log INSERTs succeed despite RLS during org_saml_connections INSERT/UPDATE
- Follows same pattern as auto_enroll_sso_user and auto_join_user_to_orgs_by_email
- Split auto_enroll_sso_user into internal and public versions
  - internal_auto_enroll_sso_user: No auth checks, for triggers
  - public.auto_enroll_sso_user: Validates auth.uid() and email
- Update auto_join_user_to_orgs_by_email to use internal version
- Allow service_role to bypass auth checks for trigger operations
- Fix UsageCard.vue computed properties to use dataArray.value instead of props.data
- Add proper undefined guards to lastDayEvolution and hasData
…mputed

- Add org_saml_connections, saml_domain_mappings, sso_audit_logs to postgres_schema.ts
- Fix duplicate and incomplete computed properties in UsageCard.vue
- Fix dataArray.value references in UsageCard
- All TypeScript errors resolved
- Whitelist allowed functions: cleanup_old_sso_audit_logs, cleanup_queue_messages, cleanup_old_audit_logs, process_stats_queue, send_stats_email
- Prevents arbitrary function execution via cron_tasks table
- Raises warning for unauthorized functions
- Remove unused useDashboardAppsStore import
- Remove unused hasData computed property
- Fix blank line before closing script tag
- Update sumValues to properly handle (number | undefined)[] with explicit return type
- Add type narrowing for calculateDemoEvolution call
- Add hasChartData computed property for template usage
- Add back @ts-expect-error directives for packages without TypeScript definitions
- Type totalSum explicitly in reduce callback
- Remove incorrect migration that embedded logic in process_all_cron_tasks()
- Update SSO audit cleanup to use cron_tasks table INSERT pattern
- Fix TypeScript errors in RBAC files by using namespace import for postgres_schema
- Revert unrelated UsageCard data prop default change
Fixes test failures in get_orgs_v7 2FA and password policy enforcement tests.
The RBAC migration changed behavior to show denied orgs with redacted data,
but tests expect orgs to be completely hidden when access is denied.

This restores the original behavior where orgs are filtered out entirely
when the user doesn't meet 2FA or password policy requirements.
- Fix hasRealData in UsageCard to treat all defined non-null values (including zero) as real data
- Add composite unique constraint (org_id, entity_id) to org_saml_connections table
- Fix auto_join_user_to_orgs_by_email to allow trigger context by checking auth.uid() IS NOT NULL

These changes ensure:
1. Zero values in usage charts are treated as real data, not demo data
2. Each organization can only have one SSO connection per entity_id
3. Auto-enrollment works correctly when triggered during user creation (auth.uid() is NULL in trigger context)
…ord policy

The previous fix incorrectly filtered out orgs for both 2FA and password policy
violations. The correct behavior is:

- 2FA enforcement: Hide org completely (no row returned)
- Password policy enforcement: Show org with redacted sensitive data

This ensures password policy tests pass while maintaining 2FA security.
…ation

- UsageCard: Add Array.isArray guard for appValues in hasRealData
- UsageCard: Fix total computed to check for actual numbers
- postgres_schema: Change attribute_mapping and metadata from text to jsonb
- postgres_schema: Update unique constraints for org_saml_connections
- postgres_schema: Add composite unique to saml_domain_mappings
- SSO migration: Add osc.enabled check for domain-based auto-join
- SSO migration: Allow service_role/trigger context in auto_enroll_sso_user
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 7, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This PR introduces comprehensive SSO/SAML authentication infrastructure with new database tables, helper functions, and auto-enrollment triggers for domain-based organization joining. Additionally, it refactors Vue component data handling to remove store dependencies and updates the get_orgs_v7 function to enforce 2FA and password policies with selective data redaction.

Changes

Cohort / File(s) Summary
Frontend Data Handling
src/components/dashboard/UsageCard.vue
Refactored component to eliminate external store dependency for demo-mode detection. Introduced internal computed properties (isDemoMode, effectiveData, effectiveDataByApp) that determine data selection based on real data presence and loading state. Updated numeric aggregation with explicit type guards and adjusted hasChartData logic to include zero values.
Backend Import Refactoring
supabase/functions/_backend/private/groups.ts, role_bindings.ts, roles.ts
Changed schema module imports from named imports to namespace imports (e.g., import * as schema) across three backend private route files. No runtime behavior changes; all downstream usage remains valid.
Database Schema Definitions
supabase/functions/_backend/utils/postgres_schema.ts
Added three new pgTable definitions: org_saml_connections (with org_id/entity_id unique constraints), saml_domain_mappings (with domain/sso_connection_id unique constraint), and sso_audit_logs. Introduced unique constraint import from drizzle-orm. Removed aggregate schema export object.
SSO/SAML Infrastructure
supabase/migrations/20260107210800_sso_saml_complete.sql
Comprehensive migration establishing SSO/SAML foundation: creates three new tables (org_saml_connections, saml_domain_mappings, sso_audit_logs) with indexes and constraints. Implements lookup and validation helper functions. Adds auto-enrollment logic via internal/public functions and triggers on auth.users table to auto-join users based on provider or domain. Includes RLS policies and permission grants for authenticated and service roles.
SSO Audit Cleanup Scheduling
supabase/migrations/20260108052411_add_sso_audit_cleanup_cron.sql
Schedules daily cron task at 3:00 AM UTC to execute cleanup_old_sso_audit_logs function, removing logs older than 90 days and anonymizing PII for deleted users.
Organization Access Control
supabase/migrations/20260123203333_fix_get_orgs_v7_hide_denied_orgs.sql
Rewrites get_orgs_v7 function with expanded return table (adding enforcing_2fa, 2fa_has_access, password policy fields, etc.). Implements logic to completely hide orgs where 2FA is enforced and user lacks access; redacts sensitive fields for orgs with non-compliant password policies while retaining the org in results.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Auth as Auth Service
    participant DB as PostgreSQL
    participant Trigger as Trigger Function
    participant Enroll as Auto-Enroll Logic

    User->>Auth: Sign up / Update profile
    Auth->>DB: INSERT/UPDATE auth.users
    DB->>Trigger: Invoke trigger_auto_join_on_user_create()
    activate Trigger
    Trigger->>DB: Query lookup_sso_provider_for_email()
    alt Provider found
        Trigger->>Enroll: Call auto_join_user_to_orgs_by_email()
        activate Enroll
        Enroll->>DB: Query saml_domain_mappings by domain
        alt Domain mapping exists
            Enroll->>DB: Retrieve org by priority
            Enroll->>DB: INSERT into org_users (auto-join)
            Enroll->>DB: INSERT into sso_audit_logs (event: auto_joined)
        end
        Enroll->>DB: Return enrollment results
        deactivate Enroll
    end
    deactivate Trigger
    DB->>Auth: Complete user signup
    Auth->>User: Authentication successful (auto-joined to org)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

🐰 Hop-hop, SSO's here!
Domains mapped with flair,
Auto-join we cheer,
2FA security fair,
Data flows crystal clear!

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.0.0)
supabase/migrations/20260108052411_add_sso_audit_cleanup_cron.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

supabase/migrations/20260123203333_fix_get_orgs_v7_hide_denied_orgs.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

supabase/migrations/20260107210800_sso_saml_complete.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


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Feb 7, 2026

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