支持 Manifest V2 动态 tid 验证、Tenant Context 同步和租户内 JIT 投影,并保留 Manifest V1 与旧 Session 兼容。\n\n增加 tenantHint、租户切换、普通注册关闭及 application/principal/tenant 两级 SSF 撤销;迁移、定向安全测试和本地双租户跨仓 E2E 已通过。\n\nrelease_required=true;未执行 Release、Staging 或真实链路。
93 lines
4.2 KiB
SQL
93 lines
4.2 KiB
SQL
ALTER TABLE gateway_identity_configuration_revisions
|
|
DROP CONSTRAINT IF EXISTS gateway_identity_configuration_revisions_schema_version_check;
|
|
|
|
ALTER TABLE gateway_identity_configuration_revisions
|
|
ADD COLUMN IF NOT EXISTS tenant_mode text NOT NULL DEFAULT 'single_tenant',
|
|
ADD COLUMN IF NOT EXISTS tenant_context_endpoint text,
|
|
ADD COLUMN IF NOT EXISTS tenant_context_audience text,
|
|
ADD COLUMN IF NOT EXISTS tenant_context_scope text,
|
|
ADD CONSTRAINT gateway_identity_configuration_revisions_schema_version_check
|
|
CHECK (schema_version IN (1,2)),
|
|
ADD CONSTRAINT gateway_identity_configuration_revisions_tenant_mode_check
|
|
CHECK (tenant_mode IN ('single_tenant','multi_tenant')),
|
|
ADD CONSTRAINT gateway_identity_configuration_revisions_manifest_mode_check
|
|
CHECK (
|
|
(state='draft' AND issuer IS NULL)
|
|
OR
|
|
(schema_version=1 AND tenant_mode='single_tenant' AND tenant_id IS NOT NULL AND local_tenant_key <> ''
|
|
AND tenant_context_endpoint IS NULL AND tenant_context_audience IS NULL AND tenant_context_scope IS NULL)
|
|
OR
|
|
(schema_version=2 AND tenant_mode='multi_tenant' AND tenant_id IS NULL AND local_tenant_key=''
|
|
AND tenant_context_endpoint IS NOT NULL AND tenant_context_audience='urn:easyai:auth-center:tenant-context'
|
|
AND tenant_context_scope='tenant.context.read')
|
|
) NOT VALID;
|
|
|
|
CREATE TABLE IF NOT EXISTS gateway_oidc_tenant_bindings (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
issuer text NOT NULL,
|
|
application_id text NOT NULL,
|
|
external_tenant_id text NOT NULL,
|
|
gateway_tenant_id uuid NOT NULL REFERENCES gateway_tenants(id) ON DELETE CASCADE,
|
|
access_status text NOT NULL DEFAULT 'active'
|
|
CHECK (access_status IN ('active','disabled')),
|
|
metadata_status text NOT NULL DEFAULT 'metadata_pending'
|
|
CHECK (metadata_status IN ('metadata_pending','synced','rejected')),
|
|
display_name text,
|
|
slug text,
|
|
metadata_version text,
|
|
metadata_etag text,
|
|
metadata_updated_at timestamptz,
|
|
last_sync_at timestamptz,
|
|
next_sync_at timestamptz NOT NULL DEFAULT now(),
|
|
sync_failure_count integer NOT NULL DEFAULT 0 CHECK (sync_failure_count >= 0),
|
|
last_error_category text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE(issuer,application_id,external_tenant_id),
|
|
UNIQUE(id,gateway_tenant_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_gateway_oidc_tenant_bindings_sync
|
|
ON gateway_oidc_tenant_bindings(next_sync_at)
|
|
WHERE access_status='active';
|
|
|
|
CREATE TABLE IF NOT EXISTS gateway_oidc_user_bindings (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_binding_id uuid NOT NULL REFERENCES gateway_oidc_tenant_bindings(id) ON DELETE CASCADE,
|
|
subject text NOT NULL,
|
|
gateway_user_id uuid NOT NULL REFERENCES gateway_users(id) ON DELETE CASCADE,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
UNIQUE(tenant_binding_id,subject),
|
|
UNIQUE(id,gateway_user_id)
|
|
);
|
|
|
|
ALTER TABLE gateway_oidc_sessions
|
|
ADD COLUMN IF NOT EXISTS oidc_user_binding_id uuid
|
|
REFERENCES gateway_oidc_user_bindings(id) ON DELETE CASCADE,
|
|
ADD COLUMN IF NOT EXISTS oidc_client_id text;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_gateway_oidc_sessions_user_binding
|
|
ON gateway_oidc_sessions(oidc_user_binding_id,created_at DESC)
|
|
WHERE oidc_user_binding_id IS NOT NULL;
|
|
|
|
ALTER TABLE gateway_security_event_receipts
|
|
ADD COLUMN IF NOT EXISTS application_id text,
|
|
ADD COLUMN IF NOT EXISTS subject_type text
|
|
CHECK (subject_type IS NULL OR subject_type IN ('principal','tenant'));
|
|
|
|
ALTER TABLE gateway_oidc_revocation_watermarks
|
|
ADD COLUMN IF NOT EXISTS application_id text NOT NULL DEFAULT '',
|
|
ADD COLUMN IF NOT EXISTS subject_type text NOT NULL DEFAULT 'principal'
|
|
CHECK (subject_type IN ('principal','tenant'));
|
|
|
|
ALTER TABLE gateway_oidc_revocation_watermarks
|
|
DROP CONSTRAINT IF EXISTS gateway_oidc_revocation_watermarks_pkey;
|
|
|
|
ALTER TABLE gateway_oidc_revocation_watermarks
|
|
ADD PRIMARY KEY (issuer,application_id,tenant_id,subject_type,subject);
|
|
|
|
DROP INDEX IF EXISTS idx_gateway_oidc_revocation_watermarks_lookup;
|
|
CREATE INDEX idx_gateway_oidc_revocation_watermarks_lookup
|
|
ON gateway_oidc_revocation_watermarks(issuer,application_id,tenant_id,subject_type,subject,revoked_at);
|