Skip to content

Self-hosted Okahu

Self-hosted Okahu installs the Okahu control plane inside a Kubernetes cluster that you operate. The control plane, the trace store, the evaluation service, and the portal UI all run as workloads inside your cluster. Okahu provides the installer artifact and the container images; your infrastructure runs them. Contact Okahu to receive the installer bundle and the registry credentials needed to pull images.

Deployment options

Three deployment paths are supported. Pick the one that matches how much of the surrounding infrastructure you want Okahu's tooling to create for you.

Option What it does Cloud support Who it is for
1. Kubernetes deployment only Runs the installer against an existing Kubernetes cluster, Postgres database, and Azure OpenAI resource that you already own. Any Kubernetes distribution that can provision a public LoadBalancer service, including Azure AKS, AWS EKS, Google GKE, and on-premises distributions. Teams that already run production Kubernetes and want to install the Okahu workloads without changing their platform.
2. Full cloud-automated deploy A set of wrapper scripts creates the cloud resources (resource group, Kubernetes cluster, Postgres server, Azure OpenAI resource, container registry), runs the installer, and writes a state file that later operations scripts read. Azure AKS today. AWS EKS and Google GKE are planned. Teams that want a single-command install and do not already have Kubernetes, Postgres, or Azure OpenAI provisioned.
3. Agentic install A coding agent such as Claude Code or OpenAI Codex drives the Option 2 scripts on your behalf and keeps watch over the install log. Same cloud support as Option 2. Teams that already operate their infrastructure through a coding agent and want the agent to perform the install.

What Okahu provides

The following artifacts and credentials are delivered when you contact Okahu. The exact set depends on the deployment option you select.

Two tarballs are referenced throughout the sections below, and the relationship between them matters:

  • Install bundle okahu-standalone-<version>.tar.gz is the file that install.sh ships inside. Option 1 uses the install bundle directly.
  • Option 2 installer tarball okahu-standalone-installer-<version>.tar.gz is a superset. It contains the install bundle under bundle/, plus the Okahu-written Azure provisioning and operations scripts under scripts/, plus a config.example.yaml template. Option 2 and Option 3 use the installer tarball.

A customer installing with Option 2 or Option 3 does not need the install bundle separately; it is embedded in the installer tarball they receive.

For every option

Artifact Description
Install bundle okahu-standalone-<version>.tar.gz Archive containing install.sh, the per-chart Helm values files, the KubeRay cluster manifest, the Postgres schema bootstrap Job, and the installer README. This is the content Option 1 operates on directly, and is embedded inside the Option 2 installer tarball.
Image access (one of two paths) The container images that back the install have to come from somewhere the cluster can reach. Two paths are supported, and both are first-class. (a) Pull from the Okahu-hosted registry. Okahu issues a registry username and token that install.sh writes into the okahu-registry imagePullSecret. (b) Pull from your own registry. You mirror the images into a registry you already run (Azure Container Registry, Amazon ECR, Harbor, Quay, Nexus, GCP Artifact Registry) and point install.sh at that registry with OKAHU_REGISTRY_HOST. For Azure AKS, the ACR path is often the simpler one because AKS can pull from an attached ACR using its managed identity, with no imagePullSecret and no long-lived token to rotate. Okahu provides the image archives for the mirror; see Additional artifacts for a private-registry install.

Additional artifacts for Option 2

Artifact Description
Option 2 installer tarball okahu-standalone-installer-<version>.tar.gz Archive containing the install bundle above, the Azure provisioning and operations scripts (full-deploy.sh, preflight-setup.sh, deploy.sh, test.sh, status.sh, redeploy.sh, rotate-secret.sh, teardown.sh, troubleshoot.sh, lib.sh), and a config.example.yaml template.
release.tag value Pins the backend chart and image version to a release Okahu has validated against the installer bundle. Goes into the release.tag field of your YAML configuration.
portal_ux.image_tag value Pins the portal UI image to a known-good tag. The default latest tag is not recommended for production because it moves on every build. Goes into the portal_ux.image_tag field of your YAML configuration.
portal_ux.source_registry value The source container reference that the deploy.sh script imports the pinned portal UI image from into your per-cluster Azure Container Registry. Goes into the portal_ux.source_registry field of your YAML configuration.

