Advanced configuration
Optional configuration behind the defaults the deployment derives. Nothing on this page is needed for a standard install: the values file in the deployment guide is the supported shape, and everything here overrides a default that already works.
Audience: IT (the enabler)
URLs derived from applicationUrl
applicationUrl is available from application version 3.1.2. It is the address users open the application at: scheme, host, and an optional port, with no path. The chart derives every URL the platform needs about itself from it, so the hostname appears once there and once in your routing, ingress.host or httpRoute.hostnames:
| Key | Derived value |
|---|---|
api.config.auth.webAppUrl | <applicationUrl> |
api.config.auth.allowedOrigins | ["<applicationUrl>"] |
api.config.auth.oidc.redirectUri | <applicationUrl>/api/v1/auth/callback |
api.config.realtime.webhookPublicBaseUrl | <applicationUrl> |
api.config.email.outlook.webhookUrl | <applicationUrl>/api/v1/email/outlook/webhook |
api.config.workspaceApps.gmailPush.verifyAudience | <applicationUrl>/api/v1/webhooks/gmail/push |
Setting any of these keys explicitly replaces the derived value whole. The one to know about is allowedOrigins: an explicit list must include the application origin itself, or requests from the application's own address to the sign-in endpoints are refused.
api:
config:
auth:
allowedOrigins: '["https://<hostname>","https://<second-hostname>"]'An applicationUrl that is not a bare http(s)://host[:port] (a path, query, fragment, or userinfo) fails helm template with a message naming the key. Realtime setup is on by default and needs a public base URL, so a values file with neither applicationUrl nor api.config.realtime.webhookPublicBaseUrl also fails the render, rather than starting pods that cannot boot.
A custom StorageClass for the data root
On AWS (infrastructure.platform: aws in the values file) the deployment creates a default StorageClass for the data root: gp3 on the EBS CSI driver, encrypted with your KMS key, at gp3's baseline performance (3,000 IOPS, 125 MiB/s). Most deployments need nothing else.
On Azure (infrastructure.platform: azure) the default is a Premium SSD (Premium_LRS) class on the Azure Disk CSI driver, encrypted at rest with platform-managed keys.
Its IOPS scale with the disk size, so raising vfs.dataRoot.size also raises performance; see Data root performance.
If you want a class of your own — provisioned IOPS or throughput above the baseline, volume tags, or a class your organization already operates — create one that meets the contract in Storage for the data root and name it in the values file, which suppresses the created default:
vfs:
dataRoot:
storageClassName: <your-class>On platforms where no default is created, this is also how the data root is provisioned in the first place.
Resize semantics, changing the class later, and the trade-offs of the cluster's built-in gp2 class are in the Operations reference. If the class encrypts with a customer-managed KMS key, the EBS CSI driver needs a KMS grant, exactly as for the created default.
On Azure, a class of your own is how you get IOPS and throughput that do not depend on disk size, for example on Premium SSD v2, and how you encrypt the data root with a customer-managed key: the chart-created class names no key, so point your class at a disk encryption set with the Azure Disk CSI driver's diskEncryptionSetID parameter.
Letting the chart create the service account
By default you create the service account for cloud access and set serviceAccount.create: false. To let the chart create it instead, set create: true and give it a name. With EKS Pod Identity, create the association for the application namespace and that name. With IAM roles for service accounts (IRSA), add the role annotation:
serviceAccount:
create: true
name: sema4ai
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account>:role/<role>On Azure, add the workload identity annotation instead, and federate the managed identity with the chart-created account, subject system:serviceaccount:<namespace>:<name>:
serviceAccount:
create: true
name: sema4ai
annotations:
azure.workload.identity/client-id: <identity-client-id>Using your own ingress
Each deployment guide sets up one ingress: an ALB on AWS, and on Azure a Gateway on the AKS application routing add-on's Gateway API implementation, the only ingress configuration we test there. The application does not depend on either. The chart can render a Kubernetes Ingress for any ingress controller, or an HTTPRoute for any Gateway API implementation, and both route the same paths to the same Services.
Whatever serves the application must:
- Terminate TLS for the hostname in
applicationUrl, or sit behind something that does. - Pass WebSocket upgrades on
/api/v1/ws. - Keep idle connections open for up to an hour (3,600 seconds), so WebSocket and streaming connections last the length of an agent run.
- Accept request bodies of at least 200 MiB, the largest file upload.
For an ingress controller, set the class, the hostname, the TLS secret, and the annotations your controller takes for the timeout and the body size.
On Azure, where the chart renders no Ingress by default, also set enabled: true:
ingress:
enabled: true
className: <ingress-class>
host: <hostname>
annotations: {}
tls:
- hosts:
- <hostname>
secretName: <tls-secret>With no className, the class is alb on AWS and webapprouting.kubernetes.azure.com, the application routing add-on's NGINX, on Azure.
For a Gateway API implementation, name the Gateway and its listener, and the hostname.
The Gateway must admit routes from the application namespace.
On any platform other than Azure, also set ingress.enabled: false, or the chart renders an Ingress alongside the route:
httpRoute:
enabled: true
parentRefs:
- name: <gateway>
namespace: <gateway-namespace>
sectionName: <listener>
hostnames:
- <hostname>httpRoute is available from application version 3.1.4.
With enabled: true and no parentRefs, helm template fails with a message naming the key.