Autonomize · Genesis Downloads

Genesis Downloads · Install guide

Install Genesis — from zero to ready

End-to-end CLI runbook for an air-gapped customer cluster. Two Zarf bundles, one license key, twelve steps. Images go into your registry first — your scanner clears them before a single pod runs. Vendor side never reaches in; everything runs in your VPC.


What you'll need

License key

Issued by Autonomize. Format sk_yourorg_*. Used by the genesis CLI to authenticate to the download portal.

Gap-host

Linux (Ubuntu 22.04+) bastion with one-way internet access to downloads.genesis.autonomize.ai. Also needs kubectl access to your cluster. Needs: pipx, cosign, zarf, kubectl, skopeo (or az for ACR).

Customer image registry

ECR / ACR / Harbor or equivalent. genesis push-images relocates every Genesis image here before any deploy. Your CISO scanner runs against your registry, not ours.

Customer cluster prereqs

Kubernetes 1.28+, PostgreSQL 14+, Redis 7+, cert-manager, ESO, Ingress, DNS, TLS cert. Full list: Prerequisites checklist.


CLI install — step by step

The CLI path is the standard path for technical operators. No wizard, no port-forward, fully scriptable.

Pick your host type — every step below switches to match. Air-gapped pulls all tools from the signed portal bundle; connected uses public installers.

Where this page ends This guide is authoritative for the online phase you run from the internet-facing gap-host — bootstrap, pull, verify, scan, and push-images. The cluster-side steps (configure, preflight, deploy, operate, troubleshoot) are covered in depth by the runbooks that ship inside your bundleinstall-from-zero.md and the golden runbooks under docs/customer/. Steps 8–12 below are a condensed cluster-side overview; the bundled runbooks are the full reference.

