Skip to main content
An app definition is a reusable blueprint for one piece of software: where its chart lives, which version to install, which namespace it belongs in, and a values file written as a Go template so the same definition produces cluster-appropriate values on every cluster. Definitions are stored in Celum’s database, so they are supervisor-agnostic — the catalog is one list for the whole platform. GET /api/apps returns all of them; GET /api/apps/enabled returns only the enabled ones.
What the catalog feeds. It is the curated chart source for installs onto a cluster: the Install App flow reads /api/apps/enabled for its chart picker and installs through POST /api/clusters/<cluster>/helm-releases, which becomes a Flux HelmRelease on a supervisor or a CAAPH HelmChartProxy on a guest cluster. The upgrade path uses the same list to resolve a release’s chart source.Nothing goes through Git: the ArgoCD Applications and committed files earlier releases generated are gone — see Repositories & manifests.

What a definition holds

The values template

valuesTemplate is plain Go text/template. The definition stays generic and the substitution makes it specific:
The rendered result is what the chart receives — a normal values file, with no templating surviving into the cluster. The template is rendered when the app is installed, with this context:
Domain, Environment, Region and StorageClass are always empty at install time. They belonged to a cluster-creation form that no longer renders catalog apps, so a template that depends on {{.Domain}} installs those lines blank. Declare a param instead ({{.Params.domain}}) and the install asks for it.A required param that is missing, or a value that does not match its pattern, is refused with 400 before anything renders. A param the template uses but the install does not supply renders empty.
With Values as written (rawValues: true) none of this applies: the values are installed exactly as typed. A values file with no {{ is installed as it is either way.

Preview and validate before you save

Three endpoints let you check a definition without creating anything.
1

Render — see the values a cluster would get

POST /api/apps/render takes { "template": "...", "formData": { ... } } and returns { "rendered": "..." }, rendered with exactly the formData you send. To preview an install, send the install context above. A malformed template comes back as 400 with the parser’s own message, so a typo is caught in the editor rather than at install. Action: app:Render.
2

Helm check — does that chart and version exist?

POST /api/apps/helm-check takes { "helmRepoUrl", "chartName", "chartVersion" } and answers each question separately:
repoReachable: false with an error string is a URL or network problem; chartFound: false on a reachable repo means the chart name is wrong; versionFound: false means the version is. At most 20 versions come back, newest first. Both https:// and oci:// sources are supported. Action: app:HelmCheck.
3

Helm values — start from the chart's own defaults

POST /api/apps/helm-values takes the same body and returns { "values": "..." } — the chart’s default values.yaml. Use it as the starting point for a values template instead of guessing key names. Same action, app:HelmCheck.

The enabled flag

enabled: false keeps a definition in the catalog but out of every picker that reads GET /api/apps/enabled. Use it to retire an app without deleting its definition — nothing already installed is affected, because a running release does not consult the catalog. Deleting a definition does not uninstall anything. It removes the blueprint only; releases installed from it keep running, and the cluster’s Helm state is where they are visible afterwards.

Tanzu packages

isTanzuPackage and extraResources are legacy fields. They described how a definition was turned into committed files — package manifests under an apps/packages/ directory, extra resources under apps/resources/ — and that commit path no longer exists. The fields are still stored and still round-trip through export and import, so an old catalog imports without loss, but nothing consumes them.Treat a Tanzu-flagged definition as inert rather than broken. To deliver something that is not a Helm chart, wrap it in a chart and add that to the catalog.

Import and export

The whole catalog moves between installations as one JSON document.
  • GET /api/apps/export returns every definition with id, createdAt and updatedAt stripped, served as an attachment. Action: app:Export.
  • POST /api/apps/import accepts that array and upserts by name — matching names are updated in place, new ones created. The response counts both and lists per-app failures rather than aborting the batch:
Because the key is name, an export/import round-trip is idempotent, and renaming an app in the source installation creates a second definition in the target rather than renaming the existing one.

Permissions

Note that app:Delete is scoped per definition while app:Create is not — you can grant deletion of specific apps without granting creation.

Repositories & manifests

Where the GitOps repositories went, and what replaced them.

Charts & the mirror

Finding a chart to point a definition at, and why a version list can come back empty.

Cluster templates

The same Go-template model applied to whole clusters rather than single apps.

Day-2 operations

The Helm view of what a definition eventually becomes on the cluster.
Celum AI reads this catalog directly — list_apps returns the definitions (with kind=enabled for the creation-time subset), get_app returns one in full including its values template, and search_helm_charts covers the discovery step before you add one.