Additional artifacts for Option 3

Artifact Description
Private Claude Code plugin Marketplace reference and install one-liner for the Okahu-maintained plugin that packages the Option 2 scripts as Claude Code skills, exposing /ok-full-deploy, /ok-deploy-aks, and /ok-preflight-setup. Delivered to teams that use Claude Code.
Agent-specific instructions For OpenAI Codex CLI or another shell-driving coding agent, Okahu provides the Option 2 installer tarball plus a short reference prompt that the agent uses to run full-deploy.sh and interpret the install log.

Additional artifacts for a private-registry install

The artifacts below apply whenever install.sh pulls from a registry you operate, rather than from the Okahu-hosted registry. Common cases include an Azure Container Registry attached to the AKS cluster, Amazon ECR, Harbor, Quay, Nexus, GCP Artifact Registry, or any registry inside an air-gapped network perimeter. The default install path does not need these artifacts.

Artifact Description
Pre-pulled container images A set of OCI image archives for every chart in the release, suitable for docker load, skopeo copy, az acr import, or aws ecr-public batch-copy-image. You push them into your registry under the paths install.sh expects.
Chart archives The Helm chart .tgz files for every release component, so install.sh can resolve charts from a local path instead of the public OCI registry.
Mirror-aware installer bundle A copy of the install bundle whose install.sh honors OKAHU_REGISTRY_HOST pointed at your internal registry, so no pod attempts an outbound image pull.

Loading images into Azure Container Registry

The 11 Okahu container images and 11 Helm charts need to be mirrored into the ACR before install.sh runs. Two paths are supported depending on whether the ACR can reach the Okahu-hosted registry at mirror time.