Prefer GitOps or can't use Zarf? The platform bundle can also be deployed via an ArgoCD Application or plain Helm — see Deployment models for the ArgoCD/GitOps hybrid, the CRD pre-apply workaround, and the Helm-only path. (The ops bundle is always deployed imperatively; only the platform bundle supports these alternatives.)

  1. 01
    Bootstrap gap-host toolchain.

    Genesis shells out to cosign, zstd, tar, skopeo, helm, kubectl, zarf (+ zarf-init), kubelogin, and the trivy CVE DB. On an air-gapped host these are unreachable from GitHub / dl.k8s.io / raw.githubusercontent.com — Genesis publishes them as one cosign-signed tool bundle that genesis pull --tools downloads and verifies (audit A3/A5/A8).

    # Minimal OS packages (from your internal apt mirror if offline)
    sudo apt-get install -y curl jq zstd tar python3-pip pipx skopeo
    
    # cosign — the one binary needed to verify the wheels + tool bundle.
    # Pull it from your internal mirror (it is ALSO inside the tool bundle).
    # … then install the genesis CLI (step 2) and log in (step 3), and:
    genesis pull --tools                        # writes ./tools/<os-arch>/
    # zarf + zarf-init, helm, kubectl, kubelogin, cosign, trivy CVE DB —
    # each verified against a cosign-signed SHA256SUMS. No GitHub, no internet.
    export PATH="$PWD/tools/linux-amd64:$PATH"  # or install them onto PATH
    
    pipx ensurepath && exec $SHELL -l
    # Connected setup host only — public sources (NOT reachable air-gapped).
    sudo apt-get install -y curl jq zstd tar python3-pip pipx skopeo unzip
    
    COSIGN_VER=2.4.1
    curl -fsSL https://github.com/sigstore/cosign/releases/download/v${COSIGN_VER}/cosign-linux-amd64 \
      -o /tmp/cosign && sudo install /tmp/cosign /usr/local/bin/cosign
    curl -fsSL "https://dl.k8s.io/release/$(curl -sSL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \
      -o /tmp/kubectl && sudo install /tmp/kubectl /usr/local/bin/kubectl
    ZARF_VER=v0.75.1
    curl -fsSL https://github.com/defenseunicorns/zarf/releases/download/${ZARF_VER}/zarf_${ZARF_VER}_Linux_amd64 \
      -o /tmp/zarf && sudo install /tmp/zarf /usr/local/bin/zarf
    KUBELOGIN_VER=v0.2.12
    curl -fsSL -O https://github.com/Azure/kubelogin/releases/download/${KUBELOGIN_VER}/kubelogin-linux-amd64.zip
    unzip kubelogin-linux-amd64.zip && sudo install bin/linux_amd64/kubelogin /usr/local/bin/kubelogin
    curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
    
    pipx ensurepath && exec $SHELL -l
  2. 01b
    Connect to the cluster.

    The cluster-side host needs a working cluster-admin kubeconfig pointed at your cluster. On an air-gapped host, this kubeconfig is pre-provisioned by whoever owns the cluster (it does not require internet); the az login flow below is for connected setup hosts only — az login reaches Azure AD and will not work air-gapped.

    # Connected setup host (reaches Azure AD) — produces a kubeconfig you can
    # then carry to the gap-host. Air-gapped hosts: use the pre-provisioned one.
    az login
    az account set --subscription <subscription-id>
    az aks get-credentials --resource-group <rg-name> --name <cluster-name> --overwrite-existing
    # AKS + AAD: convert to a non-interactive auth mode kubectl/helm can use
    kubelogin convert-kubeconfig -l azurecli
    
    kubectl get nodes          # confirm connectivity + cluster-admin
  3. 02
    Install the genesis CLI from the portal (cosign-verified).

    The CLI ships as a signed Python wheel plus a dependency wheelhouse (third-party deps as pre-built linux-amd64 wheels). Verification uses the same cosign key as the bundles. No PyPI access needed — everything downloads from the portal.

    VER=3.6.3       # replace with your entitled version (see `genesis releases`)
    BASE=https://downloads.genesis.autonomize.ai/cli/${VER}
    
    mkdir ~/cli-install && cd ~/cli-install
    curl -sSLO ${BASE}/genesis_cli-${VER}-py3-none-any.whl
    curl -sSLO ${BASE}/genesis_platform_config-${VER}-py3-none-any.whl
    curl -sSLO ${BASE}/genesis_cli_wheelhouse-${VER}-linux-amd64.tar.gz
    curl -sSLO ${BASE}/SHA256SUMS
    curl -sSLO ${BASE}/SHA256SUMS.sig
    curl -sSLO https://downloads.genesis.autonomize.ai/cli/cosign.pub
    
    # Verify the integrity manifest signature
    cosign verify-blob \
      --key cosign.pub \
      --signature SHA256SUMS.sig \
      --insecure-ignore-tlog \
      SHA256SUMS
    
    # Verify wheel bytes against the signed manifest
    sha256sum -c SHA256SUMS --ignore-missing
    
    # Install — wheels + wheelhouse resolve everything locally, no PyPI
    tar -xzf genesis_cli_wheelhouse-${VER}-linux-amd64.tar.gz   # → ./wheelhouse/
    pipx install --pip-args="--find-links=. --find-links=wheelhouse --no-index" "./genesis_cli-${VER}-py3-none-any.whl"
    genesis --version
  4. 03
    Authenticate with your license key.
    genesis login          # paste sk_yourorg_*
    genesis whoami         # prints your customer slug + entitled channels
    genesis releases       # lists available versions

    If genesis login hangs after you paste the key (headless Linux only):

    1. Cancel the hung command with Ctrl+C.
    2. Tell the CLI to skip the system keyring for this shell and persist it for future shells:
      echo 'export PYTHON_KEYRING_BACKEND=keyring.backends.fail.Keyring' >> ~/.bashrc
      source ~/.bashrc
    3. Re-run genesis login. It returns in ~2 seconds and prints stored via ~/.genesis/creds instead of stored via keyring.

    Why this happens. The CLI prefers the OS keyring (Keychain on macOS, gnome-keyring/kwallet on Linux desktops). A bare Linux server has no desktop session, so the Python keyring library blocks waiting for a D-Bus reply that never comes. The env var above tells keyring to fail immediately; the CLI then writes the key to ~/.genesis/creds (mode 0600, owner-only) — the documented headless-host path.

  5. 04
    Pull both bundles.

    Each release publishes an ops bundle (CRDs + operators + agents — stateless) and a platform bundle (Keycloak, APISIX, AI Studio, ~18 services). Both are cosign-signed and ship with a CycloneDX SBOM.

    mkdir ~/bundles && cd ~/bundles
    genesis pull ${VER}
    # Downloads: genesis-ops-${VER}.tar.zst + genesis-platform-${VER}.tar.zst
    #            + .sig sidecars + sbom-${VER}.cdx.json + SHA256 manifests
    ls -lh
  6. 05
    Verify cosign signatures & SBOM.

    Fully offline. Nothing crosses to the cluster until both bundles pass.

    genesis verify genesis-ops-${VER}.tar.zst
    genesis verify genesis-platform-${VER}.tar.zst
    # Both must print: ✓ cosign verify OK · sha256 match
    
    # CVE-gate the bundle (HIGH+CRITICAL → exit 1; CI-gateable).
    # Extracts the per-image SBOM sidecar and runs trivy against each image.
    genesis scan genesis-ops-${VER}.tar.zst
    genesis scan genesis-platform-${VER}.tar.zst

    Scanner prereq. genesis scan shells out to trivy (to read the per-image CycloneDX SBOM sidecar and emit a HIGH/CRITICAL gate) plus the trivy CVE DB. Both ship in the signed portal tool bundle — if you ran genesis pull --tools in step 1 you already have them, no internet needed:

    # Air-gapped (default): trivy binary + CVE DB come from the tool bundle.
    # genesis scan auto-detects ./tools/<os-arch>/trivy-db.tar.gz, or pass it:
    genesis scan genesis-ops-${VER}.tar.zst --trivy-db ./tools/linux-amd64/trivy-db.tar.gz
    
    # An internal trivy-db mirror also works:
    genesis scan genesis-ops-${VER}.tar.zst -- --db-repository <internal>/trivy-db:2 --skip-db-update
    
    # Connected hosts only — public installer (NOT reachable air-gapped):
    #   curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin
    #   brew install trivy   (macOS)
    trivy --version

    Prefer Grype / Snyk / Black Duck? Extract <bundle>.sboms.tar.gz and loop your scanner over each .cdx.json — see Scan the bundle.

  7. 06
    Push all images to your registry.

    This is the step that makes your CISO happy: every image in the bundle — Genesis-owned and the bundled third-party dependencies (e.g. the Apache-2.0 Holmes image behind the Troubleshoot Agent) — is relocated into your registry before any pod ever runs in your cluster. Your scanner runs against your registry. Pods pull from your registry, never from Docker Hub or ours.

    Third-party images too Not everything in the bundle is authored by Autonomize — the Troubleshoot Agent runs the upstream robustadev/holmes image. It ships inside the ops bundle and is relocated by push-images like the rest, so it stays scannable and air-gap-safe. The vendored Holmes subchart now honors global.imageRegistry (and global.imagePullSecrets) directly, so a plain helm install or ArgoCD sync relocates Holmes with the same one override as every other image — no Holmes-specific flag needed. genesis deploy --registry sets these for you. (The older --set vinAgent.holmes.registry=${REGISTRY} shim is only needed for pre-patch bundles published before Holmes 0.27.0+genesis.1.)
    Push both bundles Push the ops bundle first, then the platform bundle. Both must be in your registry before either genesis deploy call.
    REGISTRY=your-registry.azurecr.io    # ECR, ACR, Harbor, or any OCI registry
    
    # Authenticate to your registry (Azure ACR example — no Docker needed)
    TOKEN=$(az acr login --name ${REGISTRY%%.*} --expose-token --query accessToken -o tsv)
    mkdir -p ~/.config/containers
    cat > ~/.config/containers/auth.json <<EOF
    {"auths":{"${REGISTRY}":{"auth":"$(printf '00000000-0000-0000-0000-000000000000:%s' $TOKEN | base64 -w0)"}}}
    EOF
    
    # Push ops images
    genesis push-images --to ${REGISTRY} --bundle genesis-ops-${VER}.tar.zst
    
    # Push platform images
    genesis push-images --to ${REGISTRY} --bundle genesis-platform-${VER}.tar.zst

    After this step your CISO team can run Trivy / Aqua / Twistlock / Snyk against ${REGISTRY}. Continue to step 7 only after images clear your policy.

  8. 07
    Install External Secrets Operator, then apply the ExternalSecret CRs.

    Two ExternalSecret CRs must exist in the genesis namespace before platform pods start. If they're missing, pods crash immediately with CreateContainerConfigError. The CRs depend on External Secrets Operator (ESO) being installed and a ClusterSecretStore pointing at your vault — install both now if you don't already have them. Apply everything before the ops deploy.

    7.1 — Install ESO (skip if already installed). It must serve external-secrets.io/v1 before preflight (step 10) — the eso-version check hard-FAILs when the CRD is absent (audit E3).

    # EXAMPLE — from your INTERNAL mirror, or the genesis-external-secrets
    # subchart shipped inside the platform bundle. No public Helm repo.
    # The OCI ref, --version, and image.repository below reflect ONE mirror
    # layout; substitute the path/tag/repo your registry actually uses (mirror
    # conventions vary). What matters: install ESO 0.18.x from a source your
    # air-gapped cluster can reach, with installCRDs=true.
    helm upgrade --install external-secrets \
      oci://<your-registry>/charts/external-secrets --version 0.18.2 \
      -n external-secrets --create-namespace \
      --set installCRDs=true \
      --set image.repository=<your-registry>/external-secrets/external-secrets \
      --wait
    # Connected clusters only — public Helm repo (NOT reachable air-gapped).
    helm repo add external-secrets https://charts.external-secrets.io
    helm repo update
    helm upgrade --install external-secrets external-secrets/external-secrets \
      -n external-secrets --create-namespace --set installCRDs=true --wait
    
    # 7.2 — Create a ClusterSecretStore pointing at your vault.
    # Stub below is Azure Key Vault + Workload Identity — substitute your
    # vault URL + ServiceAccount, or use the AWS / Vault / GCP variant from
    # the secrets setup guide linked below.
    cat <<'YAML' | kubectl apply -f -
    apiVersion: external-secrets.io/v1
    kind: ClusterSecretStore
    metadata:
      name: customer-akv     # ← matches secretStoreRef.name in both ExternalSecret templates
    spec:
      provider:
        azurekv:
          authType: WorkloadIdentity
          vaultUrl: "https://YOUR-KEYVAULT.vault.azure.net"
          serviceAccountRef:
            name: external-secrets
            namespace: external-secrets
    YAML
    
    # Wait until the store reports Ready=True before applying ExternalSecrets.
    kubectl wait --for=condition=Ready clustersecretstore/customer-akv --timeout=60s
    
    # 7.3 — Apply the two ExternalSecret CRs.
    kubectl create namespace genesis 2>/dev/null || true
    
    # Edit the templates IN PLACE in docs/customer/templates/ — set
    # secretStoreRef.name to "customer-akv" (or whatever you named the
    # ClusterSecretStore above), uncomment the oidc-client-secret line only
    # when auth_mode=client_secret. Then apply from the repo root:
    kubectl apply -f docs/customer/templates/customer-genesis-secrets-externalsecret.yaml
    kubectl apply -f docs/customer/templates/ai-studio-secrets-externalsecret.yaml
    
    # Wait for ESO to sync both into K8s Secrets
    kubectl -n genesis get externalsecret -w
    # Status column must show: SecretSynced for both

    Per-vault auth setup (Azure Key Vault Workload Identity, AWS Secrets Manager IRSA, HashiCorp Vault, GCP Secret Manager): see required-secrets.md.

    Ready-to-edit CR templates: customer-genesis-secrets-externalsecret.yaml · ai-studio-secrets-externalsecret.yaml. Full key list + AWS / Azure / GCP setup walkthrough: required-secrets.md.

  9. 08
    One-time cluster bootstrap, then deploy the ops bundle.

    zarf init creates the zarf-state secret and an in-cluster registry mirror (used as a relay even when you have an external registry). Run once per cluster lifetime.

    Ops first, always The ops bundle installs the 5 CRDs and the deploy operator. Without this, genesis preflight and genesis deploy --bundle genesis-platform-* will fail.
    # One-time per cluster. The zarf-init package ships in the signed tool
    # bundle (genesis pull --tools, step 1) — pass the LOCAL file; a bare
    # `zarf init` pulls init images from ghcr.io and fails air-gapped (audit A3).
    zarf init ./tools/linux-amd64/zarf-init-amd64-*.tar.zst --confirm
    kubectl -n zarf get secret zarf-state   # must exist before ops deploy
    
    # Deploy ops bundle (uses images already in your registry from step 6)
    genesis deploy --bundle genesis-ops-${VER}.tar.zst --registry ${REGISTRY} -n genesis
    kubectl -n genesis get pods             # all pods must reach 1/1 Running
  10. 09
    Configure: write the PlatformConfig ConfigMap.

    Populate your genesis.yaml with DB host, Redis host, registry URL, base URL, OIDC settings, and Secret references (never raw credentials). Then save to the cluster and emit the Helm values overlay.

    genesis configure \
      --from genesis.yaml \
      --save \
      --emit-helm-values /tmp/genesis-platform-values.yaml
    # Writes: genesis-platform-config ConfigMap (preflight reads this)
    # Emits:  /tmp/genesis-platform-values.yaml (deploy reads this)

    Full field reference: configure.md

  11. 10
    Run preflight — all 34 checks must PASS.

    Preflight reads the ConfigMap saved in step 9. It checks Postgres reachability, Redis, ESO secrets, image registry pull, OIDC discovery, cert-manager, DNS, TLS, and more. Platform deploy is blocked until preflight passes. Any FAIL/WARN row prints inline Vin Advisor advice.

    genesis preflight -n genesis
    # Prints per-check table (PASS / WARN / FAIL)
    # Exit 0 = all PASS, proceed to step 11
    # Exit 1 = one or more FAIL — fix and re-run
  12. 11
    Deploy the platform bundle.

    Helm installs the full Genesis umbrella (~18 services including Keycloak, APISIX, AI Studio, Knowledge Center). Images pull from your registry. Configuration comes from the values overlay emitted in step 9.

    cd bundles first so the --bundle path resolves to the downloaded tarball.

    cd bundles
    genesis deploy \
      --bundle genesis-platform-${VER}.tar.zst \
      --registry ${REGISTRY} \
      --values /tmp/genesis-platform-values.yaml \
      -n genesis
  13. 12
    Verify the install.
    genesis status -n genesis
    # Prints phase summary: ops ✓  platform ✓  preflight ✓
    kubectl get pods -n genesis    # all 1/1 Running

    Your platform is now available at the base_url you configured. OIDC/SSO access is live; bootstrap mode is permanently disabled.

