License key
Issued by Autonomize. Format sk_yourorg_*. Used by the genesis CLI to authenticate to the download portal.
Genesis Downloads · Install guide
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.
Issued by Autonomize. Format sk_yourorg_*. Used by the genesis CLI to authenticate to the download portal.
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).
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.
Kubernetes 1.28+, PostgreSQL 16+, Redis 7+, cert-manager, ESO, Ingress, DNS, TLS cert. Full list: Prerequisites checklist.
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.
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 bundle — install-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.)
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.76.0
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
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
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
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):
Ctrl+C.echo 'export PYTHON_KEYRING_BACKEND=keyring.backends.fail.Keyring' >> ~/.bashrc
source ~/.bashrc
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.
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
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.
This is the step that makes your CISO happy: every image in the bundle — Genesis-owned and the bundled third-party dependencies (the Chainguard preflight probe images) — 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.
push-images like the rest, so they stay scannable and air-gap-safe. Every chart honors global.imageRegistry (and global.imagePullSecrets), so a plain helm install or ArgoCD sync relocates them with the same single override as every other image — no per-image flag. The full list is in the ops-bundle image table on the Prerequisites page.
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.
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.
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.
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
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
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
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
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.
Paste the token printed by zarf package deploy (or retrieved via genesis-cp print-bootstrap-token). The Bastion is in bootstrap mode — no Keycloak yet. Token expires after 24 hours; kubectl rollout restart re-mints one.
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 Bastion writes genesis-platform-config ConfigMap and auto-revokes the bootstrap token.
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
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.
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.
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 Bastion hands you off to the OIDC login at your base URL. Bootstrap mode permanently disabled until next pod restart.
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.
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.
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.
Signed PDF enumerating every change since the previous release that touches PHI handling, encryption, audit logging, or access control.
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.
The exact sneakernet path: gap-host pulls, sidecar manifests, cluster-side ingest. Read the workflow.
Plug the SBOM and image archives into your existing scanners (Trivy, Snyk, Aqua, Wiz, etc.). No new tool to approve.
Sign in to see the latest releases entitled to your organisation, rotate keys, and view the download audit log.