The short version
Prepare the exact Kubernetes objects, check them, then choose how to deploy them.
| Deployment choice | What happens |
|---|---|
| Local files No account | cub installer or your existing source tool creates the objects. Read and test them, then use kubectl or commit the files for GitOps. |
| OCI to Argo CD or Flux No account | cub installer setup with --output-oci writes or pushes the selected objects as OCI and checks them by reading the artifact back. Your controller pulls that OCI. |
| ConfigHub to Argo CD or Flux ConfigHub account | Upload files or a literal OCI. ConfigHub keeps the objects, changes, checks, approvals, and promotions. cub release publish creates the deployment OCI for your controller. |
All three paths use objects you can inspect before deployment. Start locally and add ConfigHub when you need shared history, variants, approvals, promotion, or fleet rollout.
What this command does. cub installer is a released, open-source plugin for the cub CLI. cub installer setup pulls a catalog package and writes its Kubernetes files locally. It does not apply those files to a cluster; use kubectl, Argo CD, or Flux for delivery. The generated scripts stop before doing any work when the plugin or kustomize is missing.
Why keep the rendered objects
Helm: rebuilt from templates
- Every setting has to be wired into the template up front.
- Need a setting the chart didn't expose? You're stuck, or you copy the whole chart.
helm upgraderebuilds from the templates and overwrites what you changed.
ConfigHub: kept as data you can query and edit
- Render once to plain YAML Units you can read.
- Query the same records across apps and environments, without scraping clusters or hunting through templates first.
- Change any field afterward, by hand, a script, or an AI agent.
- The next upgrade keeps your change instead of wiping it.
Where a setting belongs
There are four places to look. Keeping them separate answers both questions: what should control a setting, and what controls it now.
| Place | Use it for | What happens on upgrade |
|---|---|---|
| Helm values | Choose the base shape: components, object count, storage mode, CRDs, ingress, Secret strategy, topology, or another choice that changes what Helm renders. | Change the recorded values and render a new base. The values profile remains linked to the objects it produced. |
| ConfigHub changes | Change an exact field after render when the base is right but an environment, region, customer, policy, image, label, resource, or other object field must differ. | The edit is a Unit revision or derived variant. It is put back when the base is upgraded. |
| Install work | Provide Secrets, CRDs, target facts, hooks, setup jobs, certificates, or other work needed around the objects. | The prerequisite or route is checked again. It is not hidden as a Helm value or a ConfigHub edit. |
| Live cluster | Observe what actually ran and compare it with the reviewed objects. | A live-only edit is drift. Record an intended fix in ConfigHub, or remove the drift. |
One field should not have two silent owners. If a new Helm render and a ConfigHub revision both change the same field, review the overlap before promotion and choose the intended result.
When this helps
This becomes useful when Helm values are not enough, an upgrade changes more than expected, or a private chart is hard to review. Keep Helm as the source. Review the exact objects, record deliberate changes, and promote the same reviewed result instead of maintaining a permanent chart fork or a hard-to-follow overlay.
Choose a starting configuration
The catalog covers the most-used charts. Each chart is rendered, checked against plain Helm, scanned, and given an honest status. Today's proven scope:
Each chart ships a recommended default base variant plus one standard fork. The forks come from a fixed vocabulary, named by what they change, not bespoke per chart:
Operators choose a vetted package release and a named base variant. They set only the small number of inputs that remain at install time. The catalog does not expose every Helm value again. It provides common paths that are reviewed, repeatable, and safe to reconcile across many installs.
| Base shape | What it changes |
|---|---|
default | Honest out-of-the-box install; the recommended starting point. |
parameterized | Same shape as default, with fill-safe fields exposed as placeholders. |
existing-secret | Bring your own Secret instead of a generated one. |
no-crds | CRDs owned externally (by a controller or GitOps). |
ha | High-availability / scaled-out mode. |
ingress-tls | Exposed via ingress with TLS. |
minimal · tls | Lean install; or bring-your-own TLS material. |
Three ways to create a base variant
ConfigHub can start from more than a Helm chart. Every maintained base has a source and intent record. It says where the objects came from and which choices produced them. It also records what remains to be supplied and which checks support the result. The role is standard, but the file matches the source instead of pretending every source is Helm.
| Starting point | Source and intent record | How it enters ConfigHub |
|---|---|---|
| Helm chart | HelmRenderIntent: chart version, preset values, release context, source lock, literal objects, and known hooks or CRDs. | Render a cub installer package. Keep the files locally, write the selected preset as OCI with --output-oci, or upload either form as a base variant. |
| AICR | The AICR recipe, fixed component versions, remaining install-time inputs, generated bundle, checksums, and public OCI digest. | Keep the generated source package for Argo CD, and upload the separate literal configuration OCI as a base variant. The AICR GPU platform example shows the public packages, 17 exact Applications, development change, and staging promotion. |
| Existing OCI | The input reference and digest, package role, object inventory, checks, and any recorded transformation. | cub variant upload oci://... creates the base Space and Units from the literal configuration bundle. |
| Existing Kubernetes YAML | The source revision or path, file checksums, object inventory, checks, and later OCI or ConfigHub revision. | cub variant upload <files> creates the base Space and Units. |
The generated base-variant records use one common shape for these sources. The record distinguishes a multi-preset source package OCI, a single literal configuration OCI, and the later ConfigHub release OCI used for delivery.
Today, the source and intent role may use a source Unit, Space metadata plus a committed receipt, or a generated base-variant record. ConfigHub does not yet have one first-class source object for every format. The catalog doctrine defines the role in full.
How ConfigHub keeps the result
For Helm, the source and intent record is the HelmRenderIntent. A chart then has two layers. Helm renders it: recipe → base variant → render intent → rendered output. ConfigHub operates it afterward by managing variants. The source-neutral base-variant record joins those layers without replacing the Helm record. Here are the steps, each named for what it does. (The small grey codes are the catalog's own labels, if you read the matrix.)
Inspect the evidence for a base variant in this order:
- Open the full rendered YAML.
- Open the render intent. It records the Helm inputs.
- Open the route records. They describe hooks, CRDs, setup jobs, required cluster facts, and other work outside ordinary objects.
| What to open | What it tells you |
|---|---|
rendered/release-objects.yaml | The Kubernetes objects captured from one reviewed render. This is the output, not the whole model. |
HelmRenderIntent | The chart version, values profile, namespace, release name, capability profile, source lock, rendered output path, evidence links, and known route facts. |
| Chart extras and routes | How this chart handles hooks, CRDs, setup jobs, generated Secrets, target prerequisites, GitOps handoff, blockers, or per-target decisions. |
The recipe: your source of truth
A recipe is the chart and version, the values you chose, the base you picked, and the locks, kept in git. It's the one place your intent lives. Nothing is rendered yet.
Render: inputs first, then the frozen objects
A base variant is a named render choice such as default, no-crds, or ha. Its render intent records the inputs for that choice: chart version, values profile, namespace, capabilities, source lock. Rendering those inputs once produces the rendered output: the exact Kubernetes objects, frozen with a checksum. Intent first, then the captured output. The rendered output is never re-rendered. It is what you read before install, what we compare against plain Helm, and what your controller pulls unchanged. The render boundary is simple. Changing the object set makes a new base variant. Changing only the operating context needs no re-render.
Example: Redis default has a package users pull, oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/bitnami-redis:25.5.3; a render intent that records the Helm inputs; and a full rendered YAML output, release-objects.yaml. The revision binds that YAML to checksums, and the package base is the repo source for that base variant. Redis has no hook route; charts with hooks or CRDs carry that context in lifecycle routes and target facts. For more examples, see the render-intent summary.
Record: the evidence, kept with the render
We keep the evidence with each render. It includes checksums, Helm-equivalence evidence, a security scan, an install gate, diffs, and live observations where they exist. A later reviewer or agent can inspect the exact render and repeat the same test. The render intent is the compact, machine-readable index for this evidence.
Route: the work Helm leaves at the edges
Helm can do more than produce ordinary YAML. A chart may install CRDs, run setup jobs, or generate Secrets. It can also require cloud identity, storage, or another existing cluster resource.
We record the right choice for each chart with its inputs, output, tests, and receipts. A base can include its CRDs or leave them to the cluster. It can require a tested setup step or an existing target resource. The catalog blocks the path when no safe default exists. A route records that decision and its evidence boundary. It is automatic only when the product runs it and a receipt proves the result.
The render intent separates requirements declared by the base from follow-up actions learned in live tests. For a recorded lifecycle route, it also says what Argo CD does and what Flux does for that exact chart version and base.
Change: derive from a base, and ConfigHub manages it
A derived variant changes a base after render. It can set the target, region, labels, or approvals, or it can edit any field. Create one per environment from a single base. The next upgrade keeps those edits. ConfigHub manages the review, promotion, approval, and delivery. It also observes the live result. Managed is a property, not a separate kind; a base variant can also be managed. Helm cannot provide this post-render history by itself.
The five words: Variants, in one picture
| Word | What it is | Re-renders Helm? | Lives in |
|---|---|---|---|
| Recipe | The source of renders: chart, version, values, declared bases, declared routing intent. | It is what gets rendered | the repo and the package |
| Base variant | A recipe rendered one named way (default, no-crds, ha…). Changing what gets installed means a new base variant. | Yes, once, and it's checked against Helm | the package; a root Space after upload |
| Rendered output | The frozen, checksummed objects a rendering produced; with its render intent it forms the render record. | No, it's already rendered | the recipe's revisions |
| Derived variant | A change derived from a base: per-environment context or later edits, upstream link recorded. | No | ConfigHub |
Any of these can be managed: that's ConfigHub operating it (compare, promote, approve, deliver, observe), a property rather than a fifth kind. One sentence for the whole picture: a recipe renders into a base variant; a base variant clones into derived variants; promotions carry reviewed changes down.
Where the recipe lives, today and next
Inside a ConfigHub org, you see Units, clones, revisions, and links. The source recipe lives in this repository and in the package. Every catalog Space also carries a plain data Unit named recipe. It sits beside the objects that recipe produced. The table compares the three forms.
| The recipe in this repo | The recipe unit in an org | A first-class source object (where this is heading) | |
|---|---|---|---|
| What it is | The authoritative source: chart pin, source lock, per-base values, revisions. | A generated record of one render's inputs, placed as data beside the output. | An executable source object: repository, chart, version, values, in one unit. |
| Carries the values? | Yes; it is the values. | No; it points at them in the repo. | Yes, self-contained. |
| Who acts on it | The catalog pipeline builds the package from it. | Nobody; the render already happened outside. | A worker renders it, and re-renders it when it changes. |
| Connected to its outputs? | Through the repo's evidence chain. | Sits in the same Space, no link. | Linked to the units it rendered. |
| Authority | Authoritative. | A copy; it can lag the repo. | Would become authoritative. |
The recipe unit is the future source object with the machinery removed: a plaque in the seat where the engine goes. It marks the spot; it does not run. When source objects become first-class, this catalog's hundred recipes are ready to become real ones.
Why the records are separate
| We chose to… | …because |
|---|---|
| Keep config fully rendered (not templated) | So you can change any field after install and the change survives upgrades. And the proof is the desired config itself, not a side effect of running an engine. |
| Freeze the render instead of re-rendering | What you read is exactly what installs and what your controller delivers, with no re-render drift between review and runtime. |
| Name every route (hooks, CRDs, prereqs) | Every behaviour Helm handled outside normal objects still has to be owned, tested, skipped, or blocked. The catalog records that decision per base variant. |
| Mark routes automatic: false until earned | Nothing is called automatic until the product actually runs the route and committed evidence proves it. No claim ahead of proof. |
| Report an honest disposition (synced ≠ working) | GitOps can say "Synced" while the workload is broken. Separate lanes make the real problems explicit instead of hiding them behind one green tick. |
| Offer existing-secret bases | A default that ships a generated password installs green but breaks silently over GitOps (the pod can't find the Secret while Argo still says Synced). Bring-your-own is the safe path. |
Recommended paths
Take the smallest path that does the job, and grow only when you need to:
| You want to… | Recommended path |
|---|---|
| Just see the objects | Render and read them. No account, no cluster. |
| Install one chart | Start at the chart's default base: cub installer setup --pull <installer OCI ref> --base default. |
| Run a database / anything with a password | Use the existing-secret base and supply the Secret yourself. Don't ship a generated one over GitOps. |
| Change something after install | Make a derived variant. It keeps your change through upgrades, no re-render. |
| Run dev / staging / prod | One base → many derived variants (per environment, region, customer). The base stays single; the instances live in ConfigHub. |
| Already run Argo or Flux | Keep your controller. Publish once to OCI; point Argo/Flux at the same bundle. |
Checks before apply
The same apply policy can protect configuration that started as Helm, AICR, cub installer, Kubara, Sveltos, or ordinary Kubernetes files. Schema, placeholder, and lifecycle-route checks block incomplete configuration. Ordinary workloads and AICR training runtimes receive checks for the fields they actually use. Production releases and system configuration keep those 7 checks and add one required approval.
The source format does not decide the risk. A user workload, shared service, and cluster-wide configuration can all begin as Helm or YAML. The live demo applies 7 common tests to 33 Spaces. It adds approval to 9 Spaces: 4 production Spaces and 5 system-configuration Spaces. The receipt includes every maintained starting format: AICR 3, cub installer 30, Helm 3, Kubara 1, rendered Kubernetes config 4, Sveltos 1. Read the policy profile and live receipt. You can also run its verifier while logged into the helm-catalog org.
The three worked examples show how ownership changes the policy. An application team owns and promotes NGINX. A platform team introduces Kube Prometheus Stack as a shared service. Kubara is approved as cluster-wide platform configuration. Each example names the target, tests, rollout order, current result, and receipt.
Worked paths and Apps
The demonstration programme tracks the Helm, AICR, cub installer, OCI, promotion, Kubara, and Sveltos paths. It also states which ConfigHub Apps work today and which remain partial or planned. The Kube Prometheus Stack example gives one complete chart-specific route plan. The RBAC review example shows one exact permission correction. That correction is tested, approved, published as OCI, and delivered by Argo CD.
Decisions you still make
Some choices we can't make for you. They depend on your cluster, your secrets, your policy. We surface them clearly and recommend a default, but the call is yours. We guide; you decide.
Which base fits. We recommend default, but you know whether you need ha, no-crds, or existing-secret. The catalog names the trade-off; you pick.
Namespace. Simple charts honour --namespace. Some complex charts embed a namespace in their objects and must install at their canonical one. The chart page says which.
Image pinning. Some default bases ship a floating tag. For reproducible, digest-bound delivery, pin it: --set-image NAME=repo/img@sha256:….
Secrets. Bring your own via the existing-secret base and stage it out-of-band (ExternalSecrets, Vault, or kubectl). We can't invent your production secret.
Prerequisites & target facts. Some bases need a Secret, a CRD, a namespace, or a cluster value to exist first. Stage them before applying, or choose a base that includes them. Each one is listed, not assumed.
When to use Helm directly. If a chart is not in the catalog, use helm template or helm install and record the chart, version, values, namespace, and release name. You can later upload the rendered files with cub variant upload.
Check a claim
When a chart page says a path passes, is blocked, or is ready to try, that claim should be backed by files you can inspect. In this repo we call those checks verification. Some checks compare generated files on your machine; some use a fresh Kubernetes cluster.
| Check file | Question it answers |
|---|---|
render-receipt | Did the same inputs produce the same Kubernetes objects twice? |
helm-equivalence-receipt | Does the cub render match plain helm template for this base variant? |
scan-receipt | What security findings were found in the rendered objects? |
install-gate | Is this render safe to try, does it need review, or is it blocked? |
object-inventory · variant-revision | Which exact Kubernetes objects and checksums belong to this render? |
The model has four steps: recipe → render → record → route. Lock the inputs, render the objects, keep the check files with them, and record the extra work Helm leaves around the edges. Live results are reported one lane at a time, not as one blanket success mark:
watch means read the warning first. blocked means do not use that path yet. not applicable means the test does not apply to that chart. You can verify the evidence three ways:
| Way to check | Needs a cluster? | What it confirms |
|---|---|---|
Run the render check yourself (npm run <chart>:verify-install:render) | No | Your own render matches the catalog's recorded contract. |
Re-verify the committed evidence (npm run verify) | No | The receipts, hashes, and generated files are self-consistent. |
Run a fresh live lane (npm run kind-parity:run / live-parity:run) | Yes | Helm vs cub, and OCI→Argo/Flux, on a throwaway cluster. |
What can be repeated exactly
Some catalog steps are pure computations that you can reproduce offline. Other steps touch a live cluster and cannot produce byte-identical results. The table states which type each step belongs to.
| Stage | Idempotent? | Reproducible from source, no cluster? | Why |
|---|---|---|---|
| Render (recipe → objects) | yes | yes, byte-identical | kustomize over the frozen upstream with pinned inputs; same inputs always give the same objects. |
| Record (receipts, checksums) | yes | yes | Just hashing and writing committed content, no live state. |
| Catalog / matrix / site views | yes | yes | Re-derived from the committed recipes; stable joins, stable order. |
| Route (hooks / CRDs / prereqs) | plan: yes | plan: yes · run: no | Naming and classifying is pure; running a route touches a cluster and may have side effects. |
| Apply (kubectl / Argo / Flux) | yes, apply + prune converges | no | Declarative apply converges to the same state, but it's a live action on a cluster. |
| Live proof / disposition | no | no, not byte-deterministic | It observes a real cluster: pod scheduling, image pulls, controller timing. Each run is a new, point-in-time observation. |
A rename or re-derivation regenerates offline from committed source. A fresh live result needs a cluster. Live runs are serial and use one temporary cluster at a time. cub cluster up creates that local kind cluster. cub cluster down removes it afterward. Render parity is not a live result, and a warning is not a pass.
Deploy from ConfigHub
For the managed path, set the Space's release target and publish the reviewed Units as one immutable release OCI. Argo CD, Flux, or a recorded direct-apply path can pull the same files. None of them renders the chart or source package again.
New to cub? Install the cub CLI first. You can pull and render public catalog packages without an account. Commands that save or change ConfigHub data require you to sign in.
cub space update <app-space> --release-target <cluster-space>/oci
cub release publish <app-space>
# Argo CD Application source
source:
repoURL: oci://oci.hub.confighub.com:443/space/<app-space>
targetRevision: latest
path: .
# Flux source
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
spec:
url: oci://oci.hub.confighub.com:443/space/<app-space>
ref:
tag: latest
A small routed-hook fixture proves that three delivery methods can consume one ConfigHub release OCI and complete the same setup Job. The first exact catalog result uses the real bitnami/nginx@24.0.2 http-clusterip preset. cub installer reproduced its committed objects, and ConfigHub published them once. Argo CD, Flux, and direct apply reported the same release digest and a ready NGINX workload. Read the plain-English result or the receipt. Every other catalog configuration still needs its own receipt before its page can make that delivery claim.
What direct apply still has to handle
The recorded direct path proves a first apply for one NGINX configuration. A reusable direct-delivery path also needs explicit behavior for these cases:
- Generated passwords. A chart default may create a Secret that should not become a shared, repeatable credential. Choose an
existing-secretpreset when the chart supports one. - CRD ordering. Apply CRDs first, wait for them to become available, then apply the objects that use them.
- Field conflicts and removals. Show who owns a conflicting field and define which removed objects may be pruned.
The catalog records these requirements per preset. A path is called automatic only after a receipt shows that it performed the required work.
Review AI changes
AI-assisted changes, with control
AI can make a change faster than a person can review it. An agent therefore edits the rendered files, not hidden live state. Before delivery, you inspect the exact diff, scan for secrets and bad settings, and record an approval. If a bad value gets through, you can restore an earlier revision. The AI proposes the change. A person or policy approves it. The cluster receives only the approved result.
Read the status
This page is not a blanket promise that every chart, controller, hook, or cluster path is ready. It shows what has been checked, what still needs work, and what a user should do next.
| Status or label | What it means |
|---|---|
pass | The named check has committed evidence. Open the receipt if you need to see exactly what was tested. |
watch | The path may be useful, but there is a named risk or prerequisite to read before you use it. |
blocked or refused | Do not use that catalog path yet. Choose another base variant, use Helm directly, or add the missing setup work. |
automatic | ConfigHub only uses this word when it runs the step and a receipt exists. Otherwise the page names who must run it. |
| GitOps delivery | The three-consumer fixture proves the OCI delivery mechanism. Each catalog configuration remains unproved for a controller until its own receipt records the sync and workload result. |