qa iteration 3
Fresh-DB bootstrap fixes enabling 25/25 pages zero HTTP errors: - Fix shared.tenants schema mismatch (missing is_default column in init script 16) - Align migration 000 column set with init script (superset for all modules) - Seed Authority tenant + stella-ops-ui OAuth client in init script 04 - Widen Platform auth bypass to cover Docker (172.0.0.0/8) and localhost (127.0.0.0/8) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -341,7 +341,9 @@ services:
|
|||||||
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
|
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
|
||||||
Platform__Authority__Issuer: "https://authority.stella-ops.local/"
|
Platform__Authority__Issuer: "https://authority.stella-ops.local/"
|
||||||
Platform__Authority__RequireHttpsMetadata: "false"
|
Platform__Authority__RequireHttpsMetadata: "false"
|
||||||
Platform__Authority__BypassNetworks__0: "172.19.0.0/16"
|
Platform__Authority__BypassNetworks__0: "172.0.0.0/8"
|
||||||
|
Platform__Authority__BypassNetworks__1: "127.0.0.0/8"
|
||||||
|
Platform__Authority__BypassNetworks__2: "::1/128"
|
||||||
Logging__LogLevel__StellaOps.Auth: "Debug"
|
Logging__LogLevel__StellaOps.Auth: "Debug"
|
||||||
Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Debug"
|
Logging__LogLevel__Microsoft.AspNetCore.Authentication: "Debug"
|
||||||
Logging__LogLevel__Microsoft.AspNetCore.Authorization: "Debug"
|
Logging__LogLevel__Microsoft.AspNetCore.Authorization: "Debug"
|
||||||
|
|||||||
@@ -465,6 +465,14 @@ CREATE INDEX IF NOT EXISTS idx_verdict_digest
|
|||||||
|
|
||||||
COMMENT ON TABLE authority.verdict_manifests IS 'VEX verdict manifests for deterministic replay verification';
|
COMMENT ON TABLE authority.verdict_manifests IS 'VEX verdict manifests for deterministic replay verification';
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- SECTION 4b: Seed Default Tenant
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
INSERT INTO authority.tenants (tenant_id, name, display_name, status)
|
||||||
|
VALUES ('demo-prod', 'Production', 'Demo Production', 'active')
|
||||||
|
ON CONFLICT (tenant_id) DO NOTHING;
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
-- SECTION 5: Triggers
|
-- SECTION 5: Triggers
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
@@ -609,3 +617,46 @@ BEGIN
|
|||||||
END
|
END
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
-- SECTION 8: Demo Seed Data
|
||||||
|
-- ============================================================================
|
||||||
|
|
||||||
|
-- Roles for demo-prod tenant
|
||||||
|
INSERT INTO authority.roles (id, tenant_id, name, display_name, description, is_system)
|
||||||
|
VALUES
|
||||||
|
('a0000002-0000-0000-0000-000000000001', 'demo-prod', 'admin', 'Administrator', 'Full platform access', true),
|
||||||
|
('a0000002-0000-0000-0000-000000000002', 'demo-prod', 'operator', 'Operator', 'Release and deployment operations', true),
|
||||||
|
('a0000002-0000-0000-0000-000000000003', 'demo-prod', 'viewer', 'Viewer', 'Read-only access', true)
|
||||||
|
ON CONFLICT (tenant_id, name) DO NOTHING;
|
||||||
|
|
||||||
|
-- OAuth Clients
|
||||||
|
INSERT INTO authority.clients (id, client_id, display_name, description, enabled, redirect_uris, post_logout_redirect_uris, allowed_scopes, allowed_grant_types, require_client_secret, require_pkce, properties)
|
||||||
|
VALUES
|
||||||
|
('demo-client-ui', 'stella-ops-ui', 'Stella Ops Console', 'Web UI application', true,
|
||||||
|
ARRAY['https://stella-ops.local/auth/callback', 'https://stella-ops.local/auth/silent-refresh', 'https://127.1.0.1/auth/callback', 'https://127.1.0.1/auth/silent-refresh'],
|
||||||
|
ARRAY['https://stella-ops.local/', 'https://127.1.0.1/'],
|
||||||
|
ARRAY['openid', 'profile', 'email', 'offline_access',
|
||||||
|
'ui.read', 'ui.admin', 'ui.preferences.read', 'ui.preferences.write',
|
||||||
|
'authority:tenants.read', 'authority:users.read', 'authority:roles.read',
|
||||||
|
'authority:clients.read', 'authority:tokens.read', 'authority:branding.read',
|
||||||
|
'authority.audit.read',
|
||||||
|
'graph:read', 'sbom:read', 'scanner:read',
|
||||||
|
'policy:read', 'policy:simulate', 'policy:author', 'policy:review', 'policy:approve',
|
||||||
|
'policy:run', 'policy:activate', 'policy:audit', 'policy:edit', 'policy:operate', 'policy:publish',
|
||||||
|
'airgap:seal', 'airgap:status:read',
|
||||||
|
'orch:read', 'analytics.read', 'advisory:read', 'advisory-ai:view', 'advisory-ai:operate',
|
||||||
|
'vex:read', 'vexhub:read',
|
||||||
|
'exceptions:read', 'exceptions:approve', 'aoc:verify', 'findings:read',
|
||||||
|
'release:read', 'scheduler:read', 'scheduler:operate',
|
||||||
|
'notify.viewer', 'notify.operator', 'notify.admin', 'notify.escalate',
|
||||||
|
'evidence:read',
|
||||||
|
'export.viewer', 'export.operator', 'export.admin',
|
||||||
|
'vuln:view', 'vuln:investigate', 'vuln:operate', 'vuln:audit',
|
||||||
|
'platform.context.read', 'platform.context.write',
|
||||||
|
'doctor:run', 'doctor:admin', 'ops.health',
|
||||||
|
'integration:read', 'integration:write', 'integration:operate',
|
||||||
|
'timeline:read', 'timeline:write'],
|
||||||
|
ARRAY['authorization_code', 'refresh_token'],
|
||||||
|
false, true, '{"tenant": "demo-prod"}'::jsonb)
|
||||||
|
ON CONFLICT (client_id) DO NOTHING;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ CREATE TABLE IF NOT EXISTS shared.tenants (
|
|||||||
tenant_id TEXT NOT NULL UNIQUE,
|
tenant_id TEXT NOT NULL UNIQUE,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
display_name TEXT,
|
display_name TEXT,
|
||||||
|
is_default BOOLEAN NOT NULL DEFAULT false,
|
||||||
status TEXT NOT NULL DEFAULT 'active',
|
status TEXT NOT NULL DEFAULT 'active',
|
||||||
settings JSONB NOT NULL DEFAULT '{}',
|
settings JSONB NOT NULL DEFAULT '{}',
|
||||||
metadata JSONB NOT NULL DEFAULT '{}',
|
metadata JSONB NOT NULL DEFAULT '{}',
|
||||||
@@ -17,6 +18,10 @@ CREATE TABLE IF NOT EXISTS shared.tenants (
|
|||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_shared_tenants_single_default
|
||||||
|
ON shared.tenants (is_default)
|
||||||
|
WHERE is_default;
|
||||||
|
|
||||||
-- Seed shared tenant for local dev
|
-- Seed shared tenant for local dev
|
||||||
INSERT INTO shared.tenants (tenant_id, name, display_name, status)
|
INSERT INTO shared.tenants (tenant_id, name, display_name, status)
|
||||||
VALUES ('demo-prod', 'Production', 'Demo Production', 'active')
|
VALUES ('demo-prod', 'Production', 'Demo Production', 'active')
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ if (!string.IsNullOrWhiteSpace(bootstrapOptions.Storage.PostgresConnectionString
|
|||||||
builder.Services.AddSingleton<IPlatformContextStore, PostgresPlatformContextStore>();
|
builder.Services.AddSingleton<IPlatformContextStore, PostgresPlatformContextStore>();
|
||||||
builder.Services.AddSingleton<ITranslationStore, PostgresTranslationStore>();
|
builder.Services.AddSingleton<ITranslationStore, PostgresTranslationStore>();
|
||||||
|
|
||||||
// Auto-migrate platform schemas on startup (release, platform, analytics, shared)
|
// Auto-migrate platform schemas on startup
|
||||||
builder.Services.AddStartupMigrations<PlatformServiceOptions>(
|
builder.Services.AddStartupMigrations<PlatformServiceOptions>(
|
||||||
schemaName: "release",
|
schemaName: "release",
|
||||||
moduleName: "Platform.Release",
|
moduleName: "Platform.Release",
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
-- Release schema prerequisite for tenant fallback lookups.
|
-- Release schema prerequisite for tenant fallback lookups.
|
||||||
-- Keeps clean-install migration execution independent from optional shared-schema owners.
|
-- Keeps clean-install migration execution independent from optional shared-schema owners.
|
||||||
|
-- Column set is the superset of what all modules need (Authority, Platform, etc.).
|
||||||
|
|
||||||
CREATE SCHEMA IF NOT EXISTS shared;
|
CREATE SCHEMA IF NOT EXISTS shared;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS shared.tenants (
|
CREATE TABLE IF NOT EXISTS shared.tenants (
|
||||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||||
|
tenant_id TEXT NOT NULL UNIQUE,
|
||||||
|
name TEXT NOT NULL DEFAULT '',
|
||||||
|
display_name TEXT,
|
||||||
is_default BOOLEAN NOT NULL DEFAULT false,
|
is_default BOOLEAN NOT NULL DEFAULT false,
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
status TEXT NOT NULL DEFAULT 'active',
|
||||||
|
settings JSONB NOT NULL DEFAULT '{}',
|
||||||
|
metadata JSONB NOT NULL DEFAULT '{}',
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_shared_tenants_single_default
|
CREATE UNIQUE INDEX IF NOT EXISTS uq_shared_tenants_single_default
|
||||||
|
|||||||
Reference in New Issue
Block a user