Skip to content

Installation

Prerequisites

  • Kubernetes v1.16+
  • Helm 3.0+
  • kubectl configured to access your cluster
  • A supported storage backend (S3 bucket, Azure Storage Account, GCS bucket, or local filesystem)
  • (Optional) A GitHub App for authenticated API access

If you plan to use OIDC authentication and tofu login, also prepare:

  • An OIDC issuer (Dex via Helm subchart or an external OIDC provider)
  • A registered OIDC client for OpenDepot (client ID/secret)
  • Externally reachable OIDC auth/token endpoints advertised in service discovery (login.v1)
  • (Optional) GroupBinding resources for fine-grained module/provider access control

See OIDC Configuration for full setup details and examples.

Install with Helm

Minimal install

For a quick start, the one-liner below is all you need. OpenDepot will use in-cluster defaults. Customise with --set flags or a values file once you're ready.

helm repo add opendepot https://tonedefdev.github.io/opendepot
helm repo update
helm install opendepot opendepot/opendepot \
  -n opendepot-system \
  --create-namespace

Upgrading an existing installation

Helm does not update CRDs during helm upgrade. If you are upgrading from a previous version, apply the latest CRDs manually first:

helm show crds opendepot/opendepot | kubectl apply --server-side -f -

To customize values:

helm install opendepot opendepot/opendepot \
  -n opendepot-system \
  --create-namespace \
  --set global.image.tag=v0.1.0 \
  --set server.service.type=ClusterIP \
  --set depot.enabled=false

Or use a values file:

helm install opendepot opendepot/opendepot \
  -n opendepot-system \
  --create-namespace \
  -f my-values.yaml

Helm Chart Values

Full Helm values reference

The tables below list every configurable Helm value. Most defaults are sensible for a standard installation — focus on global.image.tag, your storage backend, and server.ingress or server.tls for production.

Global

Value Default Description
global.namespace opendepot-system Namespace for all resources
global.imagePullPolicy IfNotPresent Image pull policy
global.image.tag "" Image tag for all services (defaults to Chart.AppVersion when empty)

Server

Value Default Description
server.enabled true Deploy the server
server.replicaCount 1 Number of replicas
server.anonymousAuth false Use the server's service account for unauthenticated module access (see note below)
server.useBearerToken true Use bearer token auth instead of kubeconfig
server.image.repository ghcr.io/tonedefdev/opendepot/server Server image
server.service.type LoadBalancer Service type
server.service.port 80 Service port
server.service.targetPort 8080 Container port
server.tls.enabled false Enable TLS on the server
server.tls.certPath /etc/tls/tls.crt Path to TLS certificate
server.tls.keyPath /etc/tls/tls.key Path to TLS key
server.ingress.enabled false Enable Kubernetes Ingress
server.ingress.istio.enabled false Enable Istio VirtualService
server.ingress.istio.hosts [opendepot.defdev.io] Istio VirtualService hosts
server.resources.requests.cpu 100m CPU request
server.resources.requests.memory 128Mi Memory request
server.resources.limits.cpu not set CPU limit
server.resources.limits.memory 512Mi Memory limit
server.nodeSelector {} Node selector
server.tolerations [] Tolerations
server.affinity {} Affinity rules
server.podDisruptionBudget.enabled false Enable PDB
server.podDisruptionBudget.minAvailable 2 Minimum available pods
server.ingress.hosts see values.yaml Standard Ingress host/path rules
server.ingress.tls [] Standard Ingress TLS configuration

Server OIDC

Value Default Description
server.oidc.enabled false Enable OIDC token validation for registry requests
server.oidc.issuerUrl "" OIDC issuer URL (auto-derived from Dex when blank and dex.enabled=true)
server.oidc.clientId opendepot OIDC client ID used by tofu login
server.oidc.clientSecretName "" Existing Secret name containing OIDC client secret
server.oidc.clientSecret "" OIDC client secret used to create chart-managed Secret when clientSecretName is blank
server.oidc.groupsClaim "" JWT claim name containing groups (defaults to groups in server flag behavior)
server.oidc.allowServiceAccountFallback false Allow Kubernetes SA bearer tokens when OIDC is enabled
server.oidc.allowClientCredentials false Allow Dex client-credentials tokens and map sub to client:<sub> for GroupBinding evaluation
server.oidc.authzUrl "" Override login.v1.authz URL advertised in service discovery
server.oidc.tokenUrl "" Override login.v1.token URL advertised in service discovery

Valkey Stats Store

Download statistics are persisted in a bundled Valkey (Redis-compatible) instance that is always deployed as part of the chart. No extra configuration is required to enable stats — they are always on.

Value Default Description
valkey.resources see values.yaml Resource requests and limits for the Valkey pod
valkey.dataStorage.enabled true Create a PVC for Valkey data. When false, stats are stored on an ephemeral in-pod volume and lost on restart
valkey.dataStorage.className "" StorageClass for the PVC. Leave blank to use the cluster default
valkey.dataStorage.requestedSize 1Gi PVC storage size
valkey.auth.enabled false Enable Valkey ACL password authentication
valkey.auth.usersExistingSecret "" Name of a pre-existing Secret whose keys are ACL usernames. Required when auth is enabled
valkey.auth.aclUsers.default.permissions ~stats:* &* -@all +HSET +HINCRBY +HGET +HGETALL +INCR +GET +ZINCRBY +ZREVRANGEBYSCORE +ZREVRANGE +EXPIREAT ACL permissions string for the default user. Scoped to stats:* keys and only the commands used by the server — do not widen to +@all in production
server.stats.valkeyPasswordSecretName "" Name of the Secret injected as OPENDEPOT_VALKEY_PASSWORD into the server. Must match valkey.auth.usersExistingSecret
valkey.nodeSelector {} Node selector for the Valkey pod
valkey.tolerations [] Tolerations for the Valkey pod
valkey.affinity {} Affinity rules for the Valkey pod

