aisquared Helm chart deploys the AI Squared platform into a Kubernetes cluster. The platform is cloud-agnostic and runs on any conformant cluster, including Amazon EKS, Azure AKS, Google GKE, and MicroK8s.
multiwoven to aisquared in version 0.117.0 and is still served from the same Helm repository. If you already run the multiwoven chart, follow Upgrading from the multiwoven chart instead of doing a fresh install.What gets deployed
- An Ingress for every public hostname.
- cert-manager
Issuers for Let’s Encrypt (when NGINX ingress is used). - HorizontalPodAutoscalers for each application component (
hpa.enabled: true). - The namespace set in
kubernetesNamespace(defaultaisquared).
Prerequisites
- A Kubernetes cluster and
kubectlconfigured to reach it - Helm 3
- A domain you control, with permission to create DNS records
- An email address for Let’s Encrypt registration (
example.comaddresses are rejected) - (Optional) A Temporal Cloud namespace, recommended for production
Hostnames
The platform is exposed on several subdomains. The chart defaults areexample.com placeholders, so you must set every one of them:
Install
Install an ingress controller
nginx ingress class. Install the NGINX ingress controller:nginx ingress class (or ALB or Kong), so ingress-nginx is still the default path. For new production clusters on AWS, consider the ALB option.Install cert-manager
Create your values file
Install the chart
--namespace/--create-namespace. The chart creates the namespace in kubernetesNamespace itself and deploys everything there.aisquared, resources are named aisquared-server, aisquared-postgresql, and so on. Other release names give <release>-aisquared-server. The in-cluster addresses for PostgreSQL, Temporal, and Lightning are worked out from the release name automatically.Point DNS at the ingress controller
A record (or a CNAME if your provider returns a hostname) for each hostname in Hostnames, pointing at that address. See your DNS provider’s documentation:Verify the staging certificate
Ready: True:https://app.your-domain.com. The browser will warn that the certificate is not trusted; this is expected for the Let’s Encrypt staging issuer. Confirm that the certificate was issued by (STAGING) Let's Encrypt.Switch to the production certificate
platformConfig.tlsCertIssuer: letsencrypt-prod in my-values.yaml and upgrade:https://app.your-domain.com.Temporal
By default the chart runs Temporal and the Temporal UI in the cluster (temporal.enabled: true). This is fine for development and evaluation. For production, we strongly recommend Temporal Cloud.
To use Temporal Cloud:
-
Download your Temporal Cloud namespace’s client certificate and key, and create a secret named
temporal-cloudin the platform namespace:The namespace exists only after the firsthelm install. If you’re configuring Temporal Cloud from the start, create the namespace withkubectl create namespace aisquaredfirst. -
Add the following to your values file:
platformConfig.temporalUiHostisn’t used when in-cluster Temporal is disabled.
Ingress options
Choose one ingress option:externalDNS.enabled: true if you run ExternalDNS and want the DNS records created for you.
To restrict access by source IP, set platformConfig.allowedSourceIP (NGINX only; default 0.0.0.0/0).
External databases
To use a managed PostgreSQL instance (for example Amazon RDS or Azure Database for PostgreSQL) instead of the in-cluster one:multipleDbHosts.enabled: true and fill in multipleDbHosts.platformDBHost, temporalDbHost, and temporalVisibilityDbHost (and the matching *Name keys).
Secrets
By default, the credentials in your values file (database passwords, API keys, SMTP passwords) are rendered into a ConfigMap. For production on AWS, the chart can load them from AWS Secrets Manager instead, through the Secrets Store CSI Driver.How it works
Credentials are split into groups, and you turn each group on separately. For each group you turn on:- You create one JSON secret in AWS Secrets Manager holding that group’s keys.
- The chart creates a
SecretProviderClassthat tells the CSI driver which JSON keys to read from that secret. - When a pod that uses the group starts, the driver fetches the secret. It copies the values into a Kubernetes
Secretin the platform namespace. That Secret is named by the group’s alias. - The pods read their environment variables from that Kubernetes Secret. The matching plaintext keys are left out of the ConfigMap, and the values in your values file are ignored.
Groups
secretsStore.
What to put in each secret
Each Secrets Manager secret is a JSON object. Every key listed for a group must be present, even if you don’t use that feature. Set unused keys to an empty string (""). If a key is missing, the CSI driver can’t mount the volume, and the pods using that group stay in ContainerCreating.
The three database groups each use two short keys, u (username) and p (password):
values.yaml. For example, the application group’s smtpPassword replaces platformConfig.smtpPassword.
Application (appCredsSecretName)
Application (appCredsSecretName)
platformConfig.Sandbox (sandboxCredsSecretName)
Sandbox (sandboxCredsSecretName)
sandboxConfig.Lightning (lightningCredsSecretName)
Lightning (lightningCredsSecretName)
lightningConfig.Box (boxCredsSecretName)
Box (boxCredsSecretName)
boxConfig.boxApiKey, boxConfig.boxEncryptionKey, boxConfig.dbUsername, boxConfig.dbPassword, and the coding-agent keys under sandboxConfig.Set it up
Install the CSI driver and the AWS provider
syncSecret.enabled=true is required: without it the driver never creates the Kubernetes Secrets, and the pods fail to start.Create the secrets in AWS Secrets Manager
prod-aisquared/app, so you can scope IAM to that prefix and keep environments apart:file:// for anything with real values, so the secrets don’t end up in your shell history.Grant the pods read access
kms:Decrypt on that key.Box uses its own service account. To use the Box group, give Box a separate role through box.serviceAccount.annotations.Configure the chart
secretRegion must match the region the secrets are in. Enabling a group without its *CredsSecretName makes the install fail with an error naming the missing value.Verify
ContainerCreating, look at its events:AccessDenied: the IAM role or policy doesn’t cover the secret name, or the service account annotation is missing.- A JMES path error: the secret is missing one of the group’s keys.
Failed to fetch secret from all regions:secretRegionis wrong.
App Builder
App Builder (called agentic coding in the chart and the code) lets users build apps by chatting with a coding agent. Self-hosting it involves three pieces:Coding agent
- Choosing the provider: the prefix of
codingAgentModelselects it, for exampleanthropic/,openai/,google/,groq/oramazon-bedrock/. - API key:
codingAgentModelApiKeyis the key for that provider. It’s required when the sandbox runtime is Box. - Amazon Bedrock: set
codingAgentModelto anamazon-bedrock/...value andcodingAgentBedrockModelIdto your Bedrock inference profile. Bedrock uses AWS credentials from the pod instead of an API key.
Sandbox runtime: Modal (default)
Sandbox runtime: Box (in your cluster)
Box is a small service that creates sandbox pods in your cluster. It gives each one a persistent volume and an ingress URL, snapshots idle sandboxes, and promotes finished apps to long-running releases. Cluster requirements- The VolumeSnapshot CRDs and snapshot-controller.
- A CSI storage driver that supports snapshots, with a
VolumeSnapshotClassmatchingboxConfig.boxSnapshotClass. - A
StorageClassmatchingboxConfig.boxStorageClass. - An ingress controller (
boxConfig.boxIngressClass, inboxConfig.boxIngressNamespace). - A wildcard DNS record
*.<boxIngressDomain>pointing at that ingress controller. - A PostgreSQL database for Box’s own state.
- API key:
platformConfig.boxApiKey(used by the platform) andboxConfig.boxApiKey(checked by Box) must be the same value. - Encryption key:
boxEncryptionKeymust be exactly 64 hex characters. It encrypts the secrets Box stores, so keep it stable; changing it makes existing sandbox secrets unreadable. - Namespaces and permissions: the chart creates the
box-sandboxesnamespace (boxConfig.boxK8sNamespace), a ClusterRole, a RoleBinding in that namespace, and thebox-criticalPriorityClass. Box runs under its own service account. For AWS access, give it a role throughbox.serviceAccount.annotations; it doesn’t share the platform’s role. - Restricted clusters: where you can’t create namespaces or RBAC (for example GovCloud), set
box.namespaces.create: falseandbox.rbac.create: false, and have a cluster admin create them.
Storage and databases for generated apps
Apps that users build can get their own file storage and Postgres database:none to turn that capability off.
The storage role (agenticCodingStsRoleName) needs:
- A trust policy for the cluster’s OIDC provider. From 0.124.0, the platform assumes the role with its IRSA web identity token. If you use static AWS keys instead of IRSA, trust the IAM principal those keys belong to.
- A
MaxSessionDurationof at leastagenticCodingStsDuration. That’s 12 hours by default; AWS’s own default is 1 hour.
Published apps
Published apps are served at<app-label>.<appgenPublishedDomain> and proxied through the platform API. To turn this on:
- Create a wildcard DNS record,
*.apps.your-domain.com, pointing at your ingress controller. - Provide a wildcard TLS certificate.
- NGINX: the HTTP-01 issuers this chart creates can’t issue wildcard certificates. Create the
tlsSecretNamesecret in the platform namespace yourself, or issue it with a cert-manager DNS-01 issuer. - ALB: cover the wildcard in your ACM certificate. Leave
appbuilderIngress.groupOrderhigher thanawsIngress.groupOrder, so that exact hostnames are matched before the wildcard.
- NGINX: the HTTP-01 issuers this chart creates can’t issue wildcard certificates. Create the
GitHub integration (optional)
This lets users push App Builder apps to GitHub repositories.- Create a GitHub App.
-
Create a Kubernetes secret from its private key:
-
Configure the chart:
agenticCodingGithubAppPrivateKeyPath takes the name of the Kubernetes secret, not a file path. The chart mounts the secret and points the app at the key file.Sandbox sizing and lifecycle
sandboxConfig. For per-value details and the Box resource settings, see the configuration reference.
AGENTIC_CODING_CUSTOM_TOOLS_ENABLED and AGENTIC_CODING_SECURITY_SCAN_ENABLED, aren’t exposed as chart values yet. They default to on.Private image registry
To pull images from a private registry, create a docker-registry secret in the platform namespace and set:<component>.<component>.image, for example server.server.image.repository and server.server.image.tag.
Upgrading
helm.sh/resource-policy: keep, so Helm never deletes it on upgrade or uninstall.
Upgrading from the multiwoven chart
The chart was renamed frommultiwoven to aisquared in 0.117.0, and its values keys were renamed. Version 0.118.0 also changed several defaults. To upgrade an existing installation in place:
Keep your resource names
nameOverride: multiwoven. Without it, every resource is recreated under a new name.Rename your values keys
--reuse-values.Pin the old defaults you relied on
Upgrade
Configuration reference
Every chart value, the environment variable it sets, its default, and the secret group it belongs to are listed in the Helm configuration reference. The chart’svalues.yaml is the source of truth for the version you’re installing.