Self-host
Run Armalo inside your own boundary.
The on-prem install is the same product as the pooled SaaS — one codebase, deployment-shape-agnostic. This page is the production install guide. The deploy path runs on your infrastructure, not a hyperscaler fallback.
1. Architecture overview
The on-prem install runs the same five planes as pooled SaaS — Experience, Collaboration, Control, Agent Runtime, Observability. The platform is deployment-shape-agnostic; the only difference between pooled and on-prem is the network boundary and the operator who owns it.
Public edge
TLS, DNS, WAF
TLS 1.3 at the edge, DDoS protection, WAF rules, public DNS. Tenants keep their own data-plane cost — the edge sits in front of whatever you provision.
Control plane
Identity, tenancy, billing, audit
Postgres, Drizzle migrations, audit, metering, vault. Owns every authoritative room event, every tenant boundary, every spend cap.
Agent runtime
Per-tenant isolated execution
Per-tenant sandbox with snapshot/resume + persistent volume. The sandbox runtime is capability-detected at install preflight: the hook probes for the strongest available isolation tier (KVM -> gVisor -> container floor) and fails the install when the cluster can't meet the configured minimum (firecracker-class by default); a weaker tier is reported as degraded posture in the health console, never silent.
See the security page for the full isolation, residency, and compliance posture against this runtime.
2. Infrastructure prerequisites
Bring your own cloud — Kubernetes, object storage, DNS, TLS, Postgres, secrets manager. The install does not require any specific hyperscaler; the substrate is the cluster you already operate. Provision the following:
- A Kubernetes cluster. Any conformant distribution — managed or self-hosted. The Helm chart targets the upstream Kubernetes API; no cloud-specific CRDs.
- Postgres 16. A managed instance or a self-managed cluster. The control plane requires the standard Postgres feature set (RLS, GUC, PITR); set postgresql.byo.host, port, and database to point the chart at it.
- Object storage with a CDN in front. For artifact, attachment, and snapshot storage. Set objectStore.byo.endpoint, region, and bucket to point the chart at it.
- A public DNS zone + ACME. Custom domains and TLS termination are operator-supplied: enable the chart's ingress, pick your ingress class, and name a pre-created TLS secret (cert-manager with your own ACME issuer works; the chart mounts the secret you name via ingress.tls.secretName).
3. The Helm install path
The install path is the Helm chart itself — no per-service deploy scripts. The release assembles the control-plane services (gateway, orchestrator, sync, control plane, web) as one templated Deployment each. License is read from the armalo-license secret (offline Ed25519 blob) or the license phone-home endpoint — see values.yaml#license. The installer creates the credential Secrets first (never in values):
helm install armalo ./infra/helm -n armalo --create-namespace -f infra/helm/values.yaml
kubectl -n armalo create secret generic armalo-postgres-credentials \
--from-literal=username=armalo_app --from-literal=password=REPLACE4. Helm chart for the on-prem install
For fully airgap-capable cluster installs, use the chart at infra/helm/:
values.yaml
Default installation: bundled Postgres, MinIO, NATS, and Vault; the sandbox runtime is capability-detected at install preflight. Region lives on the backing-service seams (e.g. objectStore.byo.region, default us-east-1) — the chart has no global region and no tenant-region policy.
values-airgap.yaml
Airgap-capable: external dependencies pinned to local registries; telemetry fully offline; chart distribution as a tarball.
templates/
Kubernetes manifests for control plane, agent runtime, observability, ingress, secrets, and policy engine.
helm upgrade --install armalo ./infra/helm \
-f infra/helm/values.yaml \
--namespace armalo --create-namespace5. Operations runbook
Backups
Backups are operator-owned in self-host. The chart gives you persistent volumes (Postgres StatefulSet, MinIO PVC) and no backup automation — run pg_basebackup/WAL archiving against your object store on the schedule your policy requires, and keep as long a window as your own policy requires. For restores, run scripts/workspace-doctor.mjs against any historical snapshot. (Armalo's own hosted backups follow the published data-retention policy.)
Disaster recovery
The DR posture is one region failover + one region restoration. Recovery is a fresh chart install against the new region: recreate the credential Secrets, run the Helm install with your values file, and verify /healthz. Active tenants continue from the replicated audit trail (replayable from the room log + CRDT states).
Monitoring
Fleet health surfaces in the operator console (/ops). Each control-plane service (gateway, orchestrator, sync, control plane, web) ships with its own liveness + readiness probe. The install preflight refuses the release when the detected sandbox tier falls below the configured minimum (firecracker-class by default); a missing or invalid license degrades the release to read-only, never a crash.
Secret rotation
Room tokens are short-lived — 4 hours by default, configurable on the identity service (RoomTokenServiceConfig.ttlMs). Webhook secrets rotate when you register a new webhook; the old secret stays valid until the registration is replaced. Key rotation for KMS-backed secrets follows the KMS provider's rotation policy — the chart ships no rotation scheduler of its own. Long-lived cloud credentials are never stored in an agent or a committed file.
Need help with the install?
Our solutions team delivers the install for enterprise and agency deployments — same engine, your boundary. Reach out via the contact page to scope.