Prefer the wizard? Technical operators with cluster-admin prefer the CLI path above. For guided first installs and POCs, the Genesis Bastion web wizard covers steps 9–11 via a browser form after ops is deployed. Steps 1–8 (tooling, CLI install, pull, verify, push-images, ExternalSecrets, ops deploy) are the same regardless of path.

The five wizard phases

1 · Bootstrap login

Paste the token printed by zarf package deploy (or retrieved via genesis-cp print-bootstrap-token). The Control Plane is in bootstrap mode — no Keycloak yet. Token expires after 24 hours; kubectl rollout restart re-mints one.

2 · Configuration

Fill in non-secret values and Secret references — never raw credentials. Covers: DB host / port / name / admin user + Secret ref for admin password; image registry URL + pull-secret name; base URL, ingress class, TLS Secret; OIDC issuer, client ID, auth mode (WIF recommended). Healthcare Guardrails (optional) — change-freeze window (UTC HH:MM start/end), confirm-production checkbox; these wire into the healthcare-guardrails preflight check. On Save, the Control Plane writes genesis-platform-config ConfigMap and auto-revokes the bootstrap token.

3 · Pre-flight

34 checks across 10 groups: infrastructure (cluster-info, k8s-version-compat, nodes, namespace, storage, storage-class-default, stale-resources), auth (rbac, sa-permissions, network-policies, security-policies), registry (registry, registry-rate-limit, acr-pull†), connectivity (cert-manager, tls, tls-validity†, dns, ingress, external-endpoints, vault), identity (oidc), database (database, pg-auth, database-bootstrap), redis (redis, redis-auth), secrets (eso-version, external-secrets-operator, secret-refs, secrets), helm-state (chart-lock, helm-release), healthcare (healthcare-guardrails). Results written to a PreflightReport CR. Each FAIL/WARN row has an “Ask agent” CTA that calls the Vin Advisor for copy-pasteable fixes. † cloud-specific — Azure clusters only

