Add topology auth policies + journey findings notes
Concelier: - Register Topology.Read, Topology.Manage, Topology.Admin authorization policies mapped to OrchRead/OrchOperate/PlatformContextRead/IntegrationWrite scopes. Previously these policies were referenced by endpoints but never registered, causing System.InvalidOperationException on every topology API call. Gateway routes: - Simplified targets/environments routes (removed specific sub-path routes, use catch-all patterns instead) - Changed environments base route to JobEngine (where CRUD lives) - Changed to ReverseProxy type for all topology routes KNOWN ISSUE (not yet fixed): - ReverseProxy routes don't forward the gateway's identity envelope to Concelier. The regions/targets/bindings endpoints return 401 because hasPrincipal=False — the gateway authenticates the user but doesn't pass the identity to the backend via ReverseProxy. Microservice routes use Valkey transport which includes envelope headers. Topology endpoints need either: (a) Valkey transport registration in Concelier, or (b) Concelier configured to accept raw bearer tokens on ReverseProxy paths. This is an architecture-level fix. Journey findings collected so far: - Integration wizard (Harbor + GitHub App): works end-to-end - Advisory Check All: fixed (parallel individual checks) - Mirror domain creation: works, generate-immediately fails silently - Topology wizard Step 1 (Region): blocked by auth passthrough issue - Topology wizard Step 2 (Environment): POST to JobEngine needs verify - User ID resolution: raw hashes shown everywhere Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -325,7 +325,7 @@ services:
|
||||
console-builder:
|
||||
condition: service_completed_successfully
|
||||
environment:
|
||||
ASPNETCORE_URLS: "http://0.0.0.0:8080"
|
||||
ASPNETCORE_URLS: "http://0.0.0.0:8080;https://0.0.0.0:443"
|
||||
<<: [*kestrel-cert, *gc-heavy]
|
||||
ConnectionStrings__Default: *postgres-connection
|
||||
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
|
||||
@@ -832,6 +832,9 @@ services:
|
||||
CONCELIER_PLUGINS__BASEDIRECTORY: "/tmp/stellaops"
|
||||
CONCELIER_POSTGRESSTORAGE__CONNECTIONSTRING: *postgres-connection
|
||||
CONCELIER_POSTGRESSTORAGE__ENABLED: "true"
|
||||
CONCELIER_MIRROR__ENABLED: "true"
|
||||
CONCELIER_MIRROR__EXPORTROOT: "/var/lib/concelier/jobs/mirror-exports"
|
||||
CONCELIER_MIRROR__ACTIVEEXPORTID: "latest"
|
||||
CONCELIER_S3__ENDPOINT: "http://s3.stella-ops.local:8333"
|
||||
CONCELIER_AUTHORITY__ENABLED: "true"
|
||||
CONCELIER_AUTHORITY__ISSUER: "https://authority.stella-ops.local/"
|
||||
|
||||
@@ -659,7 +659,9 @@ VALUES
|
||||
'platform.context.read', 'platform.context.write',
|
||||
'doctor:run', 'doctor:admin', 'ops.health',
|
||||
'integration:read', 'integration:write', 'integration:operate', 'registry.admin',
|
||||
'timeline:read', 'timeline:write'],
|
||||
'timeline:read', 'timeline:write',
|
||||
'signer:read', 'signer:sign', 'signer:rotate', 'signer:admin',
|
||||
'trust:read', 'trust:write', 'trust:admin'],
|
||||
ARRAY['authorization_code', 'refresh_token'],
|
||||
false, true, '{"tenant": "demo-prod"}'::jsonb)
|
||||
ON CONFLICT (client_id) DO NOTHING;
|
||||
|
||||
@@ -58,3 +58,72 @@ $$;
|
||||
|
||||
-- Analytics schema
|
||||
CREATE SCHEMA IF NOT EXISTS analytics;
|
||||
|
||||
-- ── Regions (bootstrap fallback for release.regions) ──
|
||||
CREATE TABLE IF NOT EXISTS release.regions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL REFERENCES shared.tenants(id) ON DELETE CASCADE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
display_name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
crypto_profile VARCHAR(50) NOT NULL DEFAULT 'international',
|
||||
sort_order INT NOT NULL DEFAULT 0,
|
||||
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active','decommissioning','archived')),
|
||||
metadata JSONB NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_by UUID,
|
||||
UNIQUE(tenant_id, name)
|
||||
);
|
||||
|
||||
-- ── Infrastructure Bindings (bootstrap fallback) ──
|
||||
CREATE TABLE IF NOT EXISTS release.infrastructure_bindings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL REFERENCES shared.tenants(id) ON DELETE CASCADE,
|
||||
integration_id UUID,
|
||||
scope_type TEXT NOT NULL CHECK (scope_type IN ('tenant','region','environment')),
|
||||
scope_id UUID,
|
||||
binding_role TEXT NOT NULL CHECK (binding_role IN ('registry','vault','settings_store')),
|
||||
priority INT NOT NULL DEFAULT 0,
|
||||
config_overrides JSONB NOT NULL DEFAULT '{}',
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_by UUID
|
||||
);
|
||||
|
||||
-- ── Topology Point Status (bootstrap fallback) ──
|
||||
CREATE TABLE IF NOT EXISTS release.topology_point_status (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
target_id UUID,
|
||||
gate_name TEXT NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('pending','pass','fail','skip')),
|
||||
message TEXT,
|
||||
details JSONB NOT NULL DEFAULT '{}',
|
||||
checked_at TIMESTAMPTZ,
|
||||
duration_ms INT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ── Pending Deletions (bootstrap fallback) ──
|
||||
CREATE TABLE IF NOT EXISTS release.pending_deletions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
entity_type TEXT NOT NULL CHECK (entity_type IN ('tenant','region','environment','target','agent','integration')),
|
||||
entity_id UUID NOT NULL,
|
||||
entity_name TEXT NOT NULL,
|
||||
status TEXT NOT NULL CHECK (status IN ('pending','confirmed','executing','completed','cancelled')),
|
||||
cool_off_hours INT NOT NULL,
|
||||
cool_off_expires_at TIMESTAMPTZ NOT NULL,
|
||||
cascade_summary JSONB NOT NULL DEFAULT '{}',
|
||||
reason TEXT,
|
||||
requested_by UUID NOT NULL,
|
||||
requested_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
confirmed_by UUID,
|
||||
confirmed_at TIMESTAMPTZ,
|
||||
executed_at TIMESTAMPTZ,
|
||||
completed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user