Helm chart standard
Distribution and versioning
The onboarding scan and the repository guardrails check a project's charts statically against this standard (chart.values, chart.secure_defaults, chart.image_digest, chart.helper, chart.schema), reading the files through the GitHub API without rendering or installing anything.
- Charts use
apiVersion: v2. The chartversionis SemVer and independent ofappVersion. - Charts are distributed as OCI artifacts from
oci://registry.commonlayer.org/charts/<chart>, signed with cosign, with provenance attached — the same verification as images. - The platform's verification policy checks that a chart's default images are digests of promoted CommonLayer images and that the chart ships a
values.schema.json.
Image references
Image configuration is explicit in values.yaml:
image:
registry: registry.commonlayer.org
repository: nginx
tag: "1.30.6-r1" # informational when digest is set
digest: "sha256:…" # the released digest; takes precedence
pullPolicy: IfNotPresentWhen a digest is set the chart renders registry/repository@digest; otherwise registry/repository:tag. Released charts ship with the digest filled in by the release workflow, so installing a chart version always installs exactly the images it was tested with. Setting image.digest: "" is the documented, explicit way to follow a tag instead.
Common values
Every chart offers these values blocks under the same names, so they can be set the same way everywhere:
| Area | Values |
|---|---|
| Naming and metadata | imagePullSecrets, nameOverride, fullnameOverride, commonLabels, commonAnnotations, podAnnotations, podLabels |
| Identity | serviceAccount.{create, name, annotations, automountServiceAccountToken} |
| Security | podSecurityContext, containerSecurityContext, networkPolicy |
| Resources and health | resources, livenessProbe, readinessProbe, startupProbe |
| Networking | service |
| Scheduling and availability | podDisruptionBudget, topologySpreadConstraints, affinity, nodeSelector, tolerations, priorityClassName |
| Storage | persistence (stateful charts) |
| Monitoring | metrics.{enabled, serviceMonitor} |
| Extension | extraEnv, extraVolumes, extraVolumeMounts |
values.schema.json validates every value, so a typo fails at install time instead of being ignored. The values table in each chart's README is generated with helm-docs.
Secure defaults
| Setting | Default |
|---|---|
| runAsNonRoot | true, UID and GID 10001, fsGroup 10001 |
| allowPrivilegeEscalation | false |
| capabilities | drop: [ALL] |
| readOnlyRootFilesystem | true, with emptyDir volumes for the documented writable paths |
| seccompProfile | RuntimeDefault |
| Service account token | Not mounted |
| Resources | Requests and limits set |
| NetworkPolicy | Available; default-deny when enabled |
Labels and helpers
Every object carries app.kubernetes.io/{name, instance, version, component, part-of, managed-by}, helm.sh/chart and the user's commonLabels. Names, labels, image references and security contexts come from one shared helper file, templates/_commonlayer.tpl, which is byte-identical in the project template and in every CommonLayer chart; CI checks that it has not drifted. No third-party library chart is used.
Tests
helm lint --strict.helm templatewith the default values and every file inchart/ci/, validated withkubeconform -strict.helm unittestsuites inchart/tests/.- A policy check with
trivy configand no high findings. - Install and upgrade tests on a kind cluster in CI: install the previous release, upgrade to the working tree, run
helm test.
Images used by charts follow the container image standard.