Deployment
Kesita deploys containerized workloads on Azure. Staging and production are separate environments. Managed PostgreSQL, Blob Storage, Key Vault and external providers are dependencies, not processes inside the application runtime.
Open the cloud architecture explorer.
Runtime topology
Section titled “Runtime topology”flowchart TB
Internet[Internet]
subgraph Public[Public ingress]
App[Kesita app]
Site[Website]
PublicAPI[Future Public Legal API]
MCP[Future MCP server]
end
subgraph Private[Private application plane]
ProductAPI[Product API]
ProductWorker[Product worker + DBOS runtime]
LegalCore[Legal Core API]
CorpusWorker[Corpus worker]
Parser[Isolated document parser]
end
subgraph Data[Managed data]
ProductData[(Product PostgreSQL + blobs)]
LegalData[(Legal PostgreSQL + corpus blobs)]
Secrets[Key Vault]
end
Internet --> App
Internet --> Site
Internet -. future .-> PublicAPI
Internet -. future .-> MCP
App --> ProductAPI
PublicAPI -->|Workload JWT| LegalCore
MCP --> PublicAPI
ProductAPI --> ProductData
ProductAPI --> ProductWorker
ProductWorker --> ProductData
ProductWorker --> LegalCore
ProductWorker --> Parser
LegalCore --> LegalData
CorpusWorker --> LegalData
Private -. managed identity .-> Secrets
Trust boundaries
Section titled “Trust boundaries”- Only intended web, Public API and MCP endpoints receive internet ingress.
- Product API, workers, Legal Core, parser and data services remain private. DBOS is linked into each worker; it is not a separately deployed service.
- Legal Core alone reads legal stores; product workloads call it with short-lived workload JWTs.
- The parser receives bounded document bytes and no database, blob or provider credentials.
- Each runtime receives a narrow database/cloud identity; migrator credentials are not runtime credentials.
- Requests propagate a request ID and W3C trace context without logging credentials, prompts, document bodies or legal text.
Azure resource map
Section titled “Azure resource map”This diagram reflects the Terraform structure rather than presenting managed services as containers. Staging and production each instantiate this topology independently.
flowchart TB
Users[Users and operators]
GitHub[GitHub Actions<br/>federated delivery identity]
Providers[Clerk, Anthropic, Voyage,<br/>Document Intelligence and Resend]
subgraph Azure[Azure environment]
subgraph Edge[Public edge]
FrontDoor[Azure Front Door<br/>custom domains and managed TLS]
WAF[WAF prevention policy<br/>global rate limit]
end
subgraph AppsSubnet[Apps subnet · public Container Apps Environment]
App[app]
Site[site]
Docs[docs]
PublicAPI[Future Public Legal API]
MCP[Future MCP server]
end
subgraph BackendSubnet[Backend subnet · internal Container Apps Environment]
ProductAPI[product-api]
ProductWorker[product-worker]
LegalAPI[legal-api]
CorpusWorker[corpus-worker]
Parser[document-parser]
ProductMigrator[product-migrator job]
LegalMigrator[legal-migrator job]
end
subgraph EndpointSubnet[Private endpoint subnet]
PgPE[PostgreSQL private endpoint]
BlobPE[Blob private endpoint]
VaultPE[Key Vault private endpoint]
AcrPE[ACR private endpoint]
PrivateDNS[Private DNS zones]
end
subgraph ManagedData[Managed data and secrets]
Postgres[(PostgreSQL Flexible Server<br/>product + legal databases)]
Storage[(Storage account<br/>product + corpus + deletion-journal)]
KeyVault[Key Vault]
ACR[Azure Container Registry]
end
subgraph Operations[Operations]
Logs[Log Analytics]
Alerts[Azure Monitor alerts<br/>and action group]
Budget[Resource-group budget]
end
Network[VNet · NSGs · private DNS<br/>NAT-controlled egress]
Identities[Per-workload managed identities<br/>narrow RBAC grants]
end
Users -->|HTTPS| FrontDoor
FrontDoor --> WAF
WAF --> App
WAF --> Site
WAF --> Docs
WAF -. future .-> PublicAPI
WAF -. future .-> MCP
App -->|private HTTPS| ProductAPI
MCP -. typed calls .-> PublicAPI
PublicAPI -. workload JWT .-> LegalAPI
ProductWorker -->|durable workflow state| PgPE
CorpusWorker -->|durable workflow state| PgPE
ProductWorker --> Parser
ProductWorker --> LegalAPI
BackendSubnet --> Network
AppsSubnet --> Network
Network --> EndpointSubnet
PgPE --> Postgres
BlobPE --> Storage
VaultPE --> KeyVault
AcrPE --> ACR
PrivateDNS --> EndpointSubnet
Identities -->|container-scoped RBAC| Storage
Identities -->|secret-scoped RBAC| KeyVault
Identities -->|AcrPull| ACR
ProductAPI --> PgPE
ProductWorker --> PgPE
ProductAPI --> BlobPE
ProductWorker --> BlobPE
LegalAPI --> PgPE
LegalAPI --> BlobPE
CorpusWorker --> PgPE
CorpusWorker --> BlobPE
BackendSubnet --> VaultPE
AppsSubnet -. logs .-> Logs
BackendSubnet -. logs .-> Logs
Postgres -. metrics .-> Alerts
Budget --> Alerts
GitHub -->|OIDC and immutable image digests| ACR
ACR --> AppsSubnet
ACR --> BackendSubnet
App --> Providers
ProductWorker --> Providers
LegalAPI --> Providers
The public Container Apps Environment is reachable only through Front Door for the configured hosts. The backend environment uses an internal load balancer and private DNS. PostgreSQL, Blob Storage, Key Vault and ACR disable or avoid general public data-plane access and are reached through private endpoints. NSGs separate apps, backend, endpoints and runner subnets; NAT provides stable controlled egress where required. DBOS stores its durable state in the owning service’s PostgreSQL database, so there is no DBOS VM, disk, subnet, ingress or Conductor deployment.
Public Legal API and MCP server are future placements, not members of the current ten-image release inventory. Adding them requires Terraform, workload identities, Front Door routes, WAF/rate-limit policy and release-manifest changes.
Environments
Section titled “Environments”flowchart LR Code[Reviewed source] --> Build[OCI images] Build --> Staging[Staging] Staging -->|Verified release evidence| Production[Production] Local[Local Compose] -. Same service contracts .-> Staging
Local development uses Compose and simulated dependencies by default. Staging validates real networking, identity, provider and recovery behavior. Production promotion must use the exact tested artifacts; infrastructure configuration alone is not evidence that the system is ready.
The Public API and MCP nodes are intentionally marked future. Their authentication and request flows are defined in External API and MCP; they must not be inferred as deployed from this diagram.