What does helm package --sign write beside the .tgz, and what is inside that file?
answer
- A sidecar, not something inside the chart
- Readable text with a signature wrapped around
- Metadata plus one hash line
- files: maps the tarball to sha256
- Signature binds packaged bytes, not sources
basics
~10 sIt writes <chart>-<version>.tgz.prov: a clear-signed OpenPGP document whose readable body is the chart's metadata plus a files: block mapping the tarball name to its SHA-256, with the signature armoured underneath.
solid answer
~40 s`helm package --sign --key <name> --keyring <secret-keyring>` produces two artifacts: the usual `maildigest-2.14.3.tgz` and a sidecar `maildigest-2.14.3.tgz.prov`. The `.prov` is clear-signed, so its body is plain readable text you can open in an editor: the chart's metadata (the `Chart.yaml` fields — name, version, appVersion, description and so on) followed by a `files:` map with one entry, the tarball's filename and its `sha256:` digest. Underneath sits the armoured OpenPGP signature over that whole body. Two consequences matter. First, the signature binds the *packaged bytes*, through the digest, not the chart source directory — re-tarring or re-packaging the chart invalidates it even if no file changed. Second, everything inside the tarball is covered by that one digest: templates, `values.yaml`, `values.schema.json`, `crds/` and any subcharts vendored under `charts/`.
code
text · 15 lines-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
apiVersion: v2
name: maildigest
description: Builds and sends the daily email digest
version: 2.14.3
appVersion: "1.9.7"
...
files:
maildigest-2.14.3.tgz: sha256:9f2c1a7d3b6e04c58ab71d2f4e07c913
-----BEGIN PGP SIGNATURE-----
wsBcBAEBCgAQBQJ...
-----END PGP SIGNATURE-----go deeper
Know that signing produces a second file whose name is the tarball's name plus .prov, and that it lives beside the chart rather than inside it. Being able to name the artifact is most of what is asked at this level.
Explain the contents: clear-signed text holding chart metadata and a files: block with the tarball's SHA-256. Be able to say how verification uses it — recompute the digest, compare, then check the signature over the document.
Draw the practical conclusion: the signature binds packaged bytes, so any mirror or job that re-packages a chart invalidates provenance even when no file changed. That single fact explains most verification failures you will be asked to debug.
Treat it as an interface between your publishing process and every consumer. Decide what the metadata in a signed document is allowed to claim, what your organisation's key is asserting when it signs bytes it did not author, and how that survives a key rotation.
A Helm provenance file is much less mysterious than it sounds: it is a short YAML-ish document with a PGP clear-signature wrapped around it, sitting next to the chart tarball in the same directory or on the same repository server. ### How it is produced ```bash helm package --sign --key 'platform-releases' \ --keyring ~/.gnupg/secring.gpg maildigest/ ``` This does the normal packaging work — read `Chart.yaml`, apply `.helmignore`, tar and gzip the directory into `maildigest-2.14.3.tgz` — and then, because `--sign` was given, computes the SHA-256 of that finished tarball, assembles a small document, and clear-signs it with the named private key. The result is `maildigest-2.14.3.tgz.prov`. `--key` selects which key to use; `--keyring` here points at the **secret** keyring, unlike verification where it points at a public one. The key's passphrase has to come from somewhere, which is the first thing that bites when you move signing into a build job. ### What is in it ``` -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 apiVersion: v2 name: maildigest description: Builds and sends the daily email digest version: 2.14.3 appVersion: "1.9.7" ... files: maildigest-2.14.3.tgz: sha256:9f2c1a7d3b6e04c58ab71d2f... -----BEGIN PGP SIGNATURE----- ... -----END PGP SIGNATURE----- ``` Two blocks: the chart's metadata, and a `files:` map naming the artifact and its digest. Because it is *clear*-signed rather than encrypted or detached-binary, anybody can read it without a key — you can `cat` a `.prov` and see exactly which chart version it claims to describe and which digest it pins. Only checking the signature needs a key. ### Why the digest is the interesting half The signature covers the document; the document covers the tarball only through that `sha256:` line. So the chain is: trusted key → signed document → digest → bytes on disk. `helm verify` and `helm install --verify` walk that chain in reverse: recompute the digest of the `.tgz` you actually have, compare it to the `files:` entry, then confirm the document's signature. That has a practical consequence people trip over constantly: the provenance binds the *packaged bytes*, not the chart's logical content. If a mirror unpacks and re-packs the tarball, or someone runs `helm package` a second time and publishes the newer tarball with the older `.prov`, verification fails even though every file in the chart is byte-identical — gzip timestamps and member ordering differ, so the digest differs. Helm 4's `helm package` honours `SOURCE_DATE_EPOCH` to make tarballs reproducible, which helps rebuild the same bytes, but the rule stands: sign the artifact you publish, and publish the artifact you signed. ### What the one digest covers Everything inside the tarball, because the tarball is one blob: `templates/`, `values.yaml`, a `values.schema.json` contract, `crds/`, `NOTES.txt`, `_helpers.tpl`, and any subcharts vendored under `charts/`. There is no per-file signature and no partial verification. What it does *not* cover is anything outside the tarball — most importantly the container images the chart's templates reference, which are separate artifacts published on their own schedule. ### The metadata block is not decoration Because the chart metadata is inside the signed body, the `.prov` also ties a specific digest to a specific `name` and `version`. A `.prov` for `maildigest-2.14.3` cannot be passed off as provenance for `2.14.4` — the metadata would say otherwise, and the digest would not match anyway. That is why the file is named after the exact tarball it belongs to. ### Interview shape The crisp answer is: a `.prov` sidecar, clear-signed, containing chart metadata plus the tarball's SHA-256. The good candidate then adds the consequence — the signature is over the packaged bytes, so re-packaging breaks it — because that is the fact that explains almost every real-world verification failure, and it is the fact a reader of the file format actually learns something from.
- Does the signature cover subcharts vendored under charts/ and the manifests in crds/?Yes. There is a single SHA-256 over the whole packaged tarball, so every file it contains is covered: templates, values.yaml, a values.schema.json contract, crds/ and any vendored subcharts. There is no per-file signing and no partial verification. What it does not cover is anything outside the tarball, in particular the container images the templates reference, which are separate artifacts with their own publication path.
- Why does re-running helm package after signing invalidate the existing .prov?Because the .prov pins the SHA-256 of the exact tarball produced at signing time, and a second packaging run produces different bytes — gzip metadata and archive ordering shift even when no file changed. Verification then fails on the digest comparison while the signature itself is fine. Helm 4's helm package honours SOURCE_DATE_EPOCH to make builds reproducible, but the discipline is to publish precisely the artifact you signed.
The .prov is a sealed packing slip taped to the outside of the box: anyone can read what the slip says the box contains and what its tamper number is, but only the sender's seal proves who wrote it — and re-taping the box changes the tamper number.
saying these in an interview costs you the question
- Thinking the .prov lives inside the chart tarball
- Saying the .prov is encrypted and unreadable without a key
- Believing it signs the chart source directory
- Assuming it lists a digest per file in the chart
- Claiming it covers the container images the chart references