How to Use Chainguard Helm Charts

A primer on how to use Chainguard-produced Helm charts to deploy Chainguard container images, including iamguarded Helm charts
  8 min read

Helm is a package manager for Kubernetes that simplifies the installation and management of applications by automating the creation of Kubernetes resources. Helm charts are reusable, versioned packages that define a collection of Kubernetes resources required to run an application or service. You use Helm to define, install, and perform upgrades to your applications on Kubernetes.

For organizations looking to deploy their Chainguard container images with Helm, Chainguard provides upstream-produced Helm charts. These charts are available from the Chainguard Registry and are intended for customers who are either looking to get started with Helm or are looking for better, trusted alternatives to the public charts they may already be using.

Chainguard also offers a limited set of Helm charts to go with a set of Chainguard-created containers labeled as iamguarded, designed specifically to support organizations migrating off of Bitnami. The iamguarded charts are forked from upstream Bitnami charts, but now configured out-of-the box for use with Chainguard’s hardened container images. These charts only receive edits necessary to make them work with Chainguard container images and retain the intended functionality of the originals they are based on. Because the iamguarded charts are forks, they may be susceptible to breaking changes introduced by the upstream. In such cases, customers should plan to transition to a community-provided alternative (or an equivalent one from Chainguard) where possible.

These charts have been tested by Chainguard to confirm they produce expected deployment results using the following policies.

  • For the community charts:

    • Version streaming: Chainguard commits to supporting chart and image versions that match the latest upstream project chart. Within that latest chart we will support the associated image versions.
    • Testing policy: We test the latest charts with the supported version streams and functionally validate by deploying the Helm chart in its representative environment and exercising the various functionality of the chart(s). We’ll also continue publishing end-of-life (EOL) version streams as long as they continue to pass our functional validation.
  • For the iamguarded charts:

    • We only build the latest/mainline versions of iamguarded images and test them against the latest version of the corresponding iamguarded Helm charts.

For both types, Chainguard makes the provenance of these charts clear. Helm charts are packaged as OCI artifacts using the upstream version adding an appended revision suffix for updates that include material changes to the chart; otherwise, tags will float based as their dependent images update. The OCI artifacts are signed and generate provenance attestations that link to the exact image digests used to ensure that all artifacts are cryptographically verifiable end-to-end for integrity and origin.

The following is an instructional guide for Chainguard users that are looking for Helm charts to use with their Chainguard container images. There are both similarities and differences for installing the two types of charts. The differences are labeled where they occur.

Configuration Requirements

If you are pulling container images directly from Chainguard, then you must set a global.org value. You don’t need this if you are pulling from your own internal registry.

You can set a global.org value using a --set flag during installation, as shown in this example:

helm install grafana oci://cgr.dev/$ORGANIZATION/charts/grafana \
  --set "global.org=$ORGANIZATION"

Or in this example for iamguarded charts:

helm install rabbitmq oci://cgr.dev/$ORGANIZATION/iamguarded-charts/rabbitmq \
  --set "global.org=$ORGANIZATION"

Alternately, you can set this value in a YAML file:

global:
  org: $ORGANIZATION

In addition, users who mirror images to custom repositories should use global.imageRegistry to override the default cgr.dev. If you have a complex mirroring strategy, consult the chart’s values.yaml for individual image configuration options including registry, repository, tag and digest. Here’s a sample from the RabbitMQ iamguarded chart documentation:

image:
  registry: myregistry.example.com
  repository: mirrored/rabbitmq-iamguarded
  digest: sha256:... # Use specific digest instead of tag

# OS Shell image for volume permissions
volumePermissions:
  enabled: true
  image:
    registry: myregistry.example.com
    repository: mirrored/os-shell-iamguarded
    digest: sha256:... # Use specific digest instead of tag

Authentication

You will need to authenticate to pull charts. These instructions explain how to use charts and images with the cgr.dev repository. If you have mirrored or copied the charts and images to an organization-specific registry, you will need to adapt these instructions to authenticate to your registry, as appropriate.

This section presents multiple authentication methods:

  • Use Helm values with global.imagePullSecrets
  • Deploy a Chainguard Helm chart using a Kubernetes pull secret
  • Use cluster node-scoped registry permissions

Use Helm values with global.imagePullSecrets

When performing authentication via a global.imagePullSecrets key-value pair, include the following in your values.yaml file.

global:
  imagePullSecrets:
    - name: chainguard-pull-secret

Deploy a Chainguard Helm chart using a Kubernetes pull secret

To begin, authenticate with chainctl and generate a pull token.

chainctl auth login
chainctl auth configure-docker --pull-token --save --ttl=24h

This token expires in 24 hours by default, which can be modified using the --ttl flag. It sets the duration for the validity of the token. The maximum valid value is 8760h (equivalent to 365 days), Valid unit strings range from nanoseconds to hours and are ns, us, ms, s, m, and h, for example --ttl=24h.

Find the username and password that are contained in the pull token, as in this sample output:

chainctl auth configure-docker --pull-token --save --ttl=24h
                                    
  ✔ Selected folder chainguard.edu.

To use this pull token in another environment, run this command:

    docker login "cgr.dev" --username "45a0c61ea6fd977f050c5fb9ac06a69eed764595/095b0c7ea9d68679" --password "eyJhbGciOiJSUzI1NiJ9.eyJhdWQ... # Token truncated"

Configuring identity "45a0c61ea6fd977f050c5fb9ac06a69eed764595/095b0c7ea9d68679" for pulls from cgr.dev (expires 2025-06-12T09:27:45-05:00).
Overwriting existing credentials.

Save the credentials as variables, like this.

HELMUSER=45a0c61ea6fd977f050c5fb9ac06a69eed764595/095b0c7ea9d68679

