Install
Each release ships a single install.yaml that bundles the namespace, the Custom Resource
Definitions, the controller’s RBAC and NetworkPolicy, and the controller Deployment. One
kubectl apply stands the whole subsystem up in its own namespace.
Both images are public, so there is nothing to build, mirror or authenticate against first. You need
a cluster, kubectl, and permission to create cluster-scoped resources (the CRDs) — see
Prerequisites.
Install
Section titled “Install”kubectl apply -f https://github.com/re-cinq/ai-agent-subsystem/releases/latest/download/install.yamlThat is the entire install. To pin a specific release instead of tracking the latest, substitute a tag from the releases page:
kubectl apply -f https://github.com/re-cinq/ai-agent-subsystem/releases/download/v0.14.0/install.yamlThen verify the deployment. One thing install.yaml cannot ship for you is
credentials: an agent calls a model provider, so it needs an agent-secrets Secret in the
ai-agents namespace before a run can succeed. See
Prerequisites.
Build your own images
Section titled “Build your own images”You do not need this to install — the published images are public. Build your own only when the cluster must pull from a private or air-gapped registry of your own.
The published images are multi-arch (linux/amd64 and linux/arm64). You need Docker (with Buildx) and a registry your cluster can pull from. Both images build from the repository root, for the platforms your nodes run:
REGISTRY=your-registry.example.com/your-projectTAG=v0.14.0
docker buildx build --platform linux/amd64,linux/arm64 --push \ -f deploy/Dockerfile.controller -t "$REGISTRY/ai-agent-controller:$TAG" .docker buildx build --platform linux/amd64,linux/arm64 --push \ -f scripts/container/Dockerfile.agent -t "$REGISTRY/ai-agent:$TAG" .Building a platform other than the host’s needs QEMU binfmt registered (docker run --privileged --rm tonistiigi/binfmt --install arm64) or a native builder of that architecture; drop the one you
do not need from --platform to skip it.
Then point the manifests at them. The controller image is set through the kustomize images:
override in deploy/kustomization.yaml; the agent runtime is the AGENT_IMAGE env in
deploy/controller.yaml:
( cd deploy && kustomize edit set image ghcr.io/re-cinq/ai-agent-controller="$REGISTRY/ai-agent-controller:$TAG" )# then set AGENT_IMAGE in deploy/controller.yaml to "$REGISTRY/ai-agent:$TAG"If your registry needs credentials, create an image pull secret in the ai-agents namespace and
reference it from the controller Deployment and the injected run pods.
From a source checkout
Section titled “From a source checkout”Before a release is published — or when developing against the manifests directly — apply the
deploy/ kustomization:
kubectl apply -k deployThe controller runs least-privilege: it can watch and patch Agents, read Stations and AgentDefinitions, manage Jobs, read pod logs, and write the ModelCatalog. See RBAC & network.
Install with Helm
Section titled “Install with Helm”Each release also publishes a Helm chart to oci://ghcr.io/re-cinq/charts. It is packaged from
deploy/, and CI fails if the two render different objects, so a Helm install creates the same
objects as install.yaml for the same release. Helm 3.8 or later is needed for OCI charts.
helm install ai-agent-subsystem oci://ghcr.io/re-cinq/charts/ai-agent-subsystem --version 0.14.0 \ --namespace defaultThe chart creates the ai-agents namespace itself, as install.yaml does, and every object goes
there. --namespace only chooses where Helm keeps its release record, so it must name a namespace
that already exists. Do not pass --namespace ai-agents --create-namespace: Helm would create the
namespace first and then fail on the chart’s own Namespace object.
| Value | Default | Effect |
|---|---|---|
controller.image.repository | ghcr.io/re-cinq/ai-agent-controller | Controller image, without tag or digest |
controller.image.digest | the release’s signed digest | Controller image digest (sha256:…). Tags are rejected |
agentImage | ghcr.io/re-cinq/ai-agent@sha256:… | Agent runtime image injected into run pods. Must be digest-pinned |
batch.enabled | false | Same as the components/batch component: batch runs |
modelCatalog.enabled | false | Same as the components/model-catalog component: model catalog |
realtime.enabled | false | Same as the components/realtime component: realtime sessions. Create the agent-realtime Secret first |
webhooks.enabled | false | Same as the components/webhooks component: GitHub webhooks. Store the HMAC key in agent-secrets first |
The chart accepts no other values. For a private registry, set controller.image.repository,
controller.image.digest and agentImage to your own images.
Helm installs the CRDs from the chart’s crds/ directory on the first install only. helm upgrade
does not change them and helm uninstall leaves them in place. When a release changes a CRD, apply
that release’s CRDs yourself (this uses yq to pick them out of
install.yaml):
curl -sL https://github.com/re-cinq/ai-agent-subsystem/releases/download/v0.14.0/install.yaml \ | yq 'select(.kind == "CustomResourceDefinition")' | kubectl apply -f -The chart is signed with cosign the same way as the images:
cosign verify ghcr.io/re-cinq/charts/ai-agent-subsystem:0.14.0 \ --certificate-identity-regexp '^https://github.com/re-cinq/ai-agent-subsystem/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comThe same chart is attached to each GitHub release
as ai-agent-subsystem-<version>.tgz, for tools that cannot pull OCI charts.
Enable batch runs (optional)
Section titled “Enable batch runs (optional)”Batch runs are off by default, and neither install.yaml nor deploy/
gives the controller access to Secrets. To enable them, install through your own kustomization that
adds the components/batch component:
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources: - https://github.com/re-cinq/ai-agent-subsystem//deploy?ref=v0.14.0components: - https://github.com/re-cinq/ai-agent-subsystem//deploy/components/batch?ref=v0.14.0kubectl apply -k .From a source checkout, list deploy and deploy/components/batch as local paths instead. With
Helm, set batch.enabled=true.
Enable realtime sessions (optional)
Section titled “Enable realtime sessions (optional)”Realtime sessions are off by default. To enable them, create the
agent-realtime Secret and add the components/realtime component; the
guide has both steps. With
Helm, create the Secret and set realtime.enabled=true.
Enable GitHub webhooks (optional)
Section titled “Enable GitHub webhooks (optional)”GitHub webhooks are off by default. To enable them, add the
components/webhooks component, which grants the controller get on the agent-secrets Secret,
sets WEBHOOKS_ENABLED=true and adds the agent-controller-webhooks Service on port 8083:
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources: - https://github.com/re-cinq/ai-agent-subsystem//deploy?ref=v0.14.0components: - https://github.com/re-cinq/ai-agent-subsystem//deploy/components/webhooks?ref=v0.14.0Then store the webhook’s HMAC key in agent-secrets, expose the Service to GitHub and add the
webhook; the guide has each step. From a source checkout, use
deploy/components/webhooks as a local path. With Helm, set webhooks.enabled=true
instead of adding the component.
Enable the model catalog (optional)
Section titled “Enable the model catalog (optional)”The ModelCatalog lists the models the subsystem can run with the
API keys in agent-secrets. It is off by default. To enable it, add the components/model-catalog
component, which grants the controller get on the agent-secrets Secret and sets
MODEL_CATALOG_ENABLED=true:
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationresources: - https://github.com/re-cinq/ai-agent-subsystem//deploy?ref=v0.14.0components: - https://github.com/re-cinq/ai-agent-subsystem//deploy/components/model-catalog?ref=v0.14.0List both components to enable batch runs and the catalog together. From a source checkout, use
deploy/components/model-catalog as a local path. With Helm, set
modelCatalog.enabled=true. Once the controller has refreshed, read the
catalog with kubectl get mc default -n ai-agents -o yaml.
Verify the deployment
Section titled “Verify the deployment”kubectl -n ai-agents get deploy,podskubectl -n ai-agents logs deploy/agent-controllerThe controller exposes /healthz (liveness), /readyz (readiness — green once it has reached
the API server), and a Prometheus /metrics endpoint on its health port; a Running pod with
passing probes means it is reconciling. The pod template carries
prometheus.io/scrape annotations, so a cluster Prometheus picks up /metrics automatically.
Verify the release
Section titled “Verify the release”The controller image install.yaml pins is signed in CI with cosign
(keyless, via the GitHub OIDC token). Confirm the signature before trusting a release:
cosign verify ghcr.io/re-cinq/ai-agent-controller@sha256:c1abb59da048e98329caf04ffc1c2bde41736e10a140307b83e848fefabb92c4 \ --certificate-identity-regexp '^https://github.com/re-cinq/ai-agent-subsystem/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comThe digest above is the one this release’s install.yaml references. A passing check means the image
was built and signed by this repository’s release workflow. The same images also carry an SPDX SBOM
and SLSA provenance attestation; see Releases.
API versions and upgrading
Section titled “API versions and upgrading”The CRDs are served at agents.re-cinq.com/v1beta1, which is also the version objects are stored
at. v1alpha1 is still served with the identical schema, so manifests and clients written for it
keep working after an upgrade; the API server answers each v1alpha1 request with a deprecation
warning. Nothing needs converting: both versions read and write the same fields.
Objects created before the upgrade stay stored as v1alpha1 until they are next written. Before a
future release stops serving v1alpha1, rewrite them once so every object is stored at v1beta1:
for kind in agentdefinitions stations agents modelcatalogs; do kubectl get "$kind.agents.re-cinq.com" -A -o json | kubectl replace -f -donekubectl get crd agents.agents.re-cinq.com -o jsonpath='{.status.storedVersions}' lists the versions
the CRD has recorded as stored. The API server never prunes that list itself; once the rewrite is
done, drop v1alpha1 from it (kubectl patch crd <name> --subresource=status --type=merge -p '{"status":{"storedVersions":["v1beta1"]}}').
Define your first recipe in Define a recipe, or jump straight to the Examples. To tear it all back down, see Uninstall.