Skip to content

Control Plane — Deployment

Target

This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.

Rewritten 2026-10-09 (design plan P1)

The June-2026 page deployed sixteen services across two AKS namespaces and Container Apps workers on Azure Service Bus. The 2026 design ships the whole platform as one host with the modules listed on the overview; the old page is archived under catalogs 2026-06.

Runtime model

Concern Choice
Deployment unit ControlPlaneApi, one container image built from the ConnectSoft microservice template; modules are assemblies composed at startup
Hosting AKS, 2 to 6 replicas, horizontal autoscaling on request rate and outbox backlog
Data control-sql (Azure SQL in saas-default; PostgreSQL allowed on-prem) with one schema per module; artifact-blob for manifests and evaluation records; cache (Redis) for scope resolution and read models
Actors Orleans silo in-process for RunGrain; membership table in control-sql
Messaging MessagingModel port; Orleans outbox/inbox adapter by default, Azure Service Bus profile where a broker is required (ADR-0012)
Identity Authorization Server (OpenIddict) and Identity microservice; workload identities for the runtime worker and partner callers
Ingress GW-01 public API gateway and GW-03 Studio BFF gateway from the API Gateway template
Configuration Config Platform for flags and reloadable options; Key Vault for secrets through workload identity
Infrastructure as code Pulumi stacks per environment and region (ADR-0017 profiles)

Topology (saas-default)

flowchart TB
    subgraph Edge["Edge"]
        GW01["GW-01 Public API"]
        GW03["GW-03 Studio BFF gateway"]
    end
    subgraph AKS["AKS, tenant-selected region"]
        subgraph NS["namespace factory-control"]
            CPA1["ControlPlaneApi replica"]
            CPA2["ControlPlaneApi replica"]
        end
        subgraph NSR["namespace factory-runtime"]
            ARW["AgentRuntimeWorker"]
        end
    end
    GW01 --> CPA1 & CPA2
    GW03 --> CPA1 & CPA2
    ARW -- gRPC --> CPA1 & CPA2
    CPA1 & CPA2 --> SQL["('control-sql')"]
    CPA1 & CPA2 --> Blob["('artifact-blob')"]
    CPA1 & CPA2 --> Redis["('cache')"]
    CPA1 & CPA2 --> KV["Key Vault"]
    CPA1 & CPA2 --> Auth["Authorization Server + Identity"]
    CPA1 & CPA2 -. outbox dispatch .-> Transport["event transport profile"]
Hold "Alt" / "Option" to enable pan & zoom

Deployment profiles

Profile (deployment profiles) Control Plane shape
saas-default ConnectSoft-operated AKS in the tenant's region (West Europe default, Israel Central available); SharedDb mode; FactoryCommercialService active
hybrid Control Plane in ConnectSoft's cloud; runtime workers, tools and knowledge stores in the customer's network; gRPC over private link
on-prem Same image in the customer's cluster; on-prem Authorization Server and Identity; internal-budget billing model only; DatabasePerTenant or DedicatedSingleTenant mode
hybrid-compute saas-default Control Plane with customer-owned model and compute pools (PF-03); nothing changes here

Scaling

Signal Action
p95 of interactive commands above 1.5 s add replica (target 2 s p95, D30)
outbox backlog above threshold add replica; alert if dispatch latency keeps growing
run grain activations per replica rebalance through Orleans placement; the silo count equals the replica count
UsageRecords write rate partition by tenant and month; reconciliation workers scale separately inside the host by partition

Tenant fairness: reservations and per-tenant concurrency limits in Run Control prevent one tenant from starving the dispatcher.

Configuration and secrets

  • Options sections are listed on each service page (Projects:*, Publication:*, RunControl:*, Usage:*, Commercial:*, ControlPlane:Host, Multitenancy, OrleansMessaging); reloadable options come from the Config Platform, the rest from the environment at start.
  • Secrets (control-sql, messaging transport, manifest signing key, payment provider) live in Key Vault and are mounted through workload identity; no Factory table stores a credential. Connection credentials for integrations are references into BC-16 and, later, the Secret Broker (BC-40).

Health and readiness

Probe Checks
/factory/health liveness process responsive
readiness control-sql reachable, migrations applied, Orleans silo joined, Authorization Server JWKS loaded, outbox dispatcher running
startup module composition complete, cache warm for scope resolution

The HealthChecks aggregator template collects the probes of the host and its dependencies for the Studio status page and for Observability.

NFR class and recovery

The Control Plane runs in the pilot-interactive class (NFR baseline, D30): tens of concurrent runs per tenant, interactive commands acknowledged under 2 s p95, 99.5 % monthly availability, RPO 15 minutes, RTO 4 hours. Restore order after a regional failure: run journal → approvals → releases → outbox/inbox → artifacts → indexes. FactoryCommercialService runs in the pilot-batch class.

Extraction triggers

A module leaves the host and becomes its own deployment unit only when one of these is documented in the ownership map: throughput isolation (run control versus administrative traffic), a separate trust boundary (commercial data), an external consumer of its gRPC surface, or a region split that requires independent placement. The module's APIs, events and schema do not change on extraction.