Skip to content

feat(flipt, flipt-v2): support image.digest for tamper-resistant pinning#284

Merged
kodiakhq[bot] merged 2 commits into
flipt-io:mainfrom
pawelfraczyk:feat/image-digest-support
May 29, 2026
Merged

feat(flipt, flipt-v2): support image.digest for tamper-resistant pinning#284
kodiakhq[bot] merged 2 commits into
flipt-io:mainfrom
pawelfraczyk:feat/image-digest-support

Conversation

@pawelfraczyk

@pawelfraczyk pawelfraczyk commented May 29, 2026

Copy link
Copy Markdown
Contributor

Problem

Both flipt and flipt-v2 render the container image as:

image: \"{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}\"

so a digest: field added under image: in values is silently ignored. For flipt-v2 the chart's JSON schema (additionalProperties: false on the image block) also rejects it outright.

The workaround today is to embed the digest into the tag:

image:
  repository: docker.flipt.io/flipt/flipt
  tag: v2.8.0@sha256:921350bb9ef4deefa5dc16b8293f446d27c06742502eaf897a8276b12492078a

The OCI runtime honours the trailing @sha256: so it functions correctly, but it diverges from the convention every other widely-used chart uses, where tag: and digest: are separate fields.

What this PR does

Adds an optional image.digest field to both charts. When set, it is appended to the rendered image reference as @<digest>:

image:
  repository: docker.flipt.io/flipt/flipt
  tag: v2.9.0
  digest: sha256:921350bb9ef4deefa5dc16b8293f446d27c06742502eaf897a8276b12492078a

renders as docker.flipt.io/flipt/flipt:v2.9.0@sha256:921350bb….

Behaviour with no digest set is unchanged.

Changes per chart

  • templates/deployment.yaml — append @digest to the image reference when set, via {{- with .Values.image.digest }}@{{ . }}{{- end }}.
  • templates/migration_job.yaml — same (migration job runs the same image).
  • values.yaml — add digest: \"\" with explanatory comment.
  • values.schema.json — add digest to image properties (plus, in flipt-v2, this is needed to bypass additionalProperties: false).
  • Chart.yaml — bump version (flipt 0.87.6 → 0.88.0, flipt-v2 2.9.2 → 2.10.0).
  • README.md — document the new value.

Verification

```bash
helm template t charts/flipt-v2

-> image: "docker.flipt.io/flipt/flipt:v2.9.0" (unchanged)

helm template t charts/flipt-v2 --set image.digest=sha256:921350bb…

-> image: "docker.flipt.io/flipt/flipt:v2.9.0@sha256:921350bb…"

helm template t charts/flipt-v2 --set image.tag=v2.8.0 --set image.digest=sha256:921350bb…

-> image: "docker.flipt.io/flipt/flipt:v2.8.0@sha256:921350bb…"

```

`helm lint` passes for both charts. CI `ct lint` + `ct install` should also pass — the change is additive and backward-compatible.

Why this matters

Pinning by digest is the canonical defence against tag republishing (the same v2.9.0 tag can be re-pushed to a different image at any time). With this PR, users can pin via the standard chart-author pattern instead of having to know about the embed-in-tag trick.

Both charts currently render the image reference as
  {{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}
which means a `digest:` field under `image:` in values.yaml is silently
ignored at the template layer — and for flipt-v2 it's also rejected by
the JSON schema (`additionalProperties: false` on the image block).

That forces digest-pinning users to embed the digest into the tag:
  tag: v2.8.0@sha256:921350bb…
which works (the OCI runtime honours the `@sha256:` suffix) but
diverges from the convention every other chart in the ecosystem uses
(separate `tag:` + `digest:` fields — bitnami, datadog, external-secrets,
cert-manager, etc).

This change adds an optional `image.digest` field to both charts. When
set, it is appended to the rendered image reference as `@<digest>`, so
the final string is `repo:tag@digest`. Behaviour with no digest is
unchanged.

Changes per chart:
- templates/deployment.yaml: append `@digest` when set
- templates/migration_job.yaml: same (job runs the same image)
- values.yaml: add `digest: ""` with a comment
- values.schema.json: add `digest` to image properties
- Chart.yaml: bump chart version (flipt 0.87.6 -> 0.88.0,
                                  flipt-v2 2.9.2 -> 2.10.0)
- README.md: document the new value

Rendered output, verified via `helm template`:
- no digest set         -> repo:tag                  (unchanged)
- digest only           -> repo:chartAppVersion@digest
- tag + digest          -> repo:tag@digest

`helm lint` passes for both charts.
@pawelfraczyk pawelfraczyk requested a review from a team as a code owner May 29, 2026 06:15

@erka erka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @pawelfraczyk for doing this.

Comment thread charts/flipt-v2/Chart.yaml Outdated
Comment thread charts/flipt/Chart.yaml Outdated
@erka

erka commented May 29, 2026

Copy link
Copy Markdown
Contributor

It's probably possible to modify update action to inject digest when a new Flipt version is released.

Per maintainer review (@erka), the helm chart's major version is kept in
lockstep with the upstream app major version by the release pipeline.
Drop the minor bumps back to patch bumps:

- charts/flipt:    0.88.0 -> 0.87.7
- charts/flipt-v2: 2.10.0 -> 2.9.3
@pawelfraczyk

Copy link
Copy Markdown
Contributor Author

Versions adjusted per review — flipt is now 0.87.7 and flipt-v2 is now 2.9.3 (patch bumps, in line with the release-pipeline convention you described). Thanks for the quick review @erka 🙏

@erka erka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @pawelfraczyk

@erka erka added the automerge label May 29, 2026
@kodiakhq kodiakhq Bot merged commit 96fedd8 into flipt-io:main May 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants