ControlPlaneApi¶
Target
This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.
| Bounded context | BC-01 Project & Environment |
| Platform / plane | Control Plane / Control |
| Deployment granularity | standalone host |
| Status | target · ConnectSoft.Factory.ControlPlane |
| Built from | connectsoft-microservice · libraries: connectsoft-extensions-saas-abstractions, connectsoft-extensions-saas-asp-net-core, connectsoft-extensions-messaging-model, connectsoft-extensions-messaging-model-orleans, connectsoft-extensions-persistence-model-nhibernate, connectsoft-extensions-identity-platform, connectsoft-extensions-resource-server |
| Decisions | ADR-0001, ADR-0009, ADR-0012, ADR-0015, ADR-0016, ADR-0017 |
| Traceability | FR-01 FR-03 FUX-01 NFR-01 NFR-07 NFR-17 XL-01 |
Purpose and responsibilities¶
ControlPlaneApi is the physical host of the Control Plane. It owns no domain state of its own; it composes the modules that do (ProjectService, EnvironmentService, AgentRegistryService, AgentCardService, RunControlService, CostUsageService, FactoryCommercialService) into one ASP.NET Core process built from the ConnectSoft microservice template, with one NHibernate session factory over the control-sql store, one Orleans silo for the run grains and one messaging profile for the outbox and inbox.
The host exists so that the pilot shape (D23, deployment profiles) can ship the whole Control Plane as a single scalable unit while every module keeps its own bounded context, schema ownership, API prefix and event topics. A module is extracted into its own host only on a documented trigger in the ownership map; nothing in a module's contract changes when that happens.
Responsibilities that are the host's and nobody else's:
- Process composition: module discovery from
ControlPlane:Host:EnabledModules, shared options binding, health aggregation, OpenTelemetry resource attributes. - Edge enforcement: token validation against the Authorization Server (canonical ADR-0101), tenant resolution per canonical ADR-0100, the request-scoped
ITenantContext, correlation and causation propagation. - Transactional infrastructure: one unit of work per command that commits the module's rows and the outbox record together (ADR-0012 §4).
- Hosting of the Orleans silo that activates
RunGrainand the other control grains, keyed through the SaaS grain identity formatter.
Context and boundaries¶
flowchart LR
S["ControlPlaneApi"]
StudioBff["StudioBff"] -->|sync-http| S
AgentRuntimeWorker["AgentRuntimeWorker"] -->|grpc| S
S -->|sync-http| ext_identity_platform["ext-identity-platform"]
S -->|sync-http| ext_config_platform["ext-config-platform"]
S -->|grpc| GovernanceHost["GovernanceHost"]
The host sits behind two gateways: GW-01 (public API, used by CLI, SDKs, partner A2A callers) and GW-03 (Studio BFF traffic). It never serves browser sessions directly; the Studio BFF (StudioBff, PF-14) holds the session and calls the host with a delegated token. The runtime worker (AgentRuntimeWorker) calls the host over gRPC for leases, outcomes, approval requests and release loading, authenticated with its workload identity.
flowchart LR
subgraph Host["ControlPlaneApi (one process, 2 to 6 replicas)"]
direction TB
Edge["Edge: JWT validation, tenant context, correlation"]
Projects["ProjectService + EnvironmentService"]
Publication["AgentRegistryService + AgentCardService"]
RunControl["RunControlService + RunGrain silo"]
Usage["CostUsageService"]
Commercial["FactoryCommercialService"]
Outbox["Outbox dispatcher + inbox"]
end
GW01["GW-01 Public API"] --> Edge
GW03["GW-03 Studio BFF gateway"] --> Edge
Worker["AgentRuntimeWorker"] -- gRPC --> Edge
Edge --> Projects & Publication & RunControl & Usage & Commercial
Projects & Publication & RunControl & Usage & Commercial --> SQL["('control-sql')"]
Outbox --> Transport["event transport profile"]
Domain model¶
None modelled
No aggregates are modelled for this item yet.
No entities modelled.
The host has no aggregates. Every aggregate of the Control Plane is listed on its module page; the aggregate roots catalog shows them together.
Entities and value objects¶
None modelled
No entities or value objects are modelled for this item yet.
Data model and storage¶
| Store | Role | Engine / profile | Tables |
|---|---|---|---|
| Control plane relational store | primary | azure-sql / nhibernate-sqlserver | — |
| Cache and coordination | cache | redis / azure-cache | — |
None modelled
No tables are modelled for this item yet.
Modules share the control-sql database but own disjoint schemas (projects, publication, runcontrol, usage, commercial) and never join across them; the only shared tables are the outbox and inbox of the messaging profile. The SharedDb, DatabasePerTenant and ResidencySilo modes of canonical ADR-0100 are selected by Multitenancy:DeploymentKind and change the connection resolution only, never the schema.
APIs¶
| Method | Path | Operation | Scope | Side effects | Idempotency | Gateway | Summary |
|---|---|---|---|---|---|---|---|
GET |
/factory/health |
Health | factory.health.read |
read | natural | GW-01 | Liveness, readiness and dependency health of the host and its modules (HealthChecks aggregator feed). |
GET |
/factory/meta/modules |
ListModules | factory.meta.read |
read | natural | GW-03 | Modules loaded in this host with their versions and schema ownership; used by the Studio about page and operators. |
None modelled
No gRPC methods are modelled for this item yet.
The host exposes only health and metadata routes. Every functional route is declared by its module and is listed on the APIs catalog; the host guarantees the shared conventions (problem details, idempotency header handling, pagination, ETag on reads, scope enforcement per route).
Messages¶
None modelled
No events are modelled for this item yet.
None modelled
No commands are modelled for this item yet.
None modelled
No consumed events are modelled for this item yet.
Workers and jobs¶
None modelled
No workers are modelled for this item yet.
Module workers are hosted services inside the same process and are listed per module. The host runs the outbox dispatcher and the inbox deduplication sweep of the selected messaging profile.
Actors and grains¶
None modelled
No grains are modelled for this item yet.
Sagas and long-running flows¶
None modelled
No sagas are modelled for this item yet.
Options and configuration¶
| Section | Key | Type | Default | Reloadable | Secret | Summary |
|---|---|---|---|---|---|---|
ControlPlane:Host |
EnabledModules |
string[] | [projects, publication, run-control, usage, tenancy, commercial] |
no | no | Modules composed into this host; extraction moves a module to its own host. |
Multitenancy |
DeploymentKind |
enum | SharedDb |
no | no | Canonical ADR-0100 installation mode (SharedDb, DatabasePerTenant, ResidencySilo, DedicatedSingleTenant). |
OrleansMessaging |
ServiceName |
string | control-plane |
no | no | Messaging profile service name for outbox and inbox. |
ConnectSoftIdentityPlatform |
Authority |
uri | https://auth.<tenant-region>.connectsoft.ai |
no | no | Authorization Server authority for token validation (ADR-0101). |
Metrics and observability¶
| Metric | Instrument | Unit | Dimensions | Summary |
|---|---|---|---|---|
connectsoft.factory.host.requests |
counter | {request} | module, route, status | Requests per module and route. |
connectsoft.factory.host.request_duration |
histogram | s | module, route | Request latency (NFR-07 target 2 s p95). |
connectsoft.factory.host.outbox_backlog |
gauge | {message} | host | Unpublished outbox records. |
The host tags every span and metric with module, tenant.id and route; module-level metrics are documented on the module pages. Logs never contain prompt, artifact or payload content (D31).
Security¶
| Authentication | oauth2-jwt |
| Scopes | factory.health.read (Health probes (unauthenticated liveness, authenticated detail).); factory.meta.read (Module metadata.) |
| Roles | Observer, Operator, PlatformAdmin |
| Tenant isolation | row-filter |
| Data classification | internal |
| Max side-effect class | shared-write |
| Secrets | control-sql (key-vault, rotate 90 d); messaging-transport (key-vault, rotate 90 d) |
Dependencies¶
Outbound
| Target | Kind | Purpose | Failure mode | Required |
|---|---|---|---|---|
| ext-identity-platform | sync-http | Token validation and role claims. | fail-fast | yes |
| ext-config-platform | sync-http | Feature flags and runtime configuration (when available). | degrade | no |
| GovernanceHost | grpc | Policy decisions for module commands. | fail-fast | yes |
Inbound
| Target | Kind | Purpose | Failure mode | Required |
|---|---|---|---|---|
| StudioBff | sync-http | All Studio commands and reads. | — | yes |
| AgentRuntimeWorker | grpc | Leases, outcomes, approval requests, release loading. | — | yes |
Failure and recovery¶
| Scenario | Detection | Recovery | Data impact | RTO (min) |
|---|---|---|---|---|
| Identity Platform unreachable | token validation failures and health check | fail closed; cached JWKS allows validation of already-issued tokens until expiry | none | 15 |
| Messaging transport unavailable | outbox backlog gauge rising | transitions keep committing; dispatcher retries; alert at threshold | delayed consumers | 60 |
| Host crash | readiness probe | AKS restarts replica; grains re-activate from persisted state | none | 5 |
NFR targets¶
| Target | Class value (pilot-interactive) | Override |
|---|---|---|
| latency_p95_ms | 2000 | — |
| availability_pct | 99.5 | — |
| throughput_rps | 50 | — |
| rpo_minutes | 15 | — |
| rto_minutes | 240 | — |
| cost_class | low | — |
Deployment¶
| Granularity | standalone host |
| Topologies | saas-default, hybrid, on-prem |
| Runtime | aks; replicas 2–6 |
| Ports | https 7400, grpc 7402, silo 11400, gateway 30400 |
Deployed on AKS with two to six replicas behind the gateways; the Orleans cluster membership uses the control-sql store. Hybrid and on-prem profiles run the same image with the on-prem messaging and identity endpoints; see deployment profiles and the Control Plane deployment page.
Current implementation¶
Nothing exists. The template that will produce this host exists (ConnectSoft.MicroserviceTemplate with the SaaS, NHibernate and Orleans messaging switches), as do the Authorization Server and Identity microservice it depends on; see the ecosystem composition.
Later capabilities¶
Extraction of RunControlService into its own host when runtime throughput isolates it from administrative traffic; a read-only replica host for reporting; per-region host pairs for the ResidencySilo mode.
Decisions and traceability¶
| Family | Ids |
|---|---|
| FR | FR-01, FR-03 |
| FUX | FUX-01 |
| NFR | NFR-01, NFR-07, NFR-17 |
| XL | XL-01 |