From f5b0c808563e74f43d2d0a3225082060847c8271 Mon Sep 17 00:00:00 2001 From: Hai Huang Date: Tue, 14 Apr 2026 21:36:21 -0400 Subject: [PATCH] ci: Add CI/build for unified authbridge, deprecate old components (Phase 4) CI changes: - Add Go CI jobs for authlib and cmd/authbridge modules - Add authbridge-unified image to build.yaml matrix Documentation: - Update CLAUDE.md with unified binary architecture, Go modules, and modes - Mark authbridge-unified as recommended image - Mark envoy-with-processor and old authbridge as deprecated Deprecation markers: - go-processor/main.go: deprecated in favor of cmd/authbridge - Dockerfile.envoy: deprecated in favor of cmd/authbridge/Dockerfile - entrypoint-envoy.sh: deprecated in favor of cmd/authbridge/entrypoint.sh Follow-up (separate repos): - kagenti-operator: add authbridge-unified to image config - kagenti: add authbridge-unified-config ConfigMap to Helm chart Ref: kagenti/kagenti-extensions#279 Assisted-By: Claude (Anthropic AI) Signed-off-by: Hai Huang --- .github/workflows/build.yaml | 6 +++ .github/workflows/ci.yaml | 57 +++++++++++++++++++++++ CLAUDE.md | 48 ++++++++++++++++--- authbridge/authproxy/Dockerfile.envoy | 2 + authbridge/authproxy/entrypoint-envoy.sh | 1 + authbridge/authproxy/go-processor/main.go | 4 ++ 6 files changed, 112 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 68e982200..6c99f2b61 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -50,6 +50,12 @@ jobs: context: ./authbridge dockerfile: authproxy/Dockerfile.authbridge + # Unified AuthBridge binary (Envoy + authbridge in one container) + # Drop-in replacement for envoy-with-processor + - name: authbridge-unified + context: ./authbridge + dockerfile: cmd/authbridge/Dockerfile + # Demo application for testing - name: demo-app context: ./authbridge/authproxy/quickstart/demo-app diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e40eca35a..cd20d17e6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -66,6 +66,63 @@ jobs: - name: Test run: go test -v -race -cover ./... + go-ci-authlib: + name: Go CI (authlib) + runs-on: ubuntu-latest + timeout-minutes: 15 + defaults: + run: + working-directory: authbridge/authlib + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + with: + go-version-file: authbridge/authlib/go.mod + cache-dependency-path: authbridge/authlib/go.sum + + - name: Lint + run: | + go fmt ./... + go vet ./... + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v -race -cover ./... + + go-ci-authbridge-cmd: + name: Go CI (authbridge cmd) + runs-on: ubuntu-latest + timeout-minutes: 15 + defaults: + run: + working-directory: authbridge/cmd/authbridge + env: + # Disable go.work — the workspace at authbridge/ includes ./authproxy + # which would pull in the old go-processor module. The replace directive + # in go.mod handles the authlib dependency for CI builds. + GOWORK: "off" + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 + with: + go-version-file: authbridge/cmd/authbridge/go.mod + cache-dependency-path: authbridge/cmd/authbridge/go.sum + + - name: Lint + run: | + go fmt ./... + go vet ./... + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v -race -cover ./... + python-test: name: Python Tests runs-on: ubuntu-latest diff --git a/CLAUDE.md b/CLAUDE.md index 659c519b2..472e52fcd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,8 +21,21 @@ The sidecar injection webhook lives in a separate repo: [kagenti/kagenti-operato ``` kagenti-extensions/ ├── authbridge/ # Authentication bridge components -│ ├── authproxy/ # Envoy + ext-proc sidecar (Go) — token validation & exchange -│ │ ├── go-processor/ # gRPC ext-proc server (inbound JWT validation, outbound token exchange) +│ ├── authlib/ # Shared auth building blocks (Go module) +│ │ ├── validation/ # JWKS-backed JWT verifier +│ │ ├── exchange/ # RFC 8693 token exchange client +│ │ ├── cache/ # SHA-256 keyed token cache +│ │ ├── bypass/ # Path pattern matcher +│ │ ├── spiffe/ # SPIFFE credential sources +│ │ ├── routing/ # Host-to-audience router +│ │ ├── auth/ # HandleInbound + HandleOutbound composition +│ │ └── config/ # Mode presets, YAML config, validation +│ ├── cmd/authbridge/ # Unified binary — 3 modes, 1 codebase +│ │ ├── listener/ # Protocol adapters (ext_proc, ext_authz, forward/reverse proxy) +│ │ ├── entrypoint.sh # Envoy + authbridge process supervision +│ │ └── Dockerfile # Combined Envoy + authbridge image +│ ├── authproxy/ # [DEPRECATED] Old Envoy + ext-proc sidecar +│ │ ├── go-processor/ # [DEPRECATED] Use cmd/authbridge instead │ │ ├── quickstart/ # Standalone demo (no SPIFFE) │ │ └── k8s/ # Standalone K8s manifests │ ├── client-registration/ # Keycloak auto-registration (Python) @@ -88,12 +101,34 @@ The kagenti-operator (in a separate repo) injects AuthBridge sidecars into workl └────────────────────────────────────┘ ``` +## Unified AuthBridge Binary + +The `cmd/authbridge/` directory contains a unified binary that replaces three separate +codebases (go-processor, waypoint, klaviger) with a single binary supporting three modes: + +| Mode | Interception | Listeners | Use Case | +|------|-------------|-----------|----------| +| `envoy-sidecar` | Envoy iptables + ext_proc | gRPC ext_proc on :9090 | Sidecar per agent pod | +| `waypoint` | Istio ambient + ext_authz | gRPC ext_authz + HTTP forward proxy | Shared service | +| `proxy-sidecar` | Reverse proxy + forward proxy | HTTP reverse proxy + forward proxy | Sidecar without Envoy | + +**Go modules:** +- `authbridge/authlib/` — pure library, no protocol deps (validation, exchange, cache, bypass, spiffe, routing, auth, config) +- `authbridge/cmd/authbridge/` — binary + listeners, imports authlib + gRPC/Envoy deps +- `authbridge/go.work` — workspace linking both modules for local development + +**Config format:** YAML with `${ENV_VAR}` expansion, mode presets, and startup validation. +Supports `keycloak_url` + `keycloak_realm` derivation for operator compatibility. + +**Image:** `ghcr.io/kagenti/kagenti-extensions/authbridge-unified` — Envoy + authbridge +in one container (drop-in replacement for `envoy-with-processor`). + ## CI/CD Workflows | Workflow | Trigger | Purpose | |----------|---------|---------| -| `ci.yaml` | PR to main/release-* | Go fmt, vet, build for AuthProxy; Python tests | -| `build.yaml` | Tag push (`v*`) or manual | Multi-arch Docker builds for: client-registration, auth-proxy, proxy-init, envoy-with-processor, authbridge, demo-app | +| `ci.yaml` | PR to main/release-* | Go fmt, vet, build, test for authproxy, authlib, and cmd/authbridge; Python tests | +| `build.yaml` | Tag push (`v*`) or manual | Multi-arch Docker builds for: client-registration, auth-proxy, proxy-init, envoy-with-processor, authbridge, authbridge-unified, demo-app | | `security-scans.yaml` | PR to main | Dependency review, shellcheck, YAML lint, Hadolint, Bandit, Trivy, CodeQL | | `scorecard.yaml` | Weekly / push to main | OpenSSF Scorecard security health metrics | | `spellcheck_action.yml` | PR | Spellcheck on markdown files | @@ -114,11 +149,12 @@ All images are pushed to `ghcr.io/kagenti/kagenti-extensions/`: | Image | Source | Description | |-------|--------|-------------| -| `envoy-with-processor` | `authbridge/authproxy/Dockerfile.envoy` | Envoy 1.28 + go-processor ext-proc | +| **`authbridge-unified`** | **`authbridge/cmd/authbridge/Dockerfile`** | **Unified Envoy + authbridge binary (recommended)** | +| `envoy-with-processor` | `authbridge/authproxy/Dockerfile.envoy` | [DEPRECATED] Envoy + go-processor ext-proc | | `proxy-init` | `authbridge/authproxy/Dockerfile.init` | Alpine + iptables init container | | `client-registration` | `authbridge/client-registration/Dockerfile` | Python Keycloak client registrar | | `spiffe-helper` | `authbridge/spiffe-helper/Dockerfile` | Fetches SPIFFE credentials from SPIRE | -| `authbridge` | `authbridge/authproxy/Dockerfile.authbridge` | Combined sidecar (Envoy + go-processor + spiffe-helper + client-registration) | +| `authbridge` | `authbridge/authproxy/Dockerfile.authbridge` | [DEPRECATED] Combined sidecar (old architecture) | | `auth-proxy` | `authbridge/authproxy/Dockerfile` | Example pass-through proxy (for demos) | | `demo-app` | `authbridge/authproxy/quickstart/demo-app/Dockerfile` | Demo target service | diff --git a/authbridge/authproxy/Dockerfile.envoy b/authbridge/authproxy/Dockerfile.envoy index 032136edd..ebed36202 100644 --- a/authbridge/authproxy/Dockerfile.envoy +++ b/authbridge/authproxy/Dockerfile.envoy @@ -1,3 +1,5 @@ +# Deprecated: This Dockerfile builds the old envoy-with-processor image. +# Use authbridge/cmd/authbridge/Dockerfile instead (unified binary). FROM golang:1.26-alpine AS go-builder WORKDIR /app COPY go.mod go.sum ./ diff --git a/authbridge/authproxy/entrypoint-envoy.sh b/authbridge/authproxy/entrypoint-envoy.sh index b4fe6295b..ffdc1d382 100644 --- a/authbridge/authproxy/entrypoint-envoy.sh +++ b/authbridge/authproxy/entrypoint-envoy.sh @@ -1,4 +1,5 @@ #!/bin/bash +# Deprecated: Use authbridge/cmd/authbridge/entrypoint.sh instead (unified binary). set -eu # Envoy + go-processor entrypoint with process supervision. diff --git a/authbridge/authproxy/go-processor/main.go b/authbridge/authproxy/go-processor/main.go index bd4772672..57a84c891 100644 --- a/authbridge/authproxy/go-processor/main.go +++ b/authbridge/authproxy/go-processor/main.go @@ -1,3 +1,7 @@ +// Deprecated: This go-processor ext_proc server is replaced by the unified +// authbridge binary at cmd/authbridge/. The unified binary supports envoy-sidecar, +// waypoint, and proxy-sidecar modes with a shared auth library (authlib/). +// This file is kept for backwards compatibility during migration. package main import (