Skip to content
CommonLayer

Helm chart standard

Version 1. Every CommonLayer chart is built to these rules, so that charts from different projects behave the same way and are safe by default.

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 chart version is SemVer and independent of appVersion.
  • 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: IfNotPresent

When 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:

Common values blocks
AreaValues
Naming and metadataimagePullSecrets, nameOverride, fullnameOverride, commonLabels, commonAnnotations, podAnnotations, podLabels
IdentityserviceAccount.{create, name, annotations, automountServiceAccountToken}
SecuritypodSecurityContext, containerSecurityContext, networkPolicy
Resources and healthresources, livenessProbe, readinessProbe, startupProbe
Networkingservice
Scheduling and availabilitypodDisruptionBudget, topologySpreadConstraints, affinity, nodeSelector, tolerations, priorityClassName
Storagepersistence (stateful charts)
Monitoringmetrics.{enabled, serviceMonitor}
ExtensionextraEnv, 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

Secure defaults
SettingDefault
runAsNonRoottrue, UID and GID 10001, fsGroup 10001
allowPrivilegeEscalationfalse
capabilitiesdrop: [ALL]
readOnlyRootFilesystemtrue, with emptyDir volumes for the documented writable paths
seccompProfileRuntimeDefault
Service account tokenNot mounted
ResourcesRequests and limits set
NetworkPolicyAvailable; 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 template with the default values and every file in chart/ci/, validated with kubeconform -strict.
  • helm unittest suites in chart/tests/.
  • A policy check with trivy config and 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.