From fbd2dc115d47e6e77c387bea4aa22b13af492215 Mon Sep 17 00:00:00 2001 From: Bryan Frimin Date: Wed, 29 Oct 2025 20:15:06 +0100 Subject: [PATCH] Style Signed-off-by: Bryan Frimin --- pkg/coredata/migrations/20251018T194142Z.sql | 68 +++----------------- 1 file changed, 10 insertions(+), 58 deletions(-) diff --git a/pkg/coredata/migrations/20251018T194142Z.sql b/pkg/coredata/migrations/20251018T194142Z.sql index 5515065da..97828ca3c 100644 --- a/pkg/coredata/migrations/20251018T194142Z.sql +++ b/pkg/coredata/migrations/20251018T194142Z.sql @@ -1,54 +1,29 @@ --- Add SAML authentication support --- This migration adds SAML SSO functionality including: --- - SAML configurations per organization --- - SAML request/assertion tracking for security --- - Domain verification --- - User SAML subject tracking - --- Create ENUM for SAML enforcement policies CREATE TYPE saml_enforcement_policy AS ENUM ( - 'OFF', -- SAML disabled, must use password - 'OPTIONAL', -- SAML available but not required (default) - 'REQUIRED' -- Everyone must use SAML + 'OFF', + 'OPTIONAL', + 'REQUIRED' ); --- Create auth_saml_configurations table CREATE TABLE auth_saml_configurations ( id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, organization_id TEXT NOT NULL, email_domain TEXT NOT NULL, - - -- SAML enabled flag enabled BOOLEAN NOT NULL DEFAULT false, - - -- Enforcement policy for this SAML configuration enforcement_policy saml_enforcement_policy NOT NULL, - - -- Identity Provider (IdP) configuration idp_entity_id TEXT NOT NULL, idp_sso_url TEXT NOT NULL, - idp_certificate TEXT NOT NULL, -- X.509 certificate (PEM format) - idp_metadata_url TEXT, -- Optional: for auto-refresh - - -- Attribute mapping configuration (using WS-Federation Claims) + idp_certificate TEXT NOT NULL, + idp_metadata_url TEXT, attribute_email TEXT NOT NULL DEFAULT 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress', attribute_firstname TEXT NOT NULL DEFAULT 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname', attribute_lastname TEXT NOT NULL DEFAULT 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname', attribute_role TEXT NOT NULL DEFAULT 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role', - - -- Default role if mapping fails or attribute missing default_role TEXT NOT NULL DEFAULT 'MEMBER', - - -- Auto-signup settings auto_signup_enabled BOOLEAN NOT NULL DEFAULT false, - - -- Domain verification fields domain_verified BOOLEAN NOT NULL DEFAULT false, domain_verification_token TEXT, domain_verified_at TIMESTAMP, - - -- Timestamps created_at TIMESTAMP NOT NULL, updated_at TIMESTAMP NOT NULL, @@ -56,63 +31,47 @@ CREATE TABLE auth_saml_configurations ( REFERENCES organizations(id) ON DELETE CASCADE ); --- Index for fast organization lookup CREATE INDEX idx_auth_saml_configurations_organization_id ON auth_saml_configurations(organization_id); --- Index for tenant scoping CREATE INDEX idx_auth_saml_configurations_tenant_id ON auth_saml_configurations(tenant_id); --- Unique constraint scoped to organization --- This allows the same domain in different organizations --- while preventing duplicates within the same organization CREATE UNIQUE INDEX idx_saml_config_domain_org_unique ON auth_saml_configurations(organization_id, email_domain) WHERE enabled = true AND domain_verified = true; --- Index for fast domain lookup (for email-based SAML discovery) CREATE INDEX idx_saml_config_email_domain ON auth_saml_configurations(email_domain) WHERE enabled = true AND domain_verified = true; --- Add SAML subject to users table for tracking SAML NameID ALTER TABLE users ADD COLUMN saml_subject TEXT; --- Unique constraint: one SAML subject globally CREATE UNIQUE INDEX idx_users_saml_subject ON users(saml_subject) WHERE saml_subject IS NOT NULL; --- Make hashed_password nullable for SAML users --- SAML users authenticate via IdP and don't have passwords ALTER TABLE users ALTER COLUMN hashed_password DROP NOT NULL; --- Create auth_saml_assertions table for replay attack prevention CREATE TABLE auth_saml_assertions ( - id TEXT PRIMARY KEY, -- SAML Assertion ID + id TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, organization_id TEXT NOT NULL, used_at TIMESTAMP NOT NULL, expires_at TIMESTAMP NOT NULL ); --- Index for cleanup of expired assertions CREATE INDEX idx_auth_saml_assertions_expires_at ON auth_saml_assertions(expires_at); --- Index for organization lookup CREATE INDEX idx_auth_saml_assertions_organization_id ON auth_saml_assertions(organization_id); --- Index for tenant scoping CREATE INDEX idx_auth_saml_assertions_tenant_id ON auth_saml_assertions(tenant_id); --- Create auth_saml_requests table for proper InResponseTo validation --- This prevents replay attacks and validates the SAML authentication flow CREATE TABLE auth_saml_requests ( - id TEXT PRIMARY KEY, -- SAML Request ID generated by SP + id TEXT PRIMARY KEY, organization_id TEXT NOT NULL, tenant_id TEXT NOT NULL, created_at TIMESTAMP NOT NULL, @@ -122,20 +81,16 @@ CREATE TABLE auth_saml_requests ( REFERENCES organizations(id) ON DELETE CASCADE ); --- Index for fast request ID lookup during SAML callback CREATE INDEX idx_auth_saml_requests_id_org ON auth_saml_requests(id, organization_id); --- Index for cleanup of expired requests CREATE INDEX idx_auth_saml_requests_expires_at ON auth_saml_requests(expires_at); --- Create auth_saml_relay_states table for secure RelayState management --- This prevents organization hijacking attacks CREATE TABLE auth_saml_relay_states ( - token TEXT PRIMARY KEY, -- Cryptographically secure random token + token TEXT PRIMARY KEY, tenant_id TEXT NOT NULL, organization_id TEXT NOT NULL, - request_id TEXT NOT NULL, -- Links to auth_saml_requests.id - saml_config_id TEXT NOT NULL, -- Links to auth_saml_configurations.id + request_id TEXT NOT NULL, + saml_config_id TEXT NOT NULL, created_at TIMESTAMP NOT NULL, expires_at TIMESTAMP NOT NULL, @@ -147,11 +102,8 @@ CREATE TABLE auth_saml_relay_states ( REFERENCES auth_saml_requests(id) ON DELETE CASCADE ); --- Index for fast token lookup during callback CREATE INDEX idx_auth_saml_relay_states_token ON auth_saml_relay_states(token); --- Index for cleanup of expired relay states CREATE INDEX idx_auth_saml_relay_states_expires_at ON auth_saml_relay_states(expires_at); --- Index for tenant scoping CREATE INDEX idx_auth_saml_relay_states_tenant_id ON auth_saml_relay_states(tenant_id);