Path 1: az acr import (ACR has temporary Internet access to Okahu's registry)

Azure performs the copy from Okahu's registry to your ACR through its control plane, so the operator's machine does not need to pull the images locally. The ACR itself needs outbound connectivity to the Okahu-hosted registry for the duration of the import. The AKS cluster can then be fully air-gapped afterward.

export ACR=myacr                              # Your Azure Container Registry name
export OKAHU_REGISTRY_USER=<supplied by Okahu>
export OKAHU_REGISTRY_TOKEN=<supplied by Okahu>
export RELEASE_TAG=<supplied by Okahu>        # Backend chart and image version
export PORTAL_UX_TAG=<supplied by Okahu>      # portal-ux image tag
export PORTAL_UX_CHART=<supplied by Okahu>    # portal-ux chart version

# Backend images (10 total)
for svc in okahu-data okahu-eval-api okahu-graphs okahu-ingestion okahu-mcp \
           okahu-ml-analysis okahu-provisioning okahu-scheduler okahu-sre-agent okahu-ray; do
  az acr import --name "$ACR" \
    --source "okahu.jfrog.io/containers/okahu-cloud/standalone/${svc}:${RELEASE_TAG}" \
    --image  "containers/okahu-cloud/standalone/${svc}:${RELEASE_TAG}" \
    --username "$OKAHU_REGISTRY_USER" --password "$OKAHU_REGISTRY_TOKEN"
done

# portal-ux image (eleventh, carries its own tag)
az acr import --name "$ACR" \
  --source "okahu.jfrog.io/containers/okahu-cloud/standalone/portal-ux:${PORTAL_UX_TAG}" \
  --image  "containers/okahu-cloud/standalone/portal-ux:${PORTAL_UX_TAG}" \
  --username "$OKAHU_REGISTRY_USER" --password "$OKAHU_REGISTRY_TOKEN"

# Helm charts, 10 at the release tag plus portal-ux at its own chart version
helm registry login "${ACR}.azurecr.io" \
  --username 00000000-0000-0000-0000-000000000000 \
  --password "$(az acr login --name "$ACR" --expose-token --output tsv --query accessToken)"

mkdir -p ./charts
for chart in okahu-shared okahu-data okahu-graphs okahu-ingestion okahu-mcp \
             okahu-ml-analysis okahu-provisioning okahu-scheduler okahu-sre-agent eval-api; do
  helm pull "oci://okahu.jfrog.io/containers/okahu-cloud/charts/${chart}" \
    --version "$RELEASE_TAG" --destination ./charts
  helm push "./charts/${chart}-${RELEASE_TAG}.tgz" \
    "oci://${ACR}.azurecr.io/containers/okahu-cloud/charts"
done

helm pull "oci://okahu.jfrog.io/containers/okahu-cloud/charts/portal-ux" \
  --version "$PORTAL_UX_CHART" --destination ./charts
helm push "./charts/portal-ux-${PORTAL_UX_CHART}.tgz" \
  "oci://${ACR}.azurecr.io/containers/okahu-cloud/charts"

Path 2: OCI archives and skopeo (ACR has no outbound Internet access)

Request the pre-pulled image archives and chart .tgz files from Okahu, transfer them across the air gap, then push into the ACR using skopeo (for images) and helm push (for charts).

# On a connected workstation, transfer /airgap-okahu-release/*.tar and /airgap-okahu-release/charts/*.tgz
# across the air gap. On the air-gapped side with ACR access:

export ACR=myacr
helm registry login "${ACR}.azurecr.io" \
  --username 00000000-0000-0000-0000-000000000000 \
  --password "$(az acr login --name "$ACR" --expose-token --output tsv --query accessToken)"

for img in /airgap-okahu-release/images/*.tar; do
  skopeo copy "oci-archive:${img}" \
    "docker://${ACR}.azurecr.io/containers/okahu-cloud/standalone/$(basename "$img" .tar)"
done

for chart in /airgap-okahu-release/charts/*.tgz; do
  helm push "$chart" "oci://${ACR}.azurecr.io/containers/okahu-cloud/charts"
done

Attach the ACR to AKS so the cluster can pull without an imagePullSecret

az aks update --name <aks-name> --resource-group <rg-name> --attach-acr "$ACR"

With the ACR attached, AKS authenticates to the ACR using its managed identity. The okahu-registry imagePullSecret that install.sh writes is still populated but becomes redundant for the pull itself.

Run install.sh against your ACR

OKAHU_REGISTRY_HOST="${ACR}.azurecr.io" \
OKAHU_REGISTRY_PATH=containers/okahu-cloud \
OKAHU_REGISTRY_USER=00000000-0000-0000-0000-000000000000 \
OKAHU_REGISTRY_TOKEN="$(az acr login --name "$ACR" --expose-token --output tsv --query accessToken)" \
./install.sh \
  --release               "$RELEASE_TAG" \
  --portal-ux-version     "$PORTAL_UX_CHART" \
  --pg-url                "postgresql://..." \
  --azure-openai-endpoint "https://YOUR_AOAI.openai.azure.com/" \
  --azure-openai-key      "$AOAI_KEY" \
  --azure-openai-model    "gpt-4.1"

Upstream dependencies (fully air-gapped only)

The installer also pulls three upstream Helm charts directly from the Internet: Traefik (https://traefik.github.io/charts), cert-manager (https://charts.jetstack.io), and KubeRay (https://ray-project.github.io/kuberay-helm/). A fully air-gapped install needs those three chart archives plus their referenced images mirrored into the ACR as well. Contact Okahu for a mirror-aware installer bundle that bundles the upstream charts and patches install.sh to resolve them locally.

Delivery and support

Okahu CX delivers the artifacts above over a channel agreed with your team (private download link, cloud storage share, or email attachment) and sends a notification when a new version ships. Installation assistance, cleanup commands for trailing state at uninstall time, and support for additional LLM providers are all available through the same channel. Contact Okahu to open the conversation.

Common prerequisites

Every option requires the following four items in addition to the artifacts Okahu provides. Option-specific prerequisites appear in each section below.

  1. Azure OpenAI with a gpt-4.1 deployment at a Standard, GlobalStandard, or DataZoneStandard SKU with sufficient tokens-per-minute capacity for your workload. The installer uses the literal deployment name gpt-4.1 because the evaluation service references the deployment by that exact name.
  2. A Postgres 16 database that the installer can use exclusively. The installer creates schemas and tables inside the database you supply; it does not share tables with another application. Postgres 15 and 14 are not supported.
  3. Local tools on the operator's PATH: kubectl, helm version 3.8 or later for OCI chart support, python3, curl, and tar.
  4. The artifacts listed in What Okahu provides: at minimum the install bundle and image-pull credentials, plus the Option 2 installer tarball and pinned configuration values if you are using Option 2 or 3.

Option 1. Kubernetes deployment only

Option 1 installs the Okahu workloads into a Kubernetes cluster that already exists. You own the cluster, the Postgres server, and the Azure OpenAI resource; the installer deploys only the Okahu workloads, the KubeRay cluster used by the evaluation service, cert-manager if HTTPS is enabled, and the Traefik ingress.

Prerequisites

In addition to the common prerequisites, Option 1 requires:

  • A Kubernetes cluster whose current kubectl context points at the target. The cluster must support provisioning a public LoadBalancer service, because the Traefik ingress acquires a public IP that way.
  • A Postgres 16 database that the installer can reach from inside the cluster, with an administrative user whose connection string is passed to --pg-url.
  • An Azure OpenAI resource whose endpoint, API key, and gpt-4.1 deployment name are known.

Install command

Extract the install bundle and run the installer. The following command installs with the default authentication mode (simple, which configures a shared bearer token):

tar xzf okahu-standalone-<version>.tar.gz
cd okahu-standalone-<version>

./install.sh \
  --pg-url                "postgresql://USER:PASS@YOUR_PG_HOST:5432/DB?sslmode=require" \
  --registry-user         "YOUR_REGISTRY_USERNAME" \
  --registry-token        "YOUR_REGISTRY_TOKEN" \
  --azure-openai-endpoint "https://YOUR_AOAI.openai.azure.com/" \
  --azure-openai-key      "YOUR_AOAI_KEY" \
  --azure-openai-model    "gpt-4.1"

When the installer finishes, it prints the LoadBalancer address, the tenant identifier, the shared authentication token (for simple mode), and the first API key. Save that information. The API key is stored only as a hash, so a subsequent re-run cannot display the plaintext value a second time.

Enabling HTTPS and Entra ID sign-in

To expose the portal over HTTPS with a Let's Encrypt certificate, and to require Microsoft Entra ID sign-in rather than a shared bearer token, add the following flags to the install command.

./install.sh \
  --pg-url                "postgresql://USER:PASS@YOUR_PG_HOST:5432/DB?sslmode=require" \
  --registry-user         "YOUR_REGISTRY_USERNAME" \
  --registry-token        "YOUR_REGISTRY_TOKEN" \
  --azure-openai-endpoint "https://YOUR_AOAI.openai.azure.com/" \
  --azure-openai-key      "YOUR_AOAI_KEY" \
  --azure-openai-model    "gpt-4.1" \
  --hostname              "okahu.your-domain.example" \
  --acme-email            "ops@your-company.example" \
  --auth-provider         entra \
  --azure-ad-tenant-id    "YOUR_ENTRA_TENANT_ID" \
  --azure-ad-client-id    "YOUR_ENTRA_APP_CLIENT_ID"

Each new flag has a specific purpose. The following table explains why each one is required.

Flag Purpose
--hostname Declares the public DNS name that the portal and APIs will serve under. The installer uses this value to request a Let's Encrypt certificate through cert-manager, to configure the Traefik router rules, and to construct the default Entra redirect URI. The DNS name must resolve to the LoadBalancer's public IP before the installer runs; the ACME HTTP challenge fails otherwise.
--acme-email Registers an ACME account with Let's Encrypt. Let's Encrypt uses the address for certificate expiry notifications and policy announcements. The flag is required whenever --hostname is supplied, because every Let's Encrypt account must have a registered contact.
--auth-provider entra Switches the control plane and the portal UI from the default shared-bearer mode to Microsoft Entra ID. In Entra mode, each user signs in individually, the portal exchanges the authorization code for access tokens through MSAL, and the backend services validate the tokens against Entra.
--azure-ad-tenant-id Identifies the Entra directory (tenant) that owns the app registration. The backend services use the tenant GUID to look up the signing keys that validate incoming access tokens.
--azure-ad-client-id Identifies the Entra app registration that the portal uses to sign users in. The portal sends this value to Entra as the OAuth 2.0 client_id parameter, and the backend services use it to validate the aud claim on every access token.

Every install.sh flag

The complete flag set is listed below. Flags marked Required must be supplied either on the command line or through the matching environment variable. All others have working defaults.

Required

Flag Environment variable Description
--pg-url URL OKAHU_PG_URL Postgres connection string. The database must be exclusive to Okahu.
--registry-user U OKAHU_REGISTRY_USER Username issued by Okahu for pulling container images.
--registry-token T OKAHU_REGISTRY_TOKEN Token issued by Okahu for pulling container images.
--azure-openai-endpoint URL OKAHU_AZURE_OPENAI_ENDPOINT Base URL of the Azure OpenAI resource.
--azure-openai-key K OKAHU_AZURE_OPENAI_KEY API key for the Azure OpenAI resource.
--azure-openai-model M OKAHU_AZURE_OPENAI_MODEL Name of the Azure OpenAI deployment. Set to gpt-4.1.

Versioning

Flag Environment variable Description
--release V OKAHU_RELEASE Pins the Okahu chart and image version. Defaults to the newest stable release.
--portal-ux-version V OKAHU_PORTAL_UX_CHART_VERSION Pins the portal-ux chart version. Defaults to the newest stable release.

Authentication

Flag Environment variable Description
--auth-provider P OKAHU_AUTH_PROVIDER Selects simple (default, shared bearer token) or entra (Microsoft Entra ID sign-in).
--simple-auth-secret S OKAHU_SIMPLE_AUTH_SECRET Simple mode only. The shared bearer token value. Generated when omitted; reused across re-runs.
--simple-auth-email E OKAHU_SIMPLE_AUTH_EMAIL Simple mode only. The administrator email recorded on the first tenant. Default: admin@okahu.local.
--azure-ad-tenant-id G OKAHU_AZURE_AD_TENANT_ID Entra mode only. Directory (tenant) GUID.
--azure-ad-client-id G OKAHU_AZURE_AD_CLIENT_ID Entra mode only. App registration client GUID.
--azure-ad-authority-host H OKAHU_AZURE_AD_AUTHORITY_HOST Entra mode only. OAuth authority hostname. Default: login.microsoftonline.com.
--admin-token T OKAHU_ADMIN_TOKEN Entra mode only. An administrator's Entra access token used by the installer for the tenant-create and API-key-mint bootstrap calls.
--azure-redirect-uri U OKAHU_AZURE_REDIRECT_URI Entra mode only. The exact redirect URI registered on the app. Defaults to https://<hostname>/en.
--skip-entra-app-update OKAHU_SKIP_ENTRA_APP_UPDATE Entra mode only. Set when the operator does not have permission to update the app registration; the operator must register the redirect URI manually.

HTTPS and DNS

Flag Environment variable Description
--hostname H OKAHU_HOSTNAME Public DNS name. Enables HTTPS and a Let's Encrypt certificate. Required when --auth-provider is entra.
--acme-email E OKAHU_ACME_EMAIL Contact address for the ACME account. Required whenever --hostname is set.
--acme-server U OKAHU_ACME_SERVER ACME endpoint. Default: Let's Encrypt production.
--dns-label L OKAHU_DNS_LABEL Azure only. Asks AKS to assign this DNS label to the LoadBalancer's public IP, so the installer can derive a <label>.<region>.cloudapp.azure.com hostname.

Tenancy

Flag Environment variable Description
--okahu-tenant-id T OKAHU_TENANT_ID Pins the tenant the services resolve to. Required only when the database holds more than one tenant.
--tenant-display-name N OKAHU_TENANT_DISPLAY_NAME Display name for the first tenant. Default: Okahu.

Workloads and cluster

Flag Environment variable Description
--namespace NS OKAHU_NAMESPACE Kubernetes namespace for the main Okahu workloads. Default: okahu.
--ray-namespace NS OKAHU_RAY_NAMESPACE Kubernetes namespace for the KubeRay cluster used by the evaluation service. Default: okahu-ray.
--ray-cluster-name N OKAHU_RAY_CLUSTER_NAME Name of the RayCluster resource. Default: okahu-eval-raycluster.
--ray-workers N OKAHU_RAY_WORKERS Number of Ray worker pods. Default: 2.
--kubeconfig PATH KUBECONFIG Path to the kubeconfig file. Default: the current context.
--azure-api-version V OKAHU_AZURE_API_VERSION Azure OpenAI API version. Default: 2024-10-21. The value must match a version supported by your Azure OpenAI resource.

Option 2. Full cloud-automated deploy

Option 2 creates the surrounding cloud resources (resource group, Kubernetes cluster, Postgres server, Azure OpenAI resource, container registry) and then runs the installer with the correct arguments. The entry point reads a single YAML configuration file so that re-runs are deterministic and version-controllable.

2a. Azure AKS

Option 2a provisions an Azure AKS cluster, an Azure Database for PostgreSQL Flexible Server, an Azure OpenAI resource with a gpt-4.1 deployment, and an Azure Container Registry attached to the cluster. The entry point runs the installer and writes a .env.<prefix> file that other operations scripts consume.

Prerequisites

In addition to the common prerequisites, Option 2a requires:

  • An Azure subscription on which the operator has the Owner or Contributor role.
  • The Azure CLI (az) version 2.56 or later, logged in with az login and set to the target subscription with az account set --subscription <id>.
  • Permission to update Entra app registrations (the Application.ReadWrite.All Microsoft Graph permission, or equivalent through the Cloud Application Administrator role). The installer uses this permission to add the portal's redirect URI to the app registration.
  • The pyyaml Python package installed, so that the entry point can parse the YAML configuration.
  • Sufficient quota in the target region for a Standard_D4s_v5 node pool (at least 12 vCPUs) and for the gpt-4.1 Azure OpenAI SKU you selected.

Install bundle layout

The installer archive that Okahu provides for Option 2a has the following layout.

okahu-standalone-installer-<version>/
├── README.md
├── config.example.yaml
├── bundle/                        # install.sh and the Helm values files
├── scripts/
│   ├── full-deploy.sh             # Entry point; runs preflight-setup then deploy
│   ├── preflight-setup.sh         # One-time per Azure subscription and Entra tenant
│   ├── deploy.sh                  # Creates the cloud resources and runs install.sh
│   ├── test.sh                    # 17-case smoke test, with an HTML report
│   ├── status.sh                  # Cluster snapshot
│   ├── redeploy.sh                # Helm upgrade to a new release tag
│   ├── rotate-secret.sh           # Rotates the shared bearer token (simple mode only)
│   ├── teardown.sh                # Deletes the Azure resource group
│   ├── troubleshoot.sh            # Collects a diagnostic bundle
│   └── lib.sh
└── config/                        # Where operator-written YAML configurations live

Install command

tar xzf okahu-standalone-installer-<version>.tar.gz
cd okahu-standalone-installer-<version>

cp config.example.yaml config/prod.yaml
# Edit config/prod.yaml. Set prefix, hostname, dns_label, redirect_uri,
# auth.entra.tenant_id, auth.entra.client_id, portal_ux values, and release.

./scripts/full-deploy.sh --config config/prod.yaml

The entry point completes in approximately 25 minutes. On success, it writes .env.prod with the LoadBalancer address, tenant identifier, API key, and the names of every Azure resource it created.

Configuration schema

Each key in the configuration file maps to one or more environment variables that the underlying installer and scripts read. The schema is as follows.

prefix: prod                                                     # Used as the prefix for every Azure resource name
region: eastus                                                   # Azure region for every resource

aks:
  node_count: 3                                                  # Node count for the system node pool
  node_sku: Standard_D4s_v5                                      # VM size for the system node pool

auth:
  provider: entra                                                # Either "entra" or "simple"
  hostname: prod-okahu.eastus.cloudapp.azure.com                 # Public DNS name. See the hostname flag description below.
  dns_label: prod-okahu                                          # Label assigned to the LoadBalancer public IP so Azure assigns the above hostname
  acme_email: ops@your-company.example                           # Let's Encrypt contact
  acme_server: https://acme-v02.api.letsencrypt.org/directory    # ACME endpoint; defaults to Let's Encrypt production
  redirect_uri: https://prod-okahu.eastus.cloudapp.azure.com/en  # Entra app redirect URI
  entra:
    tenant_id: YOUR_ENTRA_TENANT_ID                              # Directory (tenant) GUID
    client_id: YOUR_ENTRA_APP_CLIENT_ID                          # App registration client GUID

portal_ux:
  acr_name: prodokahuacr                                         # Azure Container Registry name
  image_repo: prodokahuacr.azurecr.io/portal-ux                  # Pinned portal-ux image repository
  image_tag: <image tag supplied by Okahu>                       # Pinned portal-ux image tag
  source_registry: <mirror source supplied by Okahu>             # Source registry that the deploy script imports the portal-ux image from

release:
  tag: <release tag supplied by Okahu>                           # Pins the backend chart and image version

To add a second cluster, copy the YAML file and change the prefix, acr_name, hostname, dns_label, and redirect_uri values.

Operations

The operations scripts listed below are part of the Option 2a installer tarball that Okahu provides. They are not part of the upstream install.sh bundle used by Option 1; they are wrappers that Okahu ships specifically to automate the lifecycle of a cloud-automated deploy. Each script reads the same YAML configuration file.

./scripts/test.sh           --config config/prod.yaml
./scripts/status.sh         --config config/prod.yaml
./scripts/redeploy.sh       --config config/prod.yaml
./scripts/rotate-secret.sh  --config config/prod.yaml
./scripts/teardown.sh       --config config/prod.yaml --yes
Script What it does When to run it
test.sh Runs a 17-case smoke test suite against the live cluster: health endpoints for every service, a positive and negative authentication check, a tenant and API-key readback, an ingest round-trip, and a Kubernetes readiness probe. Writes a timestamped HTML report under logs/ and opens it in the operator's default browser. After every install, after every redeploy, and whenever a cluster behavior needs a quick confirmation.
status.sh Prints a snapshot of the cluster: namespaces, deployments and their replica counts, the Traefik LoadBalancer address, the RayCluster state, and the Postgres server state. Read-only. When investigating cluster health between tests.
redeploy.sh Re-runs install.sh against the existing cluster, skipping all Azure provisioning. Used to upgrade the Okahu release tag by setting a new release.tag in the configuration, to re-apply a changed Helm values override, or to recover from a partial install. When upgrading to a new release, when a chart value changes, or when install.sh left a release in a half-applied state.
rotate-secret.sh Simple authentication mode only. Generates a new 32-character shared bearer token, patches the okahu-secrets Kubernetes Secret, and triggers a rolling restart of every backend deployment so pods pick up the new value. Updates .env.<prefix> with the new token. Tenant API keys (the okh_… values) are not affected by rotation. Entra authentication mode has no shared token to rotate; access tokens are issued per user by Microsoft Entra. The same rotation can be performed by passing --simple-auth-secret <new-value> to install.sh (or exporting OKAHU_SIMPLE_AUTH_SECRET before redeploy.sh); the installer detects the change, updates the Secret, and restarts the pods on its own. The rotate-secret.sh wrapper is the single-command convenience path for the same operation. At the operator's rotation cadence for the simple provider, or when the shared token may have been exposed.
teardown.sh Deletes the Azure resource group, which cascades the AKS cluster, Postgres server, Azure OpenAI resource, and container registry. Moves .env.<prefix> aside so later scripts do not treat the cluster as live. The --yes flag skips the interactive confirmation prompt. When decommissioning a cluster.

2b. AWS EKS

Support for AWS EKS is planned and not yet available. Contact Okahu to register interest; this signals demand and helps prioritize the work. In the meantime, teams on EKS can use Option 1 today by provisioning the EKS cluster, Postgres database, and Azure OpenAI resource themselves and then running install.sh directly.

2c. Google GKE

Support for Google GKE is planned and not yet available. Contact Okahu to register interest. Teams on GKE can use Option 1 today using the same approach as EKS.

Option 3. Agentic install

Option 3 is the same deploy as Option 2, driven by a coding agent instead of a human operator. The agent reads the YAML configuration, runs the scripts, watches the deploy log, and surfaces errors in context.

The scripts contain no LLM calls. The agent operates above the scripts, driving them from the shell; the scripts themselves are deterministic bash plus az, kubectl, helm, curl, and python3.

Claude Code

Okahu provides a private Claude Code plugin that packages the Option 2 scripts as Claude Code skills. The plugin exposes three slash commands: /ok-full-deploy, /ok-deploy-aks, and /ok-preflight-setup. Contact Okahu to request access and installation instructions.

OpenAI Codex CLI and other coding agents

Any agent that can run shell commands can drive the Option 2 scripts without additional packaging. Install the Option 2 installer bundle on the agent's host, then point the agent at ./scripts/full-deploy.sh --config config/<prefix>.yaml. The agent needs read access to the configuration file, write access to the working directory for log files, and the same Azure, Entra, and Kubernetes credentials that an operator would use.

Limitations

LLM provider

Azure OpenAI with a gpt-4.1 deployment is required today. Direct OpenAI, Amazon Bedrock, and Anthropic are not supported. Contact Okahu if another provider is required for your deployment.

Cloud coverage

Option 2 supports Azure AKS today. AWS EKS and Google GKE are planned. Option 1 runs on any Kubernetes distribution and can be used on EKS and GKE now.

Private-registry and air-gapped environments

The installer supports pulling images from any registry you operate, not only the Okahu-hosted registry. Set OKAHU_REGISTRY_HOST to the hostname of your own registry (for example <name>.azurecr.io, <accountid>.dkr.ecr.<region>.amazonaws.com, or your Harbor instance), import the images Okahu provides, and the install runs with no outbound dependency on the Okahu registry. This is a common choice for enterprises that require every production image to live inside their own control plane, whether or not the cluster is air-gapped. Contact Okahu to arrange a shipment of pre-pulled images and chart archives.

Versioning and upgrades

Each install is pinned to the bundle version that the operator downloaded. Okahu notifies you when a new bundle is published. To upgrade an Option 2 install, edit the release.tag value in the configuration file and run ./scripts/redeploy.sh --config config/prod.yaml. To upgrade an Option 1 install, pass --release <new-version> to install.sh.

Uninstall completeness

The teardown script deletes the Azure resource group, which cascades the AKS cluster, the Postgres server, the Azure OpenAI resource, and the container registry. Three artifacts are not removed and must be cleaned up separately if a zero-trailing-state uninstall is required:

  • The Entra app registration redirect URI that the installer added. Remove it in the Azure Portal under App registrations → Authentication → Single-page application, or contact Okahu for the cleanup command.
  • The Azure point-in-time Postgres backups, which Azure retains per the server's retention policy. Delete them in the Azure Portal if you want them removed.
  • The local kubectl context, cluster, and user entries, which remain in ~/.kube/config. Remove them with kubectl config delete-context, kubectl config delete-cluster, and kubectl config delete-user.

Support

Contact Okahu for the installer bundle, image-pull credentials, air-gapped shipments, support for additional LLM providers, and installation assistance.