Set valkey.dataStorage.enabled: false for local Kind clusters or ephemeral environments where no StorageClass is available. For production, leave persistence enabled (the default) so stats survive pod restarts.

Production Security

Valkey ACL authentication is disabled by default. For production deployments, create a Kubernetes Secret containing the password, then set valkey.auth.enabled: true, valkey.auth.usersExistingSecret, and server.stats.valkeyPasswordSecretName to match. Use External Secrets Operator or HashiCorp Vault to provision the Secret in regulated environments.

Controllers

These values apply to version, module, depot, and provider independently:

Value Default Description
<service>.enabled true (provider: false) Deploy the controller
<service>.replicaCount 1 Number of replicas
<service>.image.repository ghcr.io/tonedefdev/opendepot/<service>-controller Image repository
<service>.image.tag "" Overrides global.image.tag when set
<service>.resources.requests.cpu 100m CPU request
<service>.resources.requests.memory version: 512Mi, others 128Mi Memory request
<service>.resources.limits.cpu not set CPU limit
<service>.resources.limits.memory version: 4Gi, others 512Mi Memory limit
<service>.nodeSelector {} Node selector
<service>.tolerations [] Tolerations
<service>.affinity {} Affinity rules

Note

The provider controller is disabled by default (provider.enabled: false). Enable it explicitly when you are ready to sync provider binaries — provider archives can be several hundred megabytes each.

GPG Signing (Providers)

The server signs SHA256SUMS files for provider packages using a GPG key you supply. OpenTofu verifies this signature as part of the Provider Registry Protocol. You must create a Kubernetes Secret with the following keys and reference it via server.gpg.secretName:

Secret Key Description
OPENDEPOT_PROVIDER_GPG_KEY_ID Short or long hex key ID of the signing key
OPENDEPOT_PROVIDER_GPG_ASCII_ARMOR ASCII-armored public key block (included in the API response so OpenTofu can verify)
OPENDEPOT_PROVIDER_GPG_PRIVATE_KEY_BASE64 Base64-encoded ASCII-armored private key (used by the server to sign SHA256SUMS)
Value Default Description
server.gpg.secretName "" Name of the Kubernetes Secret containing GPG signing credentials

See GPG Signing for Providers in the Configuration section for full setup instructions.

Service Account & RBAC

Value Default Description
serviceAccount.create true Create service accounts
serviceAccount.annotations {} Annotations (use for IRSA/Workload Identity)
rbac.create true Create RBAC roles and bindings
rbac.scopeToNamespace false Use namespace-scoped Role/RoleBinding instead of ClusterRole/ClusterRoleBinding

Storage

Value Default Description
storage.filesystem.enabled false Enable shared volume for filesystem storage
storage.filesystem.mountPath /data/modules Mount path inside containers
storage.filesystem.hostPath "" Use a hostPath volume (for local dev with kind)
storage.filesystem.storageClassName "" StorageClass for PVC (requires ReadWriteMany)
storage.filesystem.size 10Gi PVC storage size

Scanning

Value Default Description
scanning.enabled false Enable Trivy-based scanning (module IaC scanning and scanning image variant)
scanning.providerScanning false Enable provider binary/source scanning (requires scanning.enabled=true)
scanning.cacheMountPath /var/cache/trivy Mount path for Trivy DB cache
scanning.offline true Run Trivy with offline scan mode
scanning.blockOnCritical false Block reconciliation when CRITICAL findings exist
scanning.blockOnHigh false Block reconciliation when HIGH findings exist
scanning.cache.storageClassName "" StorageClass for Trivy DB PVC
scanning.cache.accessMode ReadWriteMany Access mode for Trivy DB PVC
scanning.cache.size 1Gi Trivy DB PVC size
scanning.dbUpdater.schedule 0 2 * * * Cron schedule for DB refresh job
scanning.dbUpdater.image.repository aquasec/trivy Trivy DB updater image repository
scanning.dbUpdater.image.tag 0.70.0 Trivy DB updater image tag

Build from Source (Alternative)

If you prefer to build container images yourself:

# Build all services for linux/arm64
make build

# Load into a kind cluster
make load

# Or build and load in one step
make deploy

Additional Makefile targets:

Target Description
make build Build all container images
make load Load all images into the kind cluster
make deploy Build and load all images
make service NAME=server Build and load a single service
make restart Restart all deployments in opendepot-system
make redeploy Build, load, and restart all services
make kind-restart Full cluster recreation with Istio, TLS, gateway, and Helm deploy (for production-like local setup)

Configurable variables:

Variable Default Description
PLATFORM linux/arm64 Target platform for container builds
KIND_CLUSTER kind Name of the kind cluster
TAG dev Image tag for all services
REGISTRY ghcr.io/tonedefdev/opendepot Container registry prefix