Architecture
Components, dependencies, data flows, and the security model of a self-hosted Ensemble deployment.
This page describes what runs where, what each component depends on, and how the pieces communicate. Read it before you deploy so the configuration and Terraform references make sense in context.
Components
The platform is four container images deployed by the Helm chart. Three are long-running workloads; one is a one-shot job that runs during install and upgrade.
| Component | Image | Kind | Port | Health check | Purpose |
|---|---|---|---|---|---|
web | workflows/web | Deployment | 3000 | GET / | The browser-facing web application and user interface |
server | workflows/server | Deployment | 3001 | GET /health | REST API: agent invocation, tools, auth, storage, orchestration |
worker | workflows/worker | Deployment | 8080 | GET / | Temporal worker that executes workflow activities |
migration | workflows/migration | Job (hook) | n/a | n/a | Creates and migrates the database schema |
All images share a single tag that tracks the chart's appVersion, so a given
chart version deploys a matching, consistent set of images. See
Helm chart for how tags and chart versions relate.
The workloads run as non-root (UID 1000) with a read-only root filesystem and all
Linux capabilities dropped. This is why they mount small emptyDir volumes at
/tmp and /home/node/.npm.
Dependencies
The chart deploys the application; you provide the services it depends on. Some are created for you by Terraform (in your account); others are external services you bring.
| Dependency | Required | Provided by | Notes |
|---|---|---|---|
| PostgreSQL 16+ | Yes | You | Amazon RDS, Cloud SQL, or Neon. Passed as PG_BASE_URL. |
| Temporal | Yes | You | Temporal Cloud or a self-hosted Temporal server. Passed as TEMPORAL_*. |
| Object storage | Yes | Terraform | Three buckets: user files, documents, tenant migrations. |
| Secrets store | Yes | Terraform | AWS Secrets Manager or GCP Secret Manager, synced into the cluster. |
| KMS keys | Yes | Terraform | Envelope encryption for secrets, connections, and environment data. |
| Auth provider | Yes | Terraform | AWS Cognito or Firebase (Identity Platform). |
| LLM providers | Yes | You | At least one of OpenAI, Anthropic, Google, AWS Bedrock, or Vertex AI. |
| Scheduler | Optional | Terraform | EventBridge Scheduler (AWS) or Cloud Scheduler (GCP) for timed jobs. |
| Redis | Optional | You | ElastiCache or Memorystore. Enables cross-instance caching and AI rate limiting. |
Neither Terraform stack creates the Kubernetes cluster, the database, or the Temporal server. Those are prerequisites you stand up first. The Terraform provisions only the supporting cloud resources (storage, secrets, KMS, IAM, auth). See Prerequisites.
Request and data flow
- A user or API client hits the ingress (an ALB on AWS or a GCE load balancer on
GCP), which terminates TLS and routes by path:
/apiand other API prefixes go toserver, everything else goes toweb. webrenders the UI and callsserverfor data.serverauthenticates the request (Cognito or Firebase), reads and writes the PostgreSQL database, stores files in object storage, decrypts secrets and connection credentials with KMS, and calls the configured LLM providers.- For workflow and long-running activities,
serverschedules work on Temporal; theworkerpicks up tasks, runs activities (which may call tools, storage, and LLMs), and reports results back through Temporal. - The
migrationjob runs before the app starts (on every install and upgrade) to bring the database schema up to date.
Identity and access
Workloads authenticate to cloud APIs without static credentials:
- AWS: IRSA (IAM Roles for Service Accounts). The Kubernetes service account
workflows-sais annotated with an IAM role ARN; pods assume that role via the cluster's OIDC provider. The role grants scoped access to the three S3 buckets, the KMS key, Secrets Manager, the scheduler, Cognito admin actions, and Bedrock. - GCP: Workload Identity. The Kubernetes service account is bound to a Google
service account via the
iam.gke.io/gcp-service-accountannotation. That service account is granted scoped access to the buckets, KMS keys, Secret Manager, and Vertex AI.
Secrets never live in the chart or in Git. They are stored in your cloud secrets manager and synchronized into the cluster (typically by the External Secrets Operator), then mounted into pods as environment variables. See Configuration.
Multi-tenancy
The platform is multi-tenanted. A single deployment serves many tenants, isolated
at the data layer. When self-hosting a single-organization deployment, set
SELF_HOSTING=true, which restricts tenant lifecycle operations to a superuser and
hides tenant/user switching in the UI.
Network topology (recommended)
- Run worker and (optionally) server nodes in private subnets with a NAT gateway for a stable outbound IP, which you can allowlist with external services such as your database or Temporal.
- Expose only the ingress publicly. The
server,web, andworkerservices areClusterIPand are not directly reachable from the internet. - Restrict database access to the cluster's security group or VPC.