Before platform install Two ExternalSecret CRs must exist in the genesis namespace before the platform pods start, or they crash with CreateContainerConfigError: customer-genesis-secrets (DB password, OIDC secret refs) and ai-studio-secrets (the full subchart env-var bundle). Ready-to-edit CR templates: customer-genesis-secrets-externalsecret.yaml · ai-studio-secrets-externalsecret.yaml. Full key list: required-secrets.md.

4 · Platform install

Stages genesis-platform-<ver>.tar.zst to a PVC, re-verifies SHA against the portal manifest, creates a GenesisDeployment CR. The Deploy operator runs zarf package deploy for the platform umbrella, sourcing helm values from the ConfigMap + resolving Secret refs. Reconcile events stream live.

5 · Post-install

Health Agent runs 8 post-install probes against the live cluster: pod health sweep, service endpoints, TLS validity, database connectivity, FHIR R4 endpoint, prior-auth workflow smoke, performance baseline, secrets audit. Results stream from the HealthReport CR. All 8 pass → install complete. The Control Plane hands you off to the OIDC login at your base URL. Bootstrap mode permanently disabled until next pod restart.


Verification artifacts

{bundle}.sig + cosign.pub

KMS-keyed ECDSA P-256 signature. Verify offline: cosign verify-blob --key cosign.pub --signature <file>.sig --insecure-ignore-tlog <file>.tar.zst. genesis verify wraps this automatically.

