Control Plane — Storage¶
The Control Plane follows a strict database-per-service model: each microservice owns its data and exposes it only through its API and published events. No service reads another service's database. Relational state lives in Azure SQL or PostgreSQL (NHibernate via ConnectSoft.Extensions.PersistenceModel.NHibernate with ConnectSoft.Extensions.Saas.NHibernate tenant filters); Redis provides caching and short-lived coordination; Azure Service Bus is the durable message backbone; Azure Key Vault holds secrets.
Target Architecture — Final-State Design
Store choice per service balances transactional consistency (Azure SQL for identity, tenancy, workflow saga state) against graph/time-series/append-only workloads (PostgreSQL for catalogue, dependency graph, audit, usage, lineage). Every row carries tenantId as part of its index for isolation.
Storage Technologies¶
| Technology | Role | Used by |
|---|---|---|
| Azure SQL | Transactional aggregates, saga state, identity. | Identity, Tenancy, Blueprint, Workflow saga, Agent, Governance. |
| PostgreSQL | Catalogue, dependency graph, append-only audit, time-series usage, lineage graph, projections. | Module catalogue, Dependency, Audit, Cost & Usage, Lineage, ProcessState. |
| Redis | Cache, quota counters, feature-flag eval, agent-pool leases. | FeatureFlag, Quota, AgentPoolManager, ProcessState, ApiToken. |
| Azure Service Bus | Durable events/commands (canonical envelope), saga messaging, dead-letter. | All services (MassTransit). |
| Azure Key Vault | Secrets: connection strings, integration credentials, signing keys. | All services; Integration connections reference secrets by configRef. |
| Azure Blob Storage | Large artifact bodies and audit exports. | ArtifactService, AuditService (via AuditExportWorker). |
Data Inventory¶
| Data | Store | Owner Service | Access Pattern | Retention | Notes |
|---|---|---|---|---|---|
| User/principal identity, clients | Azure SQL | IdentityService |
Read-heavy on auth; write on registration | Lifetime of tenant | OpenIddict schema (ConnectSoft.IdentityTemplate/AuthorizationServerTemplate). |
| Roles, permissions, scopes | Azure SQL | AuthorizationService |
Read-heavy (per request) | Lifetime of tenant | Cached in Redis. |
| Service identities, M2M credentials | Azure SQL | ServiceIdentityService |
Read on token issue | Lifetime; rotate | Secrets in Key Vault. |
| API tokens | Azure SQL + Redis | ApiTokenService |
Read-heavy validation | Until expiry/revocation | Hashed at rest; Redis caches validation. |
| Tenants | Azure SQL | TenantService |
Read-heavy; low write | Lifetime + legal hold | Slug uniquely indexed; isolation root. |
| Editions | Azure SQL | EditionService |
Read-heavy | Lifetime; versioned | Published editions immutable. |
| Subscriptions | Azure SQL | SubscriptionService |
Mixed | Lifetime + 7y billing | Drives quota & billing. |
| Feature flags | Azure SQL + Redis | FeatureFlagService |
Very read-heavy (eval) | Lifetime | Redis-cached evaluation. |
| Quota definitions & balances | Azure SQL + Redis | QuotaService |
High-frequency read/incr | Current period + history | Redis counters; SQL system of record. |
| Projects | Azure SQL | ProjectService |
Mixed | Lifetime + archive | Slug unique per tenant. |
| Environments | Azure SQL | EnvironmentService |
Read-heavy | Lifetime of project | prod gated by approvals. |
| Module catalogue | PostgreSQL | ModuleCatalogService |
Read-heavy; catalogue queries | Lifetime of project | JSONB metadata. |
| Module dependency graph | PostgreSQL | DependencyService |
Graph traversal | Lifetime of project | Cycle detection; recursive queries. |
| Blueprints & versions | Azure SQL | BlueprintService |
Mixed; versioned read | Lifetime + audit | Validated versions immutable. |
| Blueprint validation results | PostgreSQL | BlueprintValidatorService |
Write on validate; read | 1y | Projected from validation runs. |
| Context maps | PostgreSQL | ContextMapService |
Read on orchestration | Lifetime of project | Derived from blueprints. |
| Domain models | PostgreSQL | DomainModelService |
Read on orchestration | Lifetime of project | Derived from blueprints. |
| Workflow definitions | Azure SQL | WorkflowDefinitionService |
Read-heavy | Lifetime; versioned | Seeded from platform registry. |
| Workflow instance saga + event store | Azure SQL | WorkflowOrchestrator |
Append-only writes; saga reads | Lifetime + replay window | Event-sourced; enables replay. |
| Agent tasks | Azure SQL | TaskAssignmentService |
Mixed | Lifetime of workflow + audit | Idempotent assignment. |
| Process-state projection | PostgreSQL + Redis | ProcessStateService |
Very read-heavy | Rebuildable from events | Read model; Redis hot cache. |
| Replay shadow streams | PostgreSQL | WorkflowReplayService |
Append on replay | 90d | Never mutates source events. |
| Agent definitions | Azure SQL | AgentRegistryService |
Read-heavy | Lifetime; versioned | — |
| Skill definitions | Azure SQL | SkillRegistryService |
Read-heavy | Lifetime; versioned | — |
| Agent pool leases | Redis + Azure SQL | AgentPoolManager |
High-frequency read/write | Ephemeral (leases) | Leases in Redis; pool config in SQL. |
| Model policies | Azure SQL | ModelPolicyService |
Read on task assignment | Lifetime; versioned | Constrains model usage. |
| Policy definitions & decisions | Azure SQL | PolicyEngineService |
Read-heavy eval; append decisions | Decisions append-only, 7y | Decisions immutable. |
| Approval requests | Azure SQL | ApprovalService |
Mixed | Lifetime + 7y | Human gate state. |
| Audit entries | PostgreSQL (append-only) | AuditService |
Append; range queries | 7y+ (compliance) | Hash-chained; exported to Blob/SIEM. |
| Usage records & rollups | PostgreSQL (time-series) | CostUsageService |
High-volume append; aggregate | Raw 90d, rollups 7y | Time-partitioned. |
| Integration connections | Azure SQL | IntegrationService |
Read-heavy | Lifetime | Secrets in Key Vault (configRef). |
| Artifacts & metadata | PostgreSQL + Blob | ArtifactService |
Mixed; body in Blob | Lifetime + retention policy | Shares metadata with Knowledge Platform. |
| Artifact versions | PostgreSQL | VersioningService |
Read on resolve | Lifetime | Version chains. |
| Lineage edges | PostgreSQL (graph) | LineageService |
Graph traversal | Lifetime | Task→artifact→deployment lineage. |
| All events/commands | Azure Service Bus | (transport) | Publish/subscribe; dead-letter | Per topic TTL + DLQ | Canonical envelope. |
| Secrets & credentials | Azure Key Vault | (all) | Read on startup/rotation | Managed; rotated | Referenced, never inlined. |
Multi-Tenant Data Isolation¶
- Tenant column + filter: every aggregate carries
tenantId;ConnectSoft.Extensions.Saas.NHibernateapplies a global tenant filter so queries cannot cross tenants by accident. - Index discipline:
tenantIdis the leading column of tenant-scoped indexes; correlation columns (traceId,correlationId,projectId,moduleId) are indexed where cross-entity queries run (per the Metadata Schema). - Isolation models: editions may map to shared or dedicated database isolation (
Tenant.IsolationModel); high-tier tenants can be provisioned to dedicated databases per service. - Encryption: data at rest is encrypted (TDE/Azure-managed keys); secrets live in Key Vault; sensitive payloads are classified and may be redacted while metadata fields remain queryable.
Caching & Consistency¶
- Read models over joins:
ProcessStateServiceprojects workflow/task state for fast reads; the SQL event store remains the system of record. - Cache invalidation: caches key on
tenantId+ entity id; writes publish change events that invalidate Redis entries. - Eventual consistency across services: cross-service consistency is achieved via events and sagas (no distributed transactions); compensation handles failures (see Workflows).
Related¶
- Microservices · Aggregate Roots · Events · Workers · Deployment
- Reference: Metadata Schema · Event Envelope