Skip to main content
This path is for teams comfortable with Kubernetes who want to install Cake Agents directly with Helm into an existing cluster.

End State

At the end of this guide you will have:
  • a cake-agents Helm release deployed to your cluster
  • a reachable control plane UI/API
  • a database connection (embedded Postgres for development or an external database)
  • session pods launching successfully in the expected namespace

Architecture Summary

Cake Agents Architecture Cake Agents has two runtime layers:
  • The control plane is a web application deployed as a standard Kubernetes workload.
  • Each user session launches a data plane pod that runs OpenCode inside the cluster.
The chart also manages supporting pieces such as RBAC, optional embedded PostgreSQL, optional Istio resources, and integration secrets.

Prerequisites

  • A working Kubernetes cluster
  • kubectl configured for the target cluster
  • helm 3+
  • A DNS name for the control plane
  • An ingress controller or API gateway configured to route traffic to the control plane (e.g. Istio, Nginx, ALB, etc.)
  • Kubernetes secrets or secret-management flow for integration credentials
  • Optionally, a preexisting Postgres database

What the Helm Chart Configures

The Helm install configures these main concerns:
  • Control plane deployment, service account, probes, and service
  • RBAC for creating and managing session workloads
  • Embedded PostgreSQL for development, or an external database via externalDatabase.existingSecret
  • Secret wiring for integrations and auth

Set up DNS

Cake Agent’s control plane needs to be reachable at a stable DNS name. This is used for user linking flows and should match the controlPlane.host value in the Helm chart.

Choose a Database Strategy

For development, the chart defaults to embedded PostgreSQL. For shared or production-like environments, use an external database and provide a secret instead:
externalDatabase:
  existingSecret: cake-agents-db
  existingSecretKey: DATABASE_URL

postgresql:
  enabled: false
If manually provisioning this secret, you may want to first create the namespace.
kubectl create namespace cake-agents
Then apply a secret manifest that looks like this:
apiVersion: v1
kind: Secret
metadata:
  name: cake-agents-db
  namespace: cake-agents
type: Opaque
stringData:
  DATABASE_URL: postgres://username:password@hostname:port/database

Set up an auth client

Cake Agents uses OIDC for authentication. You can use any compliant provider, or delegate auth to an authenticating proxy via trusted headers. In your OIDC provider, create a new client with these settings:
  • Client type: Confidential or Public (with PKCE)
  • Redirect URI: https://<controlPlane.host>/api/auth/callback/oidc
  • Scopes: openid email profile
Export the client ID and secret for the next step. If using a public client, you can omit the secret.
kind: Secret
apiVersion: v1
metadata:
  name: sso-oidc
  namespace: cake-agents
type: Opaque
stringData:
  clientSecret: <your-client-secret>

Minimal Values File

Start from a small values file and expand from there:
image:
  tag: 0.5.0

controlPlane:
  host: agents.example.com
  extraHosts:
  - auth.example.com

externalDatabase:
  existingSecret: cake-agents-db
  existingSecretKey: DATABASE_URL

oidc:
  enabled: true

  providerId: oidc
  domain: example.com
  issuer: https://auth.example.com
  clientId: <your-oidc-client-id>
  clientSecret:
    create: false
    # Should match your provisioned secret
    name: sso-oidc
    key: clientSecret

postgresql:
  enabled: false

Install with Helm

If manually installing, you’ll need to first assume an identity in your AWS account that has permissions to pull the control plane. Then, you can log into ECR and use that to authenticate helm to Cake’s private registry. For example:
aws ecr get-login-password --region us-east-2 | helm registry login --username AWS --password-stdin 684117700585.dkr.ecr.us-east-2.amazonaws.com
Then you can install the chart with your values file:
helm upgrade --install cake-agents \
  oci://684117700585.dkr.ecr.us-east-2.amazonaws.com/charts/cake-agents \
  --version 0.5.0 \
  --namespace cake-agents \
  --create-namespace \
  -f /path/to/values.yaml \
  --wait --timeout 5m
Once you’re installed, you’ll need to configure your ingress or gateway to route traffic to the control plane service. If using Istio, you can enable the built-in gateway configuration in the chart and point your DNS at the gateway’s external IP. After you can reach the control plane in the browser, you’re ready to set up integrations:

Values Reference

registry:
  # Shared fallback registry used when controlPlane/dataPlane/dataPlaneInit image registry is empty.
  default: 684117700585.dkr.ecr.us-east-2.amazonaws.com

# Global image defaults.
image:
  # Used when a component-specific image.tag is unset/empty.
  tag: latest

controlPlane:
  # Note: control plane is not yet designed for multi-replica operation
  # and should be deployed with replicaCount: 1 for now.
  replicaCount: 1
  image:
    registry: ""
    repository: cake-agents/web
    tag: latest
    pullPolicy: Always
  imagePullSecrets: []
  # Public host used by Istio ingress resources and default ALLOWED_HOSTS.
  host: ""
  # Additional entries appended to ALLOWED_HOSTS (Vite-style: leading `.` = suffix).
  extraHosts: []
  deployment:
    # Set to override data plane image entirely (e.g. CI tag)
    dataPlaneImage: ""
    # Set to override data plane init image entirely (e.g. CI tag)
    dataPlaneInitImage: ""
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
    livenessProbe:
      path: /api/health
      periodSeconds: 30
      failureThreshold: 3
    readinessProbe:
      path: /api/health
      periodSeconds: 10
      failureThreshold: 3
    extraEnv: []
  serviceAccount:
    create: true
    automount: true
    annotations: {}
    name: ""
  podAnnotations: {}
  podLabels: {}
  nodeSelector: {}
  tolerations: []
  affinity: {}