ECDSA P-256 · AZURE KMS · OFFLINE-VERIFIABLE

{bundle}.tar.zst.sbom.cdx.json

Merged CycloneDX bill of materials for the bundle. Auditor handoff and license analysis (FOSSA, Black Duck). For CVE scanning use the per-image tarball below — CVE scanners reject the merged multi-OS document.

CYCLONEDX 1.5 · AUDIT-READY

{bundle}.tar.zst.sboms.tar.gz

Per-image CycloneDX tarball — one .cdx.json per container image. Input to genesis scan (CI-gateable HIGH/CRITICAL exit code). Extract and feed to Grype / Snyk / Black Duck for non-trivy scanners.

CYCLONEDX 1.5 · PER-IMAGE

hipaa-attestation-{ver}.pdf

Signed PDF enumerating every change since the previous release that touches PHI handling, encryption, audit logging, or access control.

PDF · HIPAA · SIGNED


Upgrades

Same shape as install. Pull a new bundle, verify, transfer, and submit a GenesisUpgrade CR via the Upgrade tab. The operator reconciles through the same three-gate chain (preflight → approval → bundle SHA re-verify), runs zarf package deploy + helm upgrade, audits Postgres schema migrations, and regenerates a per-upgrade HIPAA attestation. rollbackOnFailure defaults to true.


Where to go next

Air-gap workflow →

The exact sneakernet path: gap-host pulls, sidecar manifests, cluster-side ingest. Read the workflow.

Scan the bundle →

Plug the SBOM and image archives into your existing scanners (Trivy, Snyk, Aqua, Wiz, etc.). No new tool to approve.

Scanner runbook →

Already onboarded?

Sign in to see the latest releases entitled to your organisation, rotate keys, and view the download audit log.

Sign in →