Skip to content

fix(release): pin AuthBridge injection images + guard against :latest (#508) - #512

Merged
cwiklik merged 3 commits into
mainfrom
fix/508-pin-authbridge-images
Aug 19, 2026
Merged

fix(release): pin AuthBridge injection images + guard against :latest (#508)#512
cwiklik merged 3 commits into
mainfrom
fix/508-pin-authbridge-images

Conversation

@cwiklik

@cwiklik cwiklik commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

The operator chart pinned the cortex-built AuthBridge injection images (authbridge, authbridge-envoy, authbridge-lite, proxy-init) at :latest in charts/operator/values.yaml. release.yml only pins the controller-manager image, so every published operator-chart shipped :latest for the injected images — non-reproducible (surfaced during the v0.7.0 GA cut).

Changes

  • Pin the 4 AuthBridge injection images :latestv0.7.0-alpha.3 (current cortex release; all 4 images published).
  • Guard in release.yml: fail the release if any injected image is a floating tag (:latest/:main/:master) — so it can't regress silently.

Closes #508

Assisted-By: Claude Code

The operator chart pinned the cortex-built AuthBridge injection images (authbridge, -envoy, -lite, proxy-init) at :latest — non-reproducible, and release.yml only pins the controller-manager image, so every release shipped :latest (#508). Pin them to cortex v0.7.0-alpha.3, and add a release.yml guard that fails the release if any injected image is a floating tag so it can't regress silently.

Closes #508

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: cwiklik <cwiklikj@gmail.com>
@cwiklik
cwiklik requested review from a team as code owners August 19, 2026 14:28

@huang195 huang195 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Dobra robota — the pin is correct and verified: v0.7.0-alpha.3 is cortex's current release (published 14 min before this PR) and cortex's Build-Publish matrix tags all four images with github.ref_name on tag push, run green. Guard logic is sound (CHARTS_PATH resolves, grep under if is errexit-safe).

Three non-blocking notes: the guard fires after the operator images are already pushed, it's a 3-tag deny-list rather than a positive pin assertion, and the compiled Go defaults in defaults.go still carry :latest where the grep can't reach them.

One question: the guard happily passes a prerelease tag, so operator v0.7.0 GA would ship cortex alpha images. Intended, or does the GA cut need a re-pin once cortex has a v0.7.0?


Areas reviewed: CI/GitHub Actions, Helm values · Agent/IDE config (.claude/.vscode): none · Commits: 1, all signed-off: yes · CI: 16 pass, E2E pending

Assisted-By: Claude Code

username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Guard — injected AuthBridge images must be version-pinned (no floating tags)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Guard sits in the release job, which is needs: build-and-push + if: ref_type == 'tag'. By the time it fails, kagenti-operator and agentcard-signer are already built and pushed to ghcr with the release tag — half-published release (images out, chart not), manual cleanup.

Two cheaper spots: a pre-flight job that build-and-push depends on, or the Helm Chart Lint job in security-scans.yaml which runs on every PR — then a :latest regression is caught at review time, not mid-release.

Comment thread .github/workflows/release.yml Outdated
# Fail the release if any is a floating tag so it can never regress silently.
run: |
cd ${{ env.CHARTS_PATH }}/operator
if grep -nE 'ghcr\.io/rossoctl/cortex/[a-z-]+:(latest|main|master)([^0-9a-zA-Z.-]|$)' values.yaml; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Deny-list of 3 tag names + hardcoded registry path. These all pass the guard:

  • no tag at all (.../authbridge-envoy → implicit :latest)
  • :dev / :edge / :nightly
  • any move off ghcr.io/kagenti/kagenti-extensions/

Positive assertion is strictly tighter, and yq is already installed in this job:

for k in envoyProxy authbridge authbridgeLite proxyInit; do
  img=$(yq ".defaults.images.$k" values.yaml)
  [[ "$img" =~ :v[0-9]+\.[0-9]+\.[0-9]+ ]] || { echo "::error::defaults.images.$k not version-pinned: $img"; exit 1; }
done

Keys the check on the 4 values that matter instead of on the registry string.

authbridge: ghcr.io/rossoctl/cortex/authbridge:latest
authbridgeLite: ghcr.io/rossoctl/cortex/authbridge-lite:latest
proxyInit: ghcr.io/rossoctl/cortex/proxy-init:latest
envoyProxy: ghcr.io/rossoctl/cortex/authbridge-envoy:v0.7.0-alpha.3

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Chart layer pinned, compiled fallback not: operator/internal/webhook/config/defaults.go:34-45 still has all four at :latest, and loader.go:45 overlays the ConfigMap on top of CompiledDefaults() (fields absent from the file keep the compiled value). So any deploy without kagenti-platform-config — kustomize make deploy, or webhook.enable=false where the ConfigMap isn't rendered — still injects :latest. The new grep only reads values.yaml, so it will never catch it.

defaults.go already carries a Keep in sync with charts/operator/values.yaml comment for the spiffe-helper config; same treatment fits here.

Related: operator/test/e2e/e2e_suite_test.go:66-69 still pulls :latest (and is missing authbridge-lite), so e2e never exercises the images the chart actually ships.

The chart-layer pin (values.yaml) didn't cover the compiled fallbacks in
config/defaults.go, which loader.go overlays the platform-config ConfigMap
on top of. Any deploy without that ConfigMap (kustomize make deploy, or
webhook.enable=false) therefore still injected :latest — the exact paths the
values.yaml grep guard can't see. Pin all four compiled defaults to
v0.7.0-alpha.3 to match the chart, with a keep-in-sync note.

Also pin the e2e sidecar images (they still pulled :latest, so e2e never
exercised the shipped tags) and add the missing authbridge-lite image.

Addresses review feedback on #512.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: cwiklik <cwiklikj@gmail.com>
….go (#508)

Addresses review feedback on #512 (findings #1 and #2):

- #1 (guard runs too late): the release.yml guard only fired after
  build-and-push had already pushed the operator images, risking a
  half-published release. Add the same check to the Helm Chart Lint job in
  security-scans.yaml, which runs on every PR, so a :latest regression is
  caught at review time.
- #2 (deny-list too loose): replace the 3-tag deny-list with a positive
  :vX.Y.Z assertion over the four defaults.images.* keys (via yq), which also
  rejects untagged/:dev/:edge and registry moves.
- Both checks now also cover operator/internal/webhook/config/defaults.go
  (loader.go overlays the ConfigMap on top of these compiled fallbacks), so a
  regression in the Go defaults is caught too — not just values.yaml.

Verified locally: guard passes on the pinned state and errors on :latest and
untagged images; both workflow files parse.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: cwiklik <cwiklikj@gmail.com>
@cwiklik
cwiklik merged commit c3f9d2b into main Aug 19, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

release.yml doesn't pin injected AuthBridge images (they ship as :latest)

2 participants