nameOverride: ""
fullnameOverride: ""

# Base path for the control plane.
pathPrefix: /

# K8s namespace for session data plane workloads.
sessionNamespace:
  # Namespace to use for session workloads (empty = release namespace).
  name: ""
  # Create `sessionNamespace.name` when it differs from the release namespace.
  create: false

# Existing secret containing a full DATABASE_URL. If unset, this chart uses
# the embedded Bitnami PostgreSQL secret + env var composition in the web pod.
externalDatabase:
  existingSecret: ""
  existingSecretKey: DATABASE_URL
  # Optional map of secret key -> env var name (e.g. PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD).
  # When set, these env vars are injected from existingSecret and existingSecretKey is ignored.
  existingSecretEnv: {}

# Embedded PostgreSQL (recommended for development only).
# For production, prefer an externally managed database and set externalDatabase.existingSecret.
postgresql:
  enabled: true
  auth:
    username: postgres
    # Leave empty to let the subchart generate and persist a random admin password.
    password: ""
    # Optional existing secret used by the Bitnami subchart for auth credentials.
    # Must contain key `postgres-password` (and usually `password`).
    existingSecret: ""
    database: postgres
  primary:
    persistence:
      enabled: true
      size: 1Gi

# Optional External Secrets integrations.
externalSecrets:
  # Generate embedded PostgreSQL credentials using ESO and write them to
  # `postgresql.auth.existingSecret`.
  enabled: false
  # Recommended for previews: create once and do not rotate while PVC exists.
  refreshPolicy: CreatedOnce
  refreshInterval: 0s
  generator:
    length: 32
    digits: 8
    symbols: 8
    noUpper: false
    allowRepeat: true

sessionVolume:
  storageSize: 2Gi
  # Empty = use cluster default StorageClass
  storageClassName: ""

rbac:
  # Permissions for session workload management in sessionNamespace.
  enabled: true

# Data plane images
dataPlane:
  image:
    registry: ""
    repository: cake-agents/data-plane
    tag: main

dataPlaneInit:
  image:
    registry: ""
    repository: cake-agents/data-plane-init
    tag: main

# Cake Agents uses Better Auth for user account management and auth.
# The chart by default creates a random secret used for signing session
# cookies. You can also provide your own secret or integrate with an
# external secret manager.
betterAuth:
  secret:
    # When externalSecrets.enabled=true, the chart renders an ExternalSecret that
    # generates this Secret once (refreshPolicy defaults to CreatedOnce).
    # When externalSecrets.enabled=false, the chart creates a v1 Secret with a
    # generated value (stable across Helm upgrades via lookup).
    create: true
    # Secret name in the release namespace.
    name: better-auth
    # Annotations applied to the Secret (or ExternalSecret target Secret) when create=true.
    annotations: {}
    # Map of logical keys -> Secret data keys.
    keys:
      # Secret data key used for BETTER_AUTH_SECRET.
      secret: secret

# Cake Agents supports OIDC authentication with any compliant provider. When
# enabled, users are redirected to the OIDC provider for login.
#
# Required OIDC scopes include: openid email profile.
oidc:
  enabled: false
  # Cake Agents internal provider ID. In the future, Cake may support
  # multiple providers and this ID will be used to distinguish them
  providerId: ""
  # Restricts login to users with an email address in the specified
  # domain (e.g. `example.com`).
  domain: ""
  # Issuer URL for OIDC discovery. Must support the well-known OIDC config endpoint.
  issuer: ""
  # Client ID from the OIDC provider. Required for both confidential and public clients.
  clientId: ""
  # For public OIDC clients (PKCE), set to true and omit client secret.
  publicClient: false
  pkce: true
  # Client secret from the OIDC provider. Required for confidential clients, must be omitted for public clients.
  clientSecret:
    # Create an empty Secret scaffold in the release namespace.
    # Set to false to reference an existing Secret.
    create: false
    name: sso-oidc
    annotations: {}
    key: clientSecret

# Alternatively, Cake supports delegating auth to an authenticating proxy
# via trusted header. When headerAuth.enabled=true, Cake Agents reads user
# identity from an OIDC ID Token (jwt.header) or directly from headers
# (email.header, user.header) set by the proxy. If using OIDC, the user's
# full name and email address must be present in the token claimed.
# Recommended OIDC scopes: openid email profile
headerAuth:
  enabled: false
  email:
    header: ""
    claim: email
  jwt:
    header: ""
  user:
    header: ""
    claim: name

# If using Istio, the chart can optionally configure an Istio Gateway and VirtualService to route traffic to the control plane. You can also export the gateway credential for use in external DNS and TLS configuration.
istio:
  enabled: false
  inject: true
  gateway:
    name: ""
    create: false
    # Istio
    credentialName: istio-gateway-certificate-tls