HELMPASS=eyJhbGciOiJSUzI1NiJ9.eyJhdWQ... # Token truncated

Create your Kubernetes secret using the variables you just created.

kubectl create secret docker-registry chainguard-pull-secret \
  --docker-server=cgr.dev \
  --docker-username=$(echo $HELMUSER) \
  --docker-password=$(echo $HELMPASS) \
  -n <your-namespace>

Log in to the cgr.dev Helm registry.

helm registry login cgr.dev \
  --username=$HELMUSER \
  --password=$HELMPASS

Reference the secret in your Helm installation:

helm install grafana oci://cgr.dev/$ORGANIZATION/charts/grafana \
  --set "global.org=$ORGANIZATION" \
  --set "global.imagePullSecrets[0].name=chainguard-pull-secret"

Or for imguarded charts:

helm install rabbitmq oci://cgr.dev/$ORGANIZATION/iamguarded-charts/rabbitmq \
  --set "global.org=$ORGANIZATION" \
  --set "global.imagePullSecrets[0].name=chainguard-pull-secret"

When the install is successful, it returns a confirmation message, like this:

Pulled: cgr.dev/chainguard.edu/charts/grafana:10.5.13
Digest: sha256:2629f907b15f26c706b5668b5700340b851176a10f55cf709f89a3701f2b4220
NAME: grafana
LAST DEPLOYED: Thu Jan 29 08:19:23 2026
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:

   kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo


2. The Grafana server can be accessed via port 80 on the following DNS name from within your cluster:

   grafana.default.svc.cluster.local

   Get the Grafana URL to visit by running these commands in the same shell:
     export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=grafana" -o jsonpath="{.items[0].metadata.name}")
     kubectl --namespace default port-forward $POD_NAME 3000

3. Login with the password from step 1 and the username: admin
#################################################################################
######   WARNING: Persistence is disabled!!! You will lose your data when   #####
######            the Grafana pod is terminated.                            #####
#################################################################################

Use cluster node-scoped registry permissions

If you manage access and permissions at cluster-wide and node-specific levels, these are some best practices to consider.

Pin to tag: The best practice for community charts (not iamguarded) is to pin to the image tag, like this:

helm install grafana oci://cgr.dev/$ORGANIZATION/charts/grafana --version 10.5.13 \
  --set "global.org=$ORGANIZATION"

For imguarded charts, instead pin to digest.

For iamguarded, pin to digest: While charts follow the same tagging scheme as Chainguard images, always pin to a specific chart digest to prevent unexpected updates:

helm install rabbitmq \ 
oci://cgr.dev/$ORGANIZATION/iamguarded-charts/rabbitmq@sha256:DIGEST \
  --set "global.org=$ORGANIZATION"

Review Default Values: The chart provides security-minded defaults that are sensible but may not suit all use cases. Review the chart’s values.yaml for the full range of configuration options and adjust as needed.

Helm chart usage examples

Install with details passed in a flag

To install a Helm chart using standard Helm commands and passing details as flag values in the command itself, add the flags and values at the end like this example, substituting your organization for $ORGANIZATION.

helm install grafana oci://cgr.dev/$ORGANIZATION/charts/grafana \
  --set "global.org=$ORGANIZATION"

Or for imguarded charts:

helm install rabbitmq oci://cgr.dev/$ORGANIZATION/iamguarded-charts/rabbitmq \
 --set "global.org=$ORGANIZATION"

Install with details in a file

Alternatively, you can put values in a file, such as our values.yaml sample, and then refer to the file in your install command.

image:
  registry: cgr.dev
  repository: $ORGANIZATION/grafana # replace $ORGANIZATION
  tag: latest # pin to specific version instead of latest

Then you refer to the file like this:

helm install grafana oci://cgr.dev/$ORGANIZATION/charts/grafana \
  --values ./values.yaml

Or for imguarded charts:

helm install test oci://cgr.dev/$ORGANIZATION/iamguarded-charts/rabbitmq \
--values ./values.yaml

Installing on AWS Elastic Kubernetes Service (EKS) Auto Mode

When installing on EKS Auto Mode, you may need to create a storage class for the Helm chart’s pod(s). This can be done by creating a storage class:

cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gp3-automode
provisioner: ebs.csi.eks.amazonaws.com
parameters:
  type: gp3
  encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
EOF

You then pass the storage class’s name to the helm install command. Here, we use grafana as an example:

helm install grafana oci://cgr.dev/$ORGANIZATION/charts/grafana \
  --set "global.org=$ORGANIZATION" \
  --set "global.imagePullSecrets[0].name=chainguard-pull-secret" \
  --set "persistence.storageClass=gp3-automode"

Or, like this for iamguarded, using rabbitmq as an example:

helm install rabbitmq oci://cgr.dev/$ORGANIZATION/iamguarded-charts/rabbitmq \
  --set "global.org=$ORGANIZATION" \
  --set "global.imagePullSecrets[0].name=chainguard-pull-secret" \
  --set "persistence.storageClass=gp3-automode"

Troubleshooting

To check the Helm configuration, you can run helm install with --dry-run flag. This will output the generated Kubernetes YAML. Double check the values for the image and imagePullSecrets to ensure they point to the correct registry and authentication is in place.

To see the files, run:

helm pull --untar oci://cgr.dev/$ORGANIZATION/charts/grafana \

Or for imguarded charts:

helm pull --untar oci://cgr.dev/$ORGANIZATION/iamguarded-charts/rabbitmq

To get the values.yaml so you can examine it, run:

helm show values oci://cgr.dev/$ORGANIZATION/charts/grafana \

Or for imguarded charts:

helm show values oci://cgr.dev/$ORGANIZATION/iamguarded-charts/rabbitmq

See the Helm commands documentation for more information.

Last updated: 2026-01-29 08:49