Webinar: Better Agents, Easier than Ever — Thursday, June 18th at 9am PT / 12pm ET. Register Now
Version 2.5
Azure AKS

Deploy on Azure AKS

This guide is for the IT lead deploying Sema4.ai self-hosted edition into your Azure AKS environment. It assumes you're comfortable operating AKS — it doesn't cover general Kubernetes administration.

The application is distributed as a Helm chart installed into an existing AKS cluster. A single cluster can run multiple installations, but each must be in its own dedicated namespace.

For a single-VM install with no Kubernetes cluster to manage, see Azure VM instead. Customers with stricter governance or compliance requirements can work with Sema4.ai to design a tailored architecture. A reference Terraform module for Azure is available on request.

Provisioning the infrastructure in the bill of materials moves at the speed of your procurement, network, IAM, and security teams — anywhere from 2 days to 2 weeks. The Sema4.ai install itself is under 90 minutes, and a POC can run the same day.

Part 1 — Pre-deployment bill of materials

Hand this to procurement and your cloud/security teams on Day 0.

Decide these carefully — they're painful to retrofit:

  • Hostname — TLS, OIDC redirect URIs, and ingress all derive from it; changing it later means re-issuing certs and reconfiguring your IdP.
  • Region — moving regions later means a rebuild.

Components

