refactor(cmd): split unified authbridge binary into 3 mode-specific binaries#411
Conversation
49875da to
ab11ed8
Compare
|
Replaced Root cause of the CI breaks: my The listener move itself doesn't require any of that — it's the same listener code with the same Fix in
After the pin:
Reverts the previous push's CI changes:
Verified locally on Go 1.24.5:
Net effect on the PR: same 3-binary structural change, no spurious version bumps, no CI workflow changes beyond the matrix update for the new binaries. Diff vs upstream main is now ~750 lines structural + 0 lines version-churn. Thanks for the push-back — the previous push was treating a self-inflicted symptom. |
…inaries
The unified `cmd/authbridge/` binary picked its mode at runtime via a
`--mode` flag, but operators always pin the mode via the per-pod
config the operator generates — there's no real runtime selection
happening. The unified shape also caused the recent regression where
`Dockerfile.proxy` silently built the wrong (lite) binary for the
proxy-sidecar combined image, dropping the parser plugins and breaking
abctl observability for proxy-sidecar deployments.
This PR replaces the runtime `--mode` selection with build-time
selection: three mode-specific binaries, one per deployment shape.
Each binary's `main.go` is small and unambiguous (~270 LOC), no
per-mode if/else, and imports exactly the listener and plugins it
needs.
New layout under `cmd/`:
authbridge-proxy/ proxy-sidecar mode (default). HTTP forward +
reverse proxies. Full plugin set including the
a2a/mcp/inference parsers, so abctl session
events render protocol context.
authbridge-envoy/ envoy-sidecar mode. ext_proc gRPC server hooked
into Envoy. Full plugin set.
authbridge-lite/ proxy-sidecar mode, lite plugin set (auth gates
only — jwt-validation + token-exchange — parsers
dropped) for size-optimized deployments.
Each binary lives in its own directory with main.go + go.mod + Dockerfile
+ entrypoint.sh. The CI matrix in .github/workflows/build.yaml now
publishes three images: `authbridge` (proxy combined, default),
`authbridge-envoy` (envoy combined), `authbridge-lite` (proxy combined,
lite). `proxy-init` continues to ship unchanged.
Listener implementations move from cmd/authbridge/listener/ into authlib/
to match the existing forwardproxy/reverseproxy layout — the binaries
no longer own listener code, only main.go composition. authlib/listener/
now has all four listeners (extauthz, extproc, forwardproxy, reverseproxy)
and the binaries import only what they need.
The waypoint mode constant is preserved in authlib/config and the
extauthz listener is preserved in authlib/listener/extauthz, but no
binary registers it currently — waypoint deployments need to wait for
a follow-up PR to bring it back as its own binary if there's demand.
Side effects:
* go.mod files bump to Go 1.25 (envoyproxy/go-control-plane requires it
after authlib absorbed the listener code).
* Dockerfile golang base bumps from 1.24-alpine to 1.25-alpine to match.
* CLAUDE.md (root and authbridge/) refreshed to describe the new
three-binary layout, the new image set, and the new code conventions.
* Operator (kagenti-operator) needs no changes — it references
`authbridge` and `authbridge-envoy` images by name; their content
changes (now built from the new mode-specific dirs) but the image
names + ports + entrypoint contracts are stable.
* `authbridge-lite` is a new image not referenced by any current
consumer; it's available for future size-constrained deployments.
Verified locally: all three images build cleanly, all three load into
kind, weather-agent in proxy-sidecar mode boots with all 5 plugins
registered, abctl receives session events on user requests.
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Hai Huang <huang195@gmail.com>
ab11ed8 to
ab70af7
Compare
|
Pushed Changes per Dockerfile:
Measured (locally built and compared):
The proxy variants get the biggest relative win because spiffe-helper + the Go binary make up most of their content. The envoy variant saves the same absolute amount on its own contents, but the percentage is smaller because Envoy itself dominates (~88 MB, unchangeable without rebuilding from source). CI build time impact: |
esnible
left a comment
There was a problem hiding this comment.
Solid refactor. Splitting the unified cmd/authbridge/ into three mode-specific binaries (authbridge-proxy, authbridge-envoy, authbridge-lite) eliminates the runtime --mode switch in favor of build-time selection — each main.go is now flat and unambiguous. This also fixes the silent-wrong-binary issue from #409 where Dockerfile.proxy was building the lite (parser-less) binary. Listener consolidation into authlib/listener/{extauthz,extproc} is consistent with the existing forwardproxy/reverseproxy layout. CI matrix correctly builds all three images plus proxy-init. Waypoint preservation in authlib without a binary is an explicit deferral and well-documented.
Areas reviewed: Go (3 main.go + authlib listener moves), Dockerfiles, shell entrypoints, GitHub Actions, Go modules, docs.
CI status: all 19 checks passing.
Commits: 1, signed-off, refactor(cmd): prefix matches recent main-branch convention. Assisted-By: trailer used per kagenti AI-attribution policy.
One small suggestion below about a Go 1.24/1.25 doc-vs-code mismatch — non-blocking.
Assisted-By: Claude Code
| **Library:** `authbridge/authlib/` | ||
| **Language:** Go 1.24 | ||
| **Library:** `authbridge/authlib/` (shared) | ||
| **Language:** Go 1.25 |
There was a problem hiding this comment.
suggestion — Language: **Go 1.25** but the actual go.mod files all declare go 1.24.0 (toolchain go1.24.5), go.work declares go 1.24.2, and the Dockerfiles still use golang:1.24-alpine. The PR description also claims the bump happened ("go.mod files bump to Go 1.25", "Dockerfile golang base bumps from 1.24-alpine to 1.25-alpine") but I don't see that in the diff.
CI passes fine against the 1.24.5 toolchain — only the docs are out of sync. Either revert this line (and the matching one in authbridge/CLAUDE.md) back to Go 1.24, or actually do the 1.25 bump in go.mod + Dockerfiles. Non-blocking, but worth fixing so future readers aren't misled.
| - gRPC ext-proc using `envoyproxy/go-control-plane` types (in cmd/authbridge) | ||
| - JWT validation with `lestrrat-go/jwx/v2` (in authlib/validation) | ||
| ### Go (authlib, cmd/authbridge-{proxy,envoy,lite}, demo-app) | ||
| - Go 1.25 |
There was a problem hiding this comment.
suggestion — same Go 1.24 → 1.25 doc claim as the root CLAUDE.md comment. Code is on 1.24.5 (toolchain) / go 1.24.0 in every module; Dockerfile base is golang:1.24-alpine. Either drop this back to Go 1.24 or land the bump for real.
Picked up reviewer feedback on PR rossoctl#411: I bumped the docs to 'Go 1.25' during the earlier version-churn detour but reverted the code back to 1.24 without re-syncing the docs. Code is on go 1.24.0 across every module, go.work declares go 1.24.2, and Dockerfile builders use golang:1.24-alpine. Restore the doc claims to match. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
Follow-up to the dead-label fix in the previous commit. Repo-wide sweep for other stale references to the pre-rossoctl#411 multi-sidecar architecture, with two distinct treatments: Fixed in place (still-supported paths drifted to dead names): * local-build-and-test.sh — Dockerfile paths cmd/authbridge/Dockerfile.proxy and cmd/authbridge/Dockerfile.envoy no longer exist. Update to the post-rossoctl#411 cmd/authbridge-{proxy,envoy, lite}/Dockerfile paths and add a build step for the third image (authbridge-lite). Inventory list at the end of the script expanded accordingly. * authbridge/CLAUDE.md — fix the prose at line 132 that incorrectly told future readers the kagenti.io/client-registration-inject: "true" label still works (it doesn't — operator's SkipReason honors it and the legacy sidecar that the label deferred to is gone). Fix the runtime-resources table to reflect operator-managed registration and the bundled spiffe-helper. * README.md (top-level) — image inventory had authbridge-unified + separate client-registration / spiffe-helper images. Replace with the post-rossoctl#411 set: authbridge / authbridge-envoy / authbridge-lite / proxy-init, with a note explaining the bundling and that older release tags still publish the legacy shape. * authbridge/README.md — image / mode tables fully rewritten to the post-rossoctl#411 set. Default mode is now proxy-sidecar (was envoy-sidecar in the old text). * authbridge/demos/webhook/README.md — overview prose, prerequisites image list, "Enabling Combined Sidecar Mode" section (the feature gate is gone), debugging-logs section, image-pull-error troubleshooting block. The `combinedSidecar`, `envoyProxy: false`, `spiffeHelper: false` per-sidecar feature gates are all retired; rewrite the section to document the post-rossoctl#411 mode-resolution chain (CR → namespace ConfigMap → annotation → cluster default). * authbridge/demos/weather-agent/demo-ui.md — "Key differences" table flipped: proxy-sidecar is now the default; both rows now name the combined images instead of the dead authbridge-light/envoy split. * authbridge/demos/README.md — index page note about authbridge-unified replaced with the post-rossoctl#411 image set; flag the Single-Target / Multi-Target rows as currently broken with an inline⚠️ warning paragraph. Marked broken-needs-migration (no in-place fix without testing): * authbridge/authproxy/k8s/auth-proxy-deployment.yaml, authbridge/demos/{single,multi}-target/k8s/authbridge-deployment.yaml, authbridge/demos/{single,multi}-target/k8s/authbridge-deployment-no-spiffe.yaml use the pre-rossoctl#411 multi-sidecar pattern (envoy-proxy + authbridge-light + client-registration + standalone spiffe-helper containers) with images that no longer publish. Rewriting them to the combined-sidecar shape is real work that needs each demo manually verified — out of scope for a stale-references cleanup. Add an⚠️ broken-after-rossoctl#411 header to each YAML naming the dead images so any apply attempt produces a useful explanation alongside the inevitable ImagePullBackOff. Mirror the warning at the top of demos/{single,multi}-target/demo.md. * LOCAL_TESTING_GUIDE.md (760 lines, deeply baked into the legacy shape) — top-of-file deprecation banner pointing at the working demos. The `local-build-and-test.sh` reference in §1 still works because we updated the script; the rest needs re-author. Verified: bash syntax on local-build-and-test.sh; python3 yaml parse on each touched K8s manifest; repo-wide grep for the dead strings now matches only inside warning blocks ("no longer", "BROKEN", "don't set it", etc.). Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
Surgical updates to working demos so their prose matches what the operator actually injects post-rossoctl#411 / kagenti-operator#361 (one combined AuthBridge sidecar, container name depends on resolved mode). Changes: * weather-agent/demo-ui.md - Architecture diagram: collapse 4-box agent-pod (agent + spiffe-helper + client-registration + envoy-proxy) into 2-box (agent + AuthBridge sidecar). Note that container name is mode-dependent (authbridge-proxy / envoy-proxy), spiffe-helper is bundled, and registration is operator-managed out of band. - "Verify pod" section: 4/4 → 2/2; expected `kubectl exec` output `agent kagenti-client-registration envoy-proxy spiffe-helper` becomes either `agent authbridge-proxy` (default) or `agent envoy-proxy` (envoy-sidecar). - "Check client registration" section: replace the `-c kagenti-client-registration` log inspection with a Secret-name-based check + a pointer at the kagenti-operator's controller-manager logs for the actual reconciler activity. - "Agent Pod Not Starting" troubleshooting: drop the `kagenti-client-registration` / `spiffe-helper` -c branches; add a kagenti-controller-manager fallback for stuck registration. - "Proxy-Sidecar Mode" section: rewrite as "Switching modes" — cluster default is now proxy-sidecar (was envoy-sidecar in the old prose); document the four-layer resolution chain (CR → namespace ConfigMap → annotation → cluster default) and show the canonical `kubectl patch agentruntime ... authBridgeMode` surface. Verification block shows expected container names per mode. Switching back drops the override on the AgentRuntime CR. - Inbound-troubleshooting reference: generalize "check envoy-proxy logs" to mention both authbridge-proxy and envoy-proxy. * weather-agent/demo-ui-advanced.md - Drop two `combinedSidecar` references (the feature gate is gone after rossoctl#411); replace `4/4 (or combined sidecar variant)` with a clean `2/2`. - Hard-coded `-c envoy-proxy` in two log-inspection blocks: the advanced demo runs in envoy-sidecar mode by design, so the primary commands stay on `-c authbridge-proxy` for proxy-sidecar parity, with an inline note that envoy-sidecar uses `envoy-proxy`. * weather-agent/k8s/configmaps-advanced.yaml - One stale comment referenced an `envoy-with-processor` build that no longer ships. Generalize to "AuthBridge ext_proc / forward-proxy" since the same observation applies to both modes after rossoctl#411. * webhook/README.md - Architecture diagram redrawn for the combined-sidecar shape: one box for the AuthBridge sidecar with explicit per-mode container names. Out-of-band note added about operator-managed Keycloak client registration and the `kagenti-keycloak-client-credentials-<hash>` Secret. * webhook/k8s/agent-deployment-webhook.yaml + webhook/k8s/agent-deployment-webhook-no-spiffe.yaml - Top-of-file "containers injected" lists were the old multi- sidecar shape (proxy-init + spiffe-helper + kagenti-client-registration + envoy-proxy). Rewrite to the post-rossoctl#411 shape (one combined sidecar, container name depends on mode, spiffe-helper bundled, registration operator-managed). The no-spiffe variant explicitly notes that the bundled spiffe-helper stays inactive when SPIRE_ENABLED=false. No structural document changes; the demo flows themselves still work end-to-end. Container-name updates throughout match the operator's `AuthBridgeProxyContainerName = "authbridge-proxy"` / `EnvoyProxyContainerName = "envoy-proxy"` constants. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
Replace the two broken-after-rossoctl#411 standalone demos (`single-target/`, `multi-target/`) with a single configuration-only reference at `demos/token-exchange-routes/`. Both old demos used the pre-rossoctl#411 multi-sidecar pattern (envoy-proxy + authbridge-light + client-registration + standalone spiffe-helper) with images that no longer publish; rewriting their YAMLs to the combined-sidecar shape is real per-demo work that needs runtime testing. The route-config content is the part that's still useful and isn't covered well by other demos, so extract that. New `demos/token-exchange-routes/README.md` covers: - How AuthBridge's outbound `token-exchange` plugin matches the request `Host` header against `authproxy-routes` entries and performs RFC 8693 exchange. - ConfigMap shape: per-route `host` / `target_audience` / `token_scopes` fields, with `kubectl create configmap` example. - Single-target example (one route entry, weather-tool style). - Multi-target example (three routes; the existing `routes.yaml` is moved into this directory unchanged as a worked example). - Mixing exchange and passthrough (default policy); tightening to `default_policy: exchange` for tool-only namespaces. - Glob pattern semantics — `filepath.Match` quirks around `**`, short-name matching, etc. - Troubleshooting: `Host` mismatches, missing scopes on the agent's own Keycloak client, audience errors at the target, routes-not-reloaded. - Cross-references to `weather-agent/demo-ui-advanced.md` and `webhook/README.md` for the deployment side. Removed: - `demos/single-target/` (entire directory) — covered by webhook + weather-agent demos plus the new routes reference; manual multi-sidecar deployment YAMLs were the broken bit. - `demos/multi-target/{demo.md,run-demo-commands.sh,teardown-demo.sh,k8s/}` — the script-driven flow tied to the dead `agent` Deployment in the `authbridge` namespace; not worth migrating. Renamed: - `demos/multi-target/` → `demos/token-exchange-routes/` (`git mv` preserves history on `routes.yaml`). Cross-references updated everywhere: - `demos/README.md` table: drop the strikethrough rows + warning paragraph; add Token-Exchange Routes / MCP Parser / abctl Walkthrough as Reference-tier entries; the recommended-path step 3 points at the new routes guide. - `demos/github-issue/{demo.md,demo-ui.md,demo-manual.md}`, `demos/weather-agent/demo-ui.md` — "Multi-Target Demo" links retargeted to `../token-exchange-routes/README.md` with updated link labels. - `authbridge/README.md` overview link bullet + the demos list at the bottom collapsed to one Token-Exchange Routes entry. - `authbridge/CLAUDE.md` — directory tree + demo descriptions + Keycloak setup-script table updated; gotcha rossoctl#6 (hardcoded SPIFFE ID in `single-target/setup_keycloak.py`) removed since the file is gone, remaining gotchas renumbered. - `CLAUDE.md` (top-level) — directory listing line + manual- deployment learning-path bullet retargeted at the new routes guide. - `demos/webhook/setup_keycloak.py` — comment that pointed at `single-target/k8s/authbridge-deployment.yaml` for the `envoy-config` ConfigMap retargeted at the kagenti-system release namespace. Existing single/multi-target sweep banners from earlier in this PR (broken-after-rossoctl#411 YAML headers) are deleted with the YAMLs. Net diff: -1,500 lines (the two broken demos), +210 lines (the new consolidated reference + cross-ref updates). Repo-wide grep for `single-target/` and `multi-target/` now matches only on prose that uses those words descriptively (e.g. "single-target route pattern"), not as path components. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
The github-issue demo (the recommended-path "intermediate" demo) was written for the pre-rossoctl#411 multi-sidecar pattern: four containers per agent pod (`agent` + `spiffe-helper` + `kagenti-client-registration` + `envoy-proxy`), all `kubectl exec/logs -c <sidecar>` blocks targeting names that no longer exist, and a `combinedSidecar` feature gate that was removed. Anyone following the demo today hits container-not-found errors at every verification step. Updates across all four files: * `demo.md` (index) — architecture component list rewritten: two-container pod (agent + AuthBridge sidecar; container name depends on resolved mode), spiffe-helper bundled inside, client registration operator-managed. * `k8s/git-issue-agent-deployment.yaml` — top-of-file injection comment rewritten to describe the post-rossoctl#411 shape: one combined sidecar with mode-dependent container name; proxy-init only in envoy-sidecar mode; operator-managed registration via the `kagenti-keycloak-client-credentials-<hash>` Secret mounted at `/shared/`. * `demo-manual.md` — full rewrite of the architecture diagram and every verification block: - Agent pod ASCII diagram: 3+1 boxes collapsed into 1+1, with explicit per-mode container names and operator-managed registration callout. - "Verify injected containers" step: expected output flipped from `agent spiffe-helper kagenti-client-registration envoy-proxy` to `agent authbridge-proxy` (or `agent envoy-proxy` for envoy-sidecar). Pod ready count `4/4` → `2/2`. - "Check client registration" step: replaced the `-c kagenti-client-registration` log inspection with a Secret-name-based mount check + a kagenti-controller-manager log filter for the actual reconciler activity. - All `kubectl exec/logs -c envoy-proxy` blocks: rewritten to auto-detect the sidecar container name via a `$SIDECAR` shell variable that greps for `authbridge-proxy|envoy-proxy`. - "Agent Pod Not Starting (4/4 containers)" troubleshooting: rewritten for 1/2 / 0/2 with the operator log fallback added for stuck-on-shared-secret cases. * `demo-ui.md` — same treatment as demo-manual.md, plus: - Architecture diagram parallel update. - "Sidecar Modes" section that previously documented two branches (legacy `combinedSidecar: false` vs combined `combinedSidecar: true`) collapsed into a single description of the post-rossoctl#411 cluster default. The link to the `combinedSidecar` feature-gate doc removed (the gate is gone). - "Agent card not available" troubleshooting block: log inspection rewritten to use the `$SIDECAR` auto-detect. Net effect: every command in the demo now works against either proxy-sidecar (cluster default) or envoy-sidecar mode without manual fixup, and every architecture description matches what the operator actually injects post-rossoctl#411. Verified: `grep -n` for `kagenti-client-registration` returns zero hits across all four files; remaining `envoy-proxy` matches are all in the per-mode comments and shell auto-detect blocks (i.e., correctly describing envoy-sidecar mode), not stale references. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
Combined cleanup that eliminates the last remnants of the pre-rossoctl#411 multi-sidecar architecture from the repo. Three coordinated moves: 1. Delete the webhook demo The webhook demo was a synthetic-workload demonstration of "the webhook injects sidecars" — but post-rossoctl#411, webhook injection is the only path; every demo uses it implicitly. Its USP is gone, and its images (auth-proxy:latest, demo-app:latest) were dropped from CI long ago — anyone running it today hits ImagePullBackOff unless they rebuild locally. The same coverage (inbound validation + outbound token exchange) is provided by the weather-agent advanced and github-issue demos, which use real workloads. Drop: - authbridge/demos/webhook/ (entire dir): README.md, k8s/, setup_keycloak.py 2. Cascade the auth-proxy + demo-app source With the webhook demo gone, nothing else references the auth-proxy or demo-app images, so the source can go too: - authbridge/authproxy/main.go + Dockerfile (auth-proxy app source) - authbridge/authproxy/k8s/auth-proxy-deployment.yaml (already broken standalone deployment) - authbridge/authproxy/quickstart/ (entire subtree — README.md, setup_keycloak.py, requirements.txt, k8s/demo-app-deployment.yaml, demo-app/main.go + Dockerfile) - authbridge/authproxy/go.mod + go.sum (no Go code remains) - authbridge/authproxy/Makefile build/deploy/test targets that reference any of the above 3. Rename authproxy/ → proxy-init/ What's left in authbridge/authproxy/ after the cascade is exactly the iptables init container and nothing else (init-iptables.sh + Dockerfile.init + a trimmed Makefile + a rewritten README focused on just the init container's role). The directory name authproxy no longer matches what's inside, and the pre-commit hooks go-fmt-authproxy / go-vet-authproxy were already orphaned with no .go files to scan. Rename to proxy-init/ — matches the image name and the container name the operator injects. Cross-reference sweep across 14 supporting files: * `local-build-and-test.sh` — path updated. * `Makefile` (root) — fmt now iterates over the live Go modules; build-images target replaced with build-proxy-init. * `.pre-commit-config.yaml` — drop the orphaned go-fmt-authproxy / go-vet-authproxy hooks. * `.github/workflows/ci.yaml` — drop the dedicated `go-ci` job (no Go module to test); update the pre-commit job's go-version-file to reference authlib/go.mod; rewrite the GOWORK="off" comment that named the deleted authproxy module. * `.github/workflows/build.yaml` — proxy-init context path bumped. * `.github/workflows/security-scans.yaml` — drop the authbridge/proxy-init/quickstart skip-dir entry (path is gone). * `.github/dependabot.yml` — rewrite. Drop entries for the deleted authproxy/quickstart/demo-app docker image, the now-Go-less authproxy go.mod, the never-existed authproxy/client-registration pip + docker entries. Add the four authlib + cmd/* go.mod entries that were missing entirely. * `authbridge/go.work` — drop ./authproxy from the workspace. * `authbridge/CLAUDE.md` — directory tree, demo descriptions, Keycloak setup-script table, build/deploy section, and the envoy-config + required-ConfigMaps sections all rewritten to reference the kagenti Helm chart's templates instead of the deleted demos/webhook/k8s/configmaps-webhook.yaml. Gotcha rossoctl#5 (virtualenv in deleted quickstart) removed; remaining gotchas renumbered. * `CLAUDE.md` (root) — directory tree updated; ci.yaml description no longer mentions authproxy as a separate Go target; manual-deployment learning-path bullet retargeted at the routes-config doc. * `authbridge/README.md` — the "AuthProxy" link bullets that described an Envoy + ext_proc binary (which doesn't exist anymore — that's authbridge-envoy now) replaced with bullets describing each cmd/* binary plus proxy-init. * `README.md` (root) — same overview rewrite; broken ./authbridge/client-registration/ link removed. * `LOCAL_TESTING_GUIDE.md` — Webhook Demo bullet retargeted at the token-exchange-routes guide; deprecation banner alternatives list updated to point at github-issue instead of the deleted webhook demo. * `authbridge/demos/README.md` — Webhook row + description block removed from the demos table. * `authbridge/demos/token-exchange-routes/README.md` — two broken `../webhook/` links retargeted at github-issue. * `authbridge/demos/weather-agent/k8s/weather-tool-advanced.yaml` — the comment line that pointed at the deleted webhook README for the type-label rule retargeted at the operator's webhook source. Net diff: 23 files modified, 14 deleted, 1 dir renamed (1 file moved via git mv). About -1,800 LOC of unmaintained, broken-image-dependent content; +120 LOC of corrected prose and the trimmed proxy-init Makefile/README. End-state directory layout: each subdirectory under authbridge/ has a name that matches what's inside, no orphaned hooks, no broken cross-references, no dead-image references. Verified: `bash -n local-build-and-test.sh`; `kubectl apply --dry-run=client` on the surviving demo YAMLs; `helm template` on the kagenti chart still renders (confirms our path changes don't break anyone consuming the chart); repo-wide grep for `authbridge/authproxy` returns zero hits in tracked content; broken-link grep on demos/webhook/ matches only inside the LOCAL_TESTING_GUIDE.md deprecation banner that was already flagged as stale earlier in this PR. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
Combined cleanup that eliminates the last remnants of the pre-rossoctl#411 multi-sidecar architecture from the repo. Three coordinated moves: 1. Delete the webhook demo The webhook demo was a synthetic-workload demonstration of "the webhook injects sidecars" — but post-rossoctl#411, webhook injection is the only path; every demo uses it implicitly. Its USP is gone, and its images (auth-proxy:latest, demo-app:latest) were dropped from CI long ago — anyone running it today hits ImagePullBackOff unless they rebuild locally. The same coverage (inbound validation + outbound token exchange) is provided by the weather-agent advanced and github-issue demos, which use real workloads. Drop: - authbridge/demos/webhook/ (entire dir): README.md, k8s/, setup_keycloak.py 2. Cascade the auth-proxy + demo-app source With the webhook demo gone, nothing else references the auth-proxy or demo-app images, so the source can go too: - authbridge/authproxy/main.go + Dockerfile (auth-proxy app source) - authbridge/authproxy/k8s/auth-proxy-deployment.yaml (already broken standalone deployment) - authbridge/authproxy/quickstart/ (entire subtree — README.md, setup_keycloak.py, requirements.txt, k8s/demo-app-deployment.yaml, demo-app/main.go + Dockerfile) - authbridge/authproxy/go.mod + go.sum (no Go code remains) - authbridge/authproxy/Makefile build/deploy/test targets that reference any of the above 3. Rename authproxy/ → proxy-init/ What's left in authbridge/authproxy/ after the cascade is exactly the iptables init container and nothing else (init-iptables.sh + Dockerfile.init + a trimmed Makefile + a rewritten README focused on just the init container's role). The directory name authproxy no longer matches what's inside, and the pre-commit hooks go-fmt-authproxy / go-vet-authproxy were already orphaned with no .go files to scan. Rename to proxy-init/ — matches the image name and the container name the operator injects. Cross-reference sweep across 14 supporting files: * `local-build-and-test.sh` — path updated. * `Makefile` (root) — fmt now iterates over the live Go modules; build-images target replaced with build-proxy-init. * `.pre-commit-config.yaml` — drop the orphaned go-fmt-authproxy / go-vet-authproxy hooks. * `.github/workflows/ci.yaml` — drop the dedicated `go-ci` job (no Go module to test); update the pre-commit job's go-version-file to reference authlib/go.mod; rewrite the GOWORK="off" comment that named the deleted authproxy module. * `.github/workflows/build.yaml` — proxy-init context path bumped. * `.github/workflows/security-scans.yaml` — drop the authbridge/proxy-init/quickstart skip-dir entry (path is gone). * `.github/dependabot.yml` — rewrite. Drop entries for the deleted authproxy/quickstart/demo-app docker image, the now-Go-less authproxy go.mod, the never-existed authproxy/client-registration pip + docker entries. Add the four authlib + cmd/* go.mod entries that were missing entirely. * `authbridge/go.work` — drop ./authproxy from the workspace. * `authbridge/CLAUDE.md` — directory tree, demo descriptions, Keycloak setup-script table, build/deploy section, and the envoy-config + required-ConfigMaps sections all rewritten to reference the kagenti Helm chart's templates instead of the deleted demos/webhook/k8s/configmaps-webhook.yaml. Gotcha rossoctl#5 (virtualenv in deleted quickstart) removed; remaining gotchas renumbered. * `CLAUDE.md` (root) — directory tree updated; ci.yaml description no longer mentions authproxy as a separate Go target; manual-deployment learning-path bullet retargeted at the routes-config doc. * `authbridge/README.md` — the "AuthProxy" link bullets that described an Envoy + ext_proc binary (which doesn't exist anymore — that's authbridge-envoy now) replaced with bullets describing each cmd/* binary plus proxy-init. * `README.md` (root) — same overview rewrite; broken ./authbridge/client-registration/ link removed. * `LOCAL_TESTING_GUIDE.md` — Webhook Demo bullet retargeted at the token-exchange-routes guide; deprecation banner alternatives list updated to point at github-issue instead of the deleted webhook demo. * `authbridge/demos/README.md` — Webhook row + description block removed from the demos table. * `authbridge/demos/token-exchange-routes/README.md` — two broken `../webhook/` links retargeted at github-issue. * `authbridge/demos/weather-agent/k8s/weather-tool-advanced.yaml` — the comment line that pointed at the deleted webhook README for the type-label rule retargeted at the operator's webhook source. Net diff: 23 files modified, 14 deleted, 1 dir renamed (1 file moved via git mv). About -1,800 LOC of unmaintained, broken-image-dependent content; +120 LOC of corrected prose and the trimmed proxy-init Makefile/README. End-state directory layout: each subdirectory under authbridge/ has a name that matches what's inside, no orphaned hooks, no broken cross-references, no dead-image references. Verified: `bash -n local-build-and-test.sh`; `kubectl apply --dry-run=client` on the surviving demo YAMLs; `helm template` on the kagenti chart still renders (confirms our path changes don't break anyone consuming the chart); repo-wide grep for `authbridge/authproxy` returns zero hits in tracked content; broken-link grep on demos/webhook/ matches only inside the LOCAL_TESTING_GUIDE.md deprecation banner that was already flagged as stale earlier in this PR. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
…DME sweep Four small followups missed in the earlier sweep. All in scope of the post-rossoctl#411 cleanup; they survived because previous edits to the same files only touched the deployment-modes table + demos list, not the prose / diagrams / component-doc list. * `authbridge/README.md` line 3 — opening paragraph linked to two deleted/renamed paths: `[client registration](./client-registration/)` (no such directory in the repo) and `[token exchange](./authproxy/)` (renamed to `proxy-init/` in commit 0416172, and `proxy-init/` is just iptables — not a "token exchange" component anyway). Rewrite the paragraph to point at `authlib/` + `cmd/` for the actual code, with an explicit note that registration is now operator-managed. * `authbridge/README.md` ASCII architecture diagram — the box labeled `client-registration (registers Workload with Keycloak)` is gone (operator-managed), so drop that box. The "AuthProxy Sidecar" header was rewritten to "AuthBridge Sidecar (combined image)" with the per-mode container-name disambiguation (`authbridge-proxy` / `envoy-proxy`) we already established elsewhere. Spiffe-helper is also no longer a separate box — bundled inside the combined image, gated by `SPIRE_ENABLED`, noted inline. Add an out-of-band footer naming the operator's ClientRegistrationReconciler + the `kagenti-keycloak-client-credentials-<hash>` Secret it produces. * `authbridge/README.md` Mermaid architecture diagram — same treatment: collapse SpiffeHelper + ClientReg + Sidecar (which was three sub-nodes — auth-proxy + envoy-proxy + ext-proc) into one Sidecar node with the per-mode name. Move ClientRegistration into a new `Operator (kagenti-system)` subgraph so the diagram shows it living outside the workload pod. Renumber the request-flow arrows from 1-11 to 1-9 reflecting the simplified shape. * `authbridge/README.md` Workload Pod table — drop the `client-registration` row, and split the single `AuthProxy Sidecar` row into two per-mode rows (`authbridge-proxy` and `envoy-proxy`) with a `Mode` column. Add a brief lead-in paragraph explaining the post-rossoctl#411 shape. * `authbridge/README.md` Component Documentation links — both `[AuthProxy](authproxy/README.md)` and `[Client Registration](client-registration/README.md)` 404 now. Replace with one bullet per mode-specific cmd/* binary plus proxy-init plus authlib plus a pointer at the `docs/` directory that holds the framework / plugin author references. Add a trailing note that registration is operator-managed (the `Client Registration` link's purpose). * `CLAUDE.md` lines 265-266 — the "Routes config reference" line appeared twice (once bare, once with the parenthetical). Drop the bare duplicate; keep the more informative one. Verified: every link in authbridge/README.md resolves; repo-wide grep confirms the only remaining `client-registration` mentions in this file are descriptive prose about the post-rossoctl#411 migration ("standalone client-registration / spiffe-helper sidecars are gone"), not paths or component references. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
The advanced weather demo's two pod templates carried `kagenti.io/client-registration-inject: "true"`, which after PR #411 silently disables registration: * The operator's ClientRegistrationReconciler treats this label as a signal to skip — `SkipReason` in kagenti-operator/internal/clientreg/names.go:58 returns "label is true (legacy webhook client-registration sidecar; operator-managed registration disabled for this workload)". * The legacy in-pod kagenti-client-registration sidecar that the label was supposed to defer to was removed in #411. Net effect: setting this label today produces a workload with NO Keycloak client registered at all, and `setup_keycloak_weather_advanced.py --wait-tool-client` correctly times out waiting for a SPIFFE-shaped client (`spiffe://localtest.me/ns/<ns>/sa/<sa>`) that nobody will ever create. This was hiding behind the kagenti repo's MLflow e2e failures upstream — once those were fixed, the AuthBridge weather e2e exposed the latent bug. Drop the label from both pod templates: * k8s/weather-tool-advanced.yaml * k8s/weather-service-advanced.yaml Plus refresh the two doc references that were directing readers to set the label: * demos/weather-agent/demo-ui-advanced.md — replace the bullet that recommended the label with one explaining operator-managed registration is now the only path. * demos/webhook/README.md — rewrite the "client registration" bullet to call out the label as removed and explain why setting it today silently breaks registration. Verified: `kubectl apply --dry-run=client -f` on both YAMLs renders clean. Repo grep for the label only matches the two doc references above (both now phrased as "don't set it"). Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
…gistration-inject fix: sweep post-#411 stale references (dead labels, dead images, dead docs)
…er name The `pick_log_container` helper in deploy_and_verify_advanced.sh only knew two AuthBridge sidecar container names: `envoy-proxy` (envoy-sidecar mode) and `authbridge` (the pre-split combined-mode name from before rossoctl#411). After rossoctl#411 + kagenti-operator#361 the cluster default became proxy-sidecar, whose container is named `authbridge-proxy` — the script `die()`s on every CI run because neither of its two known names matches. Reproduced on kagenti#1592 just now. The pod actually had two containers — `mcp` and `authbridge-proxy` — i.e. the webhook had injected fine and the demo flow was healthy. The script just couldn't tell which container to read logs from: ERROR: pod weather-tool-advanced-... has neither envoy-proxy nor authbridge container (mcp authbridge-proxy) (The error message itself was misleading — the pod's container list `mcp\nauthbridge-proxy` got split across two log lines, so casual readers saw "(mcp" and assumed no sidecar was injected.) Fix: * Replace the two-branch if-elif with a small fallthrough loop over `authbridge-proxy / envoy-proxy / authbridge` so the cluster default's container name is recognized first, the envoy-sidecar mode's name still works, and the legacy combined name is kept for older clusters / replays. * Wrap `$names` in `$(echo $names)` inside the die message so the pod's container list renders on a single line, making the diagnostic accurate ("expected one of …; got: mcp authbridge-proxy") rather than visually truncated. Verified: bash -n on the script; repo grep finds no other places with the same restricted-name pick. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
Hai is right — on kagenti main, AuthBridge ships as a single combined sidecar image (kagenti-extensions#411). The weather-service pod is 2/2 regardless of SPIRE: spiffe-helper is bundled inside the combined image and activated per workload via SPIRE_ENABLED, not as a separate container. The deployment guide explicitly lists "1 combined sidecar" for both proxy-sidecar and envoy-sidecar modes (docs/authbridge/deployment-guide.md and charts/kagenti/values.yaml). The 3/3 separate-spiffe-helper layout I introduced in 8dacc17 described the pre-rossoctl#411 / v0.6 model — wrong for main. Revert the container-count claim to 2/2 in both "Check pod status" and "Verify injected containers" sections, and update the explanatory note to match the combined-sidecar architecture. Container names returned by kubectl ... containers[*].name are 'agent authbridge-proxy' (proxy mode) or 'agent envoy-proxy' (envoy mode) regardless of SPIRE. Addresses huang195's review on PR rossoctl#439. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Mariusz Sabath <mrsabath@gmail.com>
Summary
Splits the unified
cmd/authbridge/binary into three mode-specific binaries with build-time mode selection. Fixes the bug whereDockerfile.proxywas silently building the lite binary (no parsers), which broke abctl session-event observability for proxy-sidecar deployments after PR #409 merged.cmd/authbridge-proxy/(default)cmd/authbridge-envoy/cmd/authbridge-lite/Each binary has its own
main.go+go.mod+Dockerfile+entrypoint.sh. The unifiedcmd/authbridge/directory is removed; its listeners move intoauthlib/listener/{extauthz,extproc}alongside the existingforwardproxyandreverseproxylisteners so binaries no longer own listener code.CI publishes three images now (plus the unchanged
proxy-init):ghcr.io/kagenti/kagenti-extensions/authbridge— proxy-sidecar combined, what the operator points at by defaultghcr.io/kagenti/kagenti-extensions/authbridge-envoy— envoy-sidecar combinedghcr.io/kagenti/kagenti-extensions/authbridge-lite— proxy-sidecar lite combined (new)Why this PR
Two motivations stacked:
Naming was misleading. Pre-PR the layout was
cmd/authbridge(full, all modes) +cmd/authbridge-envoy(lite envoy-only) +cmd/authbridge-proxy(lite proxy-only). The mode-suffixed names looked like they should be the mode-specific full binaries; instead they were size-optimized lite variants.Dockerfile.proxywas silently using the lite proxy as the proxy-sidecar combined image — which had no parsers, so abctl couldn't render protocol context for proxy-sidecar deployments.Mode is a build-time decision, not a runtime decision. Operators set the mode via the per-pod ConfigMap the operator generates; nobody actually flips
--modeat runtime. Splitting by binary makes eachmain.goa flat 270-line file with no per-mode branching, and makes the Dockerfile contracts unambiguous.Operator (kagenti-operator) impact
None. The operator references
authbridgeandauthbridge-envoyimages by name. Image names, container ports, and the--config /etc/authbridge/config.yamlentrypoint contract are all stable. The image contents change (now built from the new mode-specific dirs, with parsers in the proxy combined), but no operator-side change is needed.Waypoint mode
Preserved but not currently shipped as a binary. The
ModeWaypointconstant inauthlib/configand theextauthzlistener inauthlib/listener/extauthz/stay so the code path is intact. If waypoint comes back as a deployed mode, a separatecmd/authbridge-waypoint/binary can be added without touching the rest.Dependency / Go version bump
authlibabsorbed the listener code that pulls inenvoyproxy/go-control-planeand gRPC, which require Go 1.25.go.workand the Dockerfile golang base images bump from 1.24 → 1.25 accordingly.Test plan
go build ./...clean for authlib + all 3 cmd/ binariesgo test ./...clean across authlib (44 packages, all pass)podman buildfrom the new Dockerfile pathsteam1namespace boots in proxy-sidecar mode against the newauthbridge:latestimageunknown pluginerrors)proxy-sidecar source=cluster-defaultfrom operator logauthbridge-liteimage and verify it can run in place ofauthbridgefor a workload that doesn't need parsers (separate test, not blocking)Follow-ups
kagenti/kagenti) image pins reference the oldauthbridge-lightname. The PR-C work for the operator's mode-resolution change will also need to update those.ghcr.io/kagenti/kagenti-extensions/authbridge-lite:<tag>.Assisted-By: Claude (Anthropic AI) noreply@anthropic.com