Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ jobs:
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.

# release.yml pins the controller-manager image (below) but NOT the cortex-built
# AuthBridge injection images; they were shipping at :latest (rossoctl/rossoctl#508).
# 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.

echo "::error::injected AuthBridge image(s) pinned to a floating tag — pin to a cortex release tag before releasing (rossoctl/rossoctl#508)"
exit 1
fi
echo "AuthBridge injected images are version-pinned OK"

- name: Package and push Helm chart
run: |
chartVersion=$(echo "${{ github.ref_name }}" | cut -c 2-)
Expand Down
8 changes: 4 additions & 4 deletions charts/operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,10 @@ featureGates:
# proxy-sidecar / lite mode (always-on enforce-redirect egress capture).
defaults:
images:
envoyProxy: ghcr.io/rossoctl/cortex/authbridge-envoy:latest
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.

authbridge: ghcr.io/rossoctl/cortex/authbridge:v0.7.0-alpha.3
authbridgeLite: ghcr.io/rossoctl/cortex/authbridge-lite:v0.7.0-alpha.3
proxyInit: ghcr.io/rossoctl/cortex/proxy-init:v0.7.0-alpha.3
pullPolicy: IfNotPresent

# Proxy settings
Expand Down
Loading