CategoryComponentSpec / SKUNotes
ComputeAKS cluster + dedicated namespaceA node pool with e.g. Standard_D4s_v6 (4 vCPU, 16 GiB) as the minimum node size. The cluster must have the OIDC issuer and Workload Identity enabledHosts the application compute. One application instance per namespace
NetworkCluster ingressAn ingress setup that routes traffic to the Sema4.ai application from end users and API clientsYours to provide and operate. The application serves plain HTTP on port 8001 with a /health/live probe; terminate TLS in your ingress. The application is typically configured with service type ClusterIP or LoadBalancer
NetworkDNS recordHostname for the workspace, e.g. sema4-agents.<customer>.com → the ingress endpoint
DataPostgreSQLAzure DB for PostgreSQL Flexible Server, PG 17+. Low-load: B2s (2 vCPU, 4 GB), 100 GB. Production: DC2ads-v6 (2 vCPU, 8 GB), 100 GBPrimary data storage for the application. Reachable from the cluster; public network access disabled. Allow-list the uuid-ossp extension via the azure.extensions server parameter (plpgsql, also required, is built in). The application enables the extensions itself, so its database user must be able to run CREATE EXTENSION
DataBlob StorageAzure Storage Account, Standard, ZRS, one container for the deployment. A configurable key prefix lets multiple deployments share one containerStores files and data frames. Restrict network access to the cluster's network or a private endpoint
DataKey Vault + RSA KEKAzure Key Vault (Standard), same region as the cluster, with an RSA key (≥2048-bit) with wrapKey and unwrapKey operationsEnvelope encryption of secrets at rest. You provide the versioned key identifier (https://<vault>.vault.azure.net/keys/<name>/<version>) in your values file
IdentityOIDC IdP appApp registration in Entra ID / Okta / Auth0 with redirect URI https://<hostname>/oidc/login/callback, logout URI https://<hostname>/oidc/logout/callback, scopes openid profile email, group claims if access-restrictedDiscovery URL, Client ID, and Client Secret needed at install. See Identity providers (OIDC)
IdentityManaged identity → service accountA user-assigned managed identity with a federated identity credential binding it to the application's Kubernetes service account (Workload Identity (opens in a new tab))Roles: Get / WrapKey / UnwrapKey on the Key Vault KEK + Storage Blob Data Contributor on the storage account
AccessAdministrative Azure & AKS accessSuitable Azure and cluster permissions for the deploying administrator, plus kubectl and helm on their workstationJust-in-time access acceptable
EgressOutbound HTTPSUnrestricted egress recommended. Needed to reach the Sema4.ai services (image + chart pull, licensing, updates) plus your LLMs and MCP serversSee the network endpoints for the Sema4.ai hosts, and Add networking rules

Ingress is your responsibility. The application serves plain HTTP on port 8001 with a /health/live health probe; you expose it with your own ingress controller or load balancer, terminate TLS there, and decide whether it is internet-facing or internal. The values template below ships a generic ingress example — adapt the class, annotations, and service type to your environment. If you use the AKS application routing add-on (managed NGINX), the template includes a commented-out starting point for it, including the TLS certificate sync from Key Vault.

Part 2 — Deployment steps

Step 1: Pick the hostname (foundational)

Decide the hostname (e.g. finance-agents.company.com) on a domain you control — whether it resolves publicly or only internally is your choice. TLS, the OIDC redirect URI, and the ingress configuration all derive from it. You'll point DNS at your ingress endpoint later (Step 7).

Step 2: Register the OIDC application

Register an OIDC application in your identity provider and capture the Discovery URL, Client ID, and Client Secret for your values file. Use:

  • Redirect URI: https://<hostname>/oidc/login/callback
  • Logout URI: https://<hostname>/oidc/logout/callback
  • Scopes: openid, profile, email
  • Authorization code flow with PKCE where supported; restrict to the allowed group(s) if your IdP supports it.

Follow the guide for your provider: Microsoft Entra ID · Auth0 · Okta.

Step 3: Provision Azure infrastructure

Either apply the reference Terraform (available from Sema4.ai on request), or provision yourself via Bicep, ARM, or the portal using the bill of materials as the spec. The end state must include:

  • An AKS cluster with the OIDC issuer and Workload Identity enabled, an ingress controller, and kubectl access configured to that cluster (your AKS admin provides the kubeconfig context — you'll need it for the Helm install). Capture the cluster's OIDC issuer URL (az aks show --query oidcIssuerProfile.issuerUrl).
  • PostgreSQL Flexible Server 17+ with the uuid-ossp and plpgsql extensions available (the application must be able to enable them), reachable from the cluster; capture host, port, and admin credentials.
  • A storage account with one blob container for the deployment (note any key prefix).
  • A Key Vault with an RSA KEK (≥2048-bit, wrapKey/unwrapKey); capture the versioned key identifier (https://<vault>.vault.azure.net/keys/<name>/<version>).
  • A user-assigned managed identity with Get / WrapKey / UnwrapKey on the KEK and Storage Blob Data Contributor on the storage account, plus a federated identity credential with the cluster's OIDC issuer URL and subject system:serviceaccount:<your-namespace>:<service-account-name>. The service account name must match the one in your values file (Step 5) — the chart creates the service account at install. Capture the identity's client ID.

Step 4: Create the application database

The application needs a dedicated database on your PostgreSQL server. Connect to the management database (postgres) with a SQL client and create one:

CREATE DATABASE <database-name>;

Capture the database name and the admin username and password — you'll enter them in your values file.

The application enables the uuid-ossp and plpgsql extensions in this database itself on first start, so the user you provide must be able to run CREATE EXTENSION (an admin user is). On Flexible Server, uuid-ossp must also be allow-listed via the azure.extensions server parameter (per the bill of materials).

Step 5: Prepare your my-values.yaml

Create the values file that configures your deployment before you start the install. Start from this template and replace every REPLACE_ME with your values (the external URL drives the OAuth callback, so it must match the hostname you registered with your IdP; the service account name and namespace must match the federated identity credential). Keep this file — you reuse it for upgrades.

Download my-values-azure-aks.example.yaml
# Helm values for the Sema4.ai Deployment on Azure AKS
#
# Only chart-default overrides and the name-derived/shared-infra fields are
# listed below. The image (registry/repository/tag) comes from the chart — tag
# is supplied via --set on helm install. The Replicated SDK injects the proxy
# pull secret from its license, so no imagePullSecrets entry is needed.
 
# The chart creates the service account. Its name and namespace must match the
# federated identity credential on the user-assigned managed identity, and the
# annotation points at that identity's client ID.
serviceAccount:
  create: true
  name: REPLACE_ME
  annotations:
    azure.workload.identity/client-id: "REPLACE_ME"
 
# Opts the pods into Azure Workload Identity so the application can reach Blob
# Storage and Key Vault with the federated managed identity.
podLabels:
  azure.workload.identity/use: "true"
 
# Ingress is YOUR responsibility: the application serves plain HTTP on port
# 8001 with a /health/live health probe — expose it with your ingress
# controller or load balancer, terminate TLS there, and decide whether it is
# internet-facing or internal. Below is a generic example for an ingress
# controller routing to a ClusterIP service (the chart default is NodePort);
# adapt className, annotations, and the service type to your environment.
service:
  type: ClusterIP
 
ingress:
  enabled: true
  className: REPLACE_ME
  annotations: {}
  hosts:
    - host: "REPLACE_ME"
      paths:
        - path: /
          pathType: Prefix
          port: http
  tls: []
 
# Starting point for the AKS application routing add-on (managed NGINX) —
# replace the generic className/annotations/tls above with these. The
# tls-cert-keyvault-uri annotation syncs the TLS certificate from Key Vault;
# it requires the vault to be attached to the add-on
# (az aks approuting update --attach-kv). The add-on's default NGINX is
# public — for an internal (private) deployment, create an internal
# controller via its NginxIngressController resource and use that class.
#
#  className: webapprouting.kubernetes.azure.com
#  annotations:
#    kubernetes.azure.com/tls-cert-keyvault-uri: "https://<vault>.vault.azure.net/certificates/<name>"
#  tls:
#    - hosts:
#        - "<hostname>"
#      # The add-on syncs the Key Vault certificate into this secret, named
#      # keyvault-<ingress-name>; with the release named 'spar' this is:
#      secretName: keyvault-spar
 
config:
  infrastructurePlatform: "azure"
 
  azure:
    storageAccountName: "REPLACE_ME"
    storageContainerName: "REPLACE_ME"
    blobKeyPrefix: "REPLACE_ME"
    # Versioned Key Vault key identifier of the RSA KEK, in the form
    # https://<vault>.vault.azure.net/keys/<name>/<version>
    keyVaultKeyUrl: "REPLACE_ME"
 
  postgres:
    host: "REPLACE_ME"
    port: "5432"
    user: "REPLACE_ME"
    password: "REPLACE_ME"
    database: "REPLACE_ME"
 
  # Public base URL (drives OAuth callback + MCP public-API base URLs).
  externalUrl: "REPLACE_ME"
 
  # authMode defaults to 'oidc' in the chart.
  workroom:
    # Register redirect URI <externalUrl>/oidc/login/callback with your IdP.
    oidcClientId: "REPLACE_ME"
    oidcClientSecret: "REPLACE_ME"
    oidcServer: "REPLACE_ME"
 
# Installs the Sema4.ai MCP Gallery container
mcpGallery:
  enabled: true

Step 6: Install the application with Helm

Before you start, make sure your Azure CLI session and kubectl context point at the target AKS cluster — e.g. authenticate (az login) and run az aks get-credentials --resource-group <rg> --name <cluster>. Otherwise the install fails with a cluster-reachability error.

Get the install details from the Sema4.ai Enterprise portal (opens in a new tab). You'll receive an email invitation — activate your account, then sign in. Your Team is your organization; if the same email is used for several self-hosted deployments, switch between them with the Team dropdown.

Go to Install and choose Helm. In step 1:

  • Instance Name — a label for the deployment in the portal tooling.
  • Kubernetes Distribution — choose Azure AKS.
  • Cluster Network Availability and Registry Access — choose the options that match your local setup (whether outbound requests are allowed or go through an HTTPS proxy, and whether your workstation can reach the cluster as well as the registry).

Then click Continue.

The Instance Name is only a label in the portal tooling — it is not the deployment's hostname or subdomain. The hostname is the one you chose in Step 1.

In step 2, the portal walks you through the install:

  1. Select a version.

  2. Export credentials and log in with the commands shown:

    export AUTH_TOKEN=<token from the portal>
    helm registry login registry.sema4.ai --username <your-email> --password $AUTH_TOKEN
  3. Skip "Create values override file" — you already prepared my-values.yaml in Step 5.

  4. Skip "Install preflight plugin" — it isn't needed for this install.

  5. Install the chart. Take the helm install command from the portal, point --values at your file, and add your namespace:

    helm install spar oci://registry.sema4.ai/sema4ai/prod-selfhosted/spar \
      --version <version> \
      --values my-values.yaml \
      --namespace <your-namespace>

The command you copy from the portal omits the namespace — append --namespace <your-namespace> yourself.

Step 7: Point DNS at your ingress

Point your hostname at whatever endpoint exposes the application — this depends on your ingress controller (the application routing add-on's public IP, an Application Gateway, an existing gateway, etc.), so the exact target and record type are yours to determine. Create the DNS record in your DNS provider (for example, Azure DNS) resolving the hostname to that endpoint. Sign-in won't complete until the hostname resolves and TLS is serving.

Step 8: Validate

  • Browse to https://<hostname> — login should redirect to your IdP.
  • Sign in with a permitted user; you should land in the Sema4.ai workspace.
  • Run a smoke-test agent to confirm the data plane (Postgres, Blob).

Keep your my-values.yaml — you reuse it for upgrades. See Update the Sema4.ai application.

Next steps

With the application running, continue to First-time setup to connect LLMs, set up MCP OAuth, and configure the rest of the workspace.