Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
79 changes: 49 additions & 30 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,14 @@
dockerfile: cmd/authbridge-proxy/Dockerfile

# AuthBridge proxy-sidecar LITE image — the SAME authbridge-proxy
# binary + Dockerfile, built with exclude_plugin_* tags so only
# jwt-validation + token-exchange compile in (drops the OPA SDK
# and the parsers, roughly halving the binary). A build variant,
# not a separate binary. Same listener layout as the full proxy
# image; not yet referenced by the operator's default config.
# binary + Dockerfile, built with a trimmed plugin set (roughly
# halving the binary). A build variant, not a separate binary.
# GO_BUILD_TAGS is derived at step time from
# authbridge/scripts/lite-tags rather than declared here, so
# adding a plugin doesn't require editing this file.
- name: authbridge-lite
context: ./authbridge
dockerfile: cmd/authbridge-proxy/Dockerfile
build_args: |
GO_BUILD_TAGS=exclude_plugin_a2aparser,exclude_plugin_ibac,exclude_plugin_inferenceparser,exclude_plugin_mcpparser,exclude_plugin_opa,exclude_plugin_sparc,exclude_plugin_tokenbroker,exclude_plugin_toolprune

# AuthBridge proxy-sidecar CPEX image — authbridge-proxy built
# with -tags cpex (links libcpex_ffi.a from a pinned CPEX
Expand All @@ -79,6 +77,15 @@
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# 1b. Set up Go — needed by the buildargs step for authbridge-lite,
# which derives GO_BUILD_TAGS from plugin source at build time.
# Cheap to install for every matrix row (~1s of cache pull); no-op
# for rows that don't need it.
- name: Set up Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: authbridge/scripts/lite-tags/go.mod

# 2. Set up QEMU for multi-arch builds
- name: Set up QEMU
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
Expand Down Expand Up @@ -119,42 +126,54 @@
# Always use the computed tag
type=raw,value=${{ steps.tag.outputs.tag }}
# Add 'latest' tag for version tags, workflow_dispatch, and pushes to main
type=raw,value=latest,enable=${{ (github.ref_type == 'tag' && startsWith(github.ref_name, 'v')) || github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main' }}

Check warning on line 129 in .github/workflows/build.yaml

View workflow job for this annotation

GitHub Actions / YAML Lint

129:151 [line-length] line too long (189 > 150 characters)

# 6b. Resolve build-args. authbridge-cpex needs CPEX_FFI_VERSION
# (the release tag) and CPEX_FFI_ABI (the FFI ABI integer the
# linked lib must report) — both read from the files next to its
# Dockerfile and asserted against the tarball at build time. Other
# images leave this empty (an undeclared build-arg is ignored).
# 6b. Resolve per-image build-args.
# authbridge-cpex: CPEX_FFI_VERSION (release tag) and CPEX_FFI_ABI
# (integer the linked lib must report), read from the files
# next to its Dockerfile and asserted at build time.
# authbridge-lite: GO_BUILD_TAGS, derived from plugin source
# (authbridge/scripts/lite-tags) so the list stays in sync
# without hand-maintenance.
# Other images leave args empty (an undeclared build-arg is
# ignored).
- name: Resolve build args
id: buildargs
run: |
if [[ "${{ matrix.image_config.name }}" == "authbridge-cpex" ]]; then
VERSION="$(tr -d '[:space:]' < authbridge/cmd/authbridge-cpex/CPEX_FFI_VERSION)"
ABI="$(tr -d '[:space:]' < authbridge/cmd/authbridge-cpex/CPEX_FFI_ABI)"
{
echo "args<<EOF"
echo "CPEX_FFI_VERSION=${VERSION}"
echo "CPEX_FFI_ABI=${ABI}"
echo "EOF"
} >> "$GITHUB_OUTPUT"
else
echo "args=" >> "$GITHUB_OUTPUT"
fi
case "${{ matrix.image_config.name }}" in
authbridge-cpex)
VERSION="$(tr -d '[:space:]' < authbridge/cmd/authbridge-cpex/CPEX_FFI_VERSION)"
ABI="$(tr -d '[:space:]' < authbridge/cmd/authbridge-cpex/CPEX_FFI_ABI)"
{
echo "args<<EOF"
echo "CPEX_FFI_VERSION=${VERSION}"
echo "CPEX_FFI_ABI=${ABI}"
echo "EOF"
} >> "$GITHUB_OUTPUT"
;;
authbridge-lite)
TAGS=$(go -C authbridge/scripts/lite-tags run .)
{
echo "args<<EOF"
echo "GO_BUILD_TAGS=${TAGS}"
echo "EOF"
} >> "$GITHUB_OUTPUT"
;;
*)
echo "args=" >> "$GITHUB_OUTPUT"
;;
esac

# 7. Build and push image
- name: Build and push ${{ matrix.image_config.name }}
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
with:
context: ${{ matrix.image_config.context }}
file: ${{ matrix.image_config.context }}/${{ matrix.image_config.dockerfile }}
# Merge both build-arg sources into a single key: static per-image
# args from the matrix (e.g. authbridge-lite GO_BUILD_TAGS) plus the
# dynamically resolved args (authbridge-cpex CPEX_FFI_*). A duplicate
# `build-args:` key is invalid YAML and fails the whole workflow; only
# one image sets each source, so concatenating them is safe.
# Dynamically-resolved args from step 6b: authbridge-cpex
# (CPEX_FFI_*) and authbridge-lite (GO_BUILD_TAGS from
# scripts/lite-tags). Other images resolve to empty.
build-args: |
${{ matrix.image_config.build_args }}
${{ steps.buildargs.outputs.args }}
push: true
platforms: linux/amd64,linux/arm64
Expand Down
8 changes: 3 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,13 @@ jobs:
run: go build -v ./...

# The authbridge-lite image is this same authbridge-proxy binary built
# with exclude_plugin_* tags (only jwt-validation + token-exchange).
# with the trimmed plugin set derived by authbridge/scripts/lite-tags.
# Build AND test that tag set on every PR — build.yaml only exercises
# it on tag/main pushes, and this guards against lite-only regressions.
- name: Build + test lite variant (exclude_plugin_* tags)
- name: Build + test lite variant
if: matrix.binary == 'authbridge-proxy'
run: |
TAGS="exclude_plugin_a2aparser,exclude_plugin_ibac,exclude_plugin_inferenceparser"
TAGS="$TAGS,exclude_plugin_mcpparser,exclude_plugin_opa,exclude_plugin_sparc,exclude_plugin_tokenbroker"
TAGS="$TAGS,exclude_plugin_toolprune"
TAGS=$(go -C ../../scripts/lite-tags run .)

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.

suggestion: the comment four lines above this (line 104) still reads # with exclude_plugin_* tags (only jwt-validation + token-exchange). That is the exact duplicated claim this PR exists to eliminate, and it is now wrong twice over — liteKeep has four entries, so lite also retains litellm_budgettrack and staticinject.

Suggest replacing it with a pointer to the generator, matching what you did in the other five docs:

      # The authbridge-lite image is this same authbridge-proxy binary built
      # with the trimmed plugin set derived by authbridge/scripts/lite-tags.

go build -v -tags "$TAGS" ./...
go test -v -race -cover -tags "$TAGS" ./...

Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/release-binaries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ jobs:
# authbridge-proxy variants: "<suffix>:<build-tags>". Empty
# suffix is the default plugin set. One variant per opt-in
# plugin (or one combined "full") — never enumerate combos.
lite_tags="exclude_plugin_a2aparser,exclude_plugin_ibac"
lite_tags="${lite_tags},exclude_plugin_inferenceparser"
lite_tags="${lite_tags},exclude_plugin_mcpparser,exclude_plugin_opa"
lite_tags="${lite_tags},exclude_plugin_sparc,exclude_plugin_tokenbroker"
# Lite tags are derived from plugin source; see
# authbridge/scripts/lite-tags.
lite_tags=$(go -C authbridge/scripts/lite-tags run .)

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.

nit: worth a line in the release notes. The list this replaces omitted exclude_plugin_toolprune (as did local-build-and-test.sh), while build.yaml and ci.yaml included it. Deriving from source resolves that drift in favour of excluding it — so the published authbridge-proxy-lite tarball loses toolprune relative to the last release. Correct outcome and precisely the bug #854 describes, just not obvious to anyone diffing tarball contents across releases.

declare -a proxy_variants=(
":"
"lite:${lite_tags}"
Expand Down Expand Up @@ -112,7 +111,7 @@ jobs:
add ''
add '`authbridge-proxy` ships in variants matching the container images:'
add 'unqualified (default plugin set, matches the `authbridge` image),'
add '`-lite` (auth-only, matches `authbridge-lite`), plus one variant per'
add '`-lite` (trimmed plugin set, matches `authbridge-lite`), plus one variant per'
add 'opt-in plugin currently offered for try-out (today: `-sessionbudget`).'
add 'Variants track opt-in plugins one-for-one; arbitrary combinations are not published.'
add ''
Expand Down
16 changes: 9 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Two mode-specific binaries (proxy, envoy), one Dockerfile each; the `authbridge-
|--------|------|-----------|---------|
| `cmd/authbridge-proxy/` | proxy-sidecar (default) | HTTP forward + reverse proxies | full (incl. parsers) |
| `cmd/authbridge-envoy/` | envoy-sidecar | gRPC ext_proc on :9090 | full (incl. parsers) |
| `authbridge-lite` _(image: proxy + `exclude_plugin_*`)_ | proxy-sidecar | HTTP forward + reverse proxies | auth-only (jwt-validation + token-exchange; OPA + parsers dropped) |
| `authbridge-lite` _(image: proxy + `exclude_plugin_*`)_ | proxy-sidecar | HTTP forward + reverse proxies | trimmed plugin set (see `authbridge/scripts/lite-tags`) |

**Go modules:**
- `authbridge/authlib/` — pure library: validation, exchange, cache, bypass, spiffe, routing, auth, config, all listener implementations, all plugins.
Expand All @@ -139,7 +139,7 @@ Two mode-specific binaries (proxy, envoy), one Dockerfile each; the `authbridge-
| Workflow | Trigger | Purpose |
|----------|---------|---------|
| `ci.yaml` | PR to main/release-* | Pre-commit, Go fmt/vet/build/test for authlib and the cmd/authbridge-* binaries; Python tests |
| `build.yaml` | Tag push (`v*`) or manual | Multi-arch Docker builds for: proxy-init, authbridge (proxy-sidecar combined), authbridge-envoy (envoy-sidecar combined), authbridge-lite (proxy Dockerfile built with `exclude_plugin_*` tags — auth-only) |
| `build.yaml` | Tag push (`v*`) or manual | Multi-arch Docker builds for: proxy-init, authbridge (proxy-sidecar combined), authbridge-envoy (envoy-sidecar combined), authbridge-lite (proxy Dockerfile built with `exclude_plugin_*` tags from `authbridge/scripts/lite-tags`) |
| `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 |
Expand Down Expand Up @@ -170,7 +170,7 @@ All images are pushed to `ghcr.io/rossoctl/cortex/` from
|-------|--------|-------------|
| **`authbridge`** | **`authbridge/cmd/authbridge-proxy/Dockerfile`** | **proxy-sidecar combined image (default mode): authbridge-proxy (full plugin set incl. parsers) + spiffe-helper. No Envoy.** |
| `authbridge-envoy` | `authbridge/cmd/authbridge-envoy/Dockerfile` | envoy-sidecar combined image: Envoy + authbridge-envoy (ext_proc, full plugin set) + spiffe-helper |
| `authbridge-lite` | `authbridge/cmd/authbridge-proxy/Dockerfile` (+ `GO_BUILD_TAGS=exclude_plugin_*`) | proxy-sidecar combined image built auth-only (jwt-validation + token-exchange; OPA + parsers dropped) + spiffe-helper. A build variant of `authbridge`, not a separate binary; not yet referenced by the operator's default config |
| `authbridge-lite` | `authbridge/cmd/authbridge-proxy/Dockerfile` (+ `GO_BUILD_TAGS=exclude_plugin_*`) | proxy-sidecar combined image with a trimmed plugin set (see `authbridge/scripts/lite-tags`), plus spiffe-helper. A build variant of `authbridge`, not a separate binary; not yet referenced by the operator's default config |
| `authbridge-cpex` | `authbridge/cmd/authbridge-cpex/Dockerfile` | proxy-sidecar build with the CPEX plugin: authbridge-proxy built with `-tags cpex`, links `libcpex_ffi.a` from a pinned CPEX release (CGO_ENABLED=1). Routes hooks through the CPEX framework (APL DSL + named CPEX policy plugins). FFI ABI version is read from `authbridge/cmd/authbridge-cpex/CPEX_FFI_VERSION` |
| `proxy-init` | `authbridge/proxy-init/Dockerfile.init` | Alpine + iptables init container (envoy-sidecar + proxy-sidecar enforce-redirect modes) |

Expand Down Expand Up @@ -252,9 +252,11 @@ cd authbridge/proxy-init && make docker-build-init
# Combined sidecars (proxy-sidecar default / envoy-sidecar)
cd authbridge && podman build -f cmd/authbridge-proxy/Dockerfile -t authbridge:latest .
cd authbridge && podman build -f cmd/authbridge-envoy/Dockerfile -t authbridge-envoy:latest .
# authbridge-lite: same proxy Dockerfile, built with exclude_plugin_* tags (auth-only)
cd authbridge && podman build -f cmd/authbridge-proxy/Dockerfile \
--build-arg GO_BUILD_TAGS="exclude_plugin_a2aparser,exclude_plugin_ibac,exclude_plugin_inferenceparser,exclude_plugin_mcpparser,exclude_plugin_opa,exclude_plugin_sparc,exclude_plugin_tokenbroker,exclude_plugin_toolprune" \
# authbridge-lite: same proxy Dockerfile, built with the trimmed
# plugin set derived from plugin source by
# authbridge/scripts/lite-tags.
cd authbridge && LITE_TAGS=$(go -C scripts/lite-tags run .) && podman build -f cmd/authbridge-proxy/Dockerfile \
--build-arg GO_BUILD_TAGS="${LITE_TAGS}" \
-t authbridge-lite:latest .
```

Expand Down Expand Up @@ -305,7 +307,7 @@ cd authbridge && podman build -f cmd/authbridge-proxy/Dockerfile \

## Gotchas and Known Issues

1. **One Go module:** The repo has a single Go module at `authbridge/proxy-init/go.mod` (Go 1.25).
1. **Multiple Go modules:** The repo has several Go modules under `authbridge/` — `authlib/`, each `cmd/*/`, `storage/redis/`, `scripts/lite-tags/`, and the `demos/*/` self-contained ones — linked by `authbridge/go.work`. Local commands from a specific module directory should typically set `GOWORK=off` (as CI does) so the module resolves its own `replace` directives instead of pulling in workspace siblings.

2. **Avoid committing venvs:** Virtual environment directories (e.g. `authbridge/proxy-init/quickstart/venv/`) should be gitignored (the repo's `.gitignore` has a `venv` pattern). Do not create and commit new virtual environments under version control.

Expand Down
14 changes: 8 additions & 6 deletions authbridge/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ binaries with shared auth logic in `authlib/`:
version lives in `cmd/authbridge-cpex/CPEX_FFI_VERSION`. The other
binaries are pure-Go (CGO_ENABLED=0) and do not import the cpex package.
- `authbridge-lite` (**image, not a separate binary**) — `cmd/authbridge-proxy`
built with `exclude_plugin_*` tags so only jwt-validation + token-exchange
compile in (OPA + parsers dropped). For size-optimized deployments that
don't need protocol-aware session events.
built with `exclude_plugin_*` tags for a trimmed plugin set (see
`authbridge/scripts/lite-tags` for the definition). For size-optimized
deployments that don't need protocol-aware session events.

Each binary is hardcoded to its deployment shape; mode is no longer selected
at runtime. The YAML `mode:` field must match the binary or boot fails.
Expand All @@ -45,7 +45,7 @@ ships in variants that mirror the container images:
| Variant | Tarball name shape | Matches |
|---|---|---|
| unqualified (default plugins) | `authbridge-proxy_<ver>_<os>_<arch>.tar.gz` | `authbridge` image |
| `-lite` (drops the OPA SDK and the protocol parsers) | `authbridge-proxy-lite_<ver>_<os>_<arch>.tar.gz` | `authbridge-lite` image |
| `-lite` (trimmed plugin set — see `authbridge/scripts/lite-tags`) | `authbridge-proxy-lite_<ver>_<os>_<arch>.tar.gz` | `authbridge-lite` image |
| `-sessionbudget` (default + opt-in session-budget) | `authbridge-proxy-sessionbudget_<ver>_<os>_<arch>.tar.gz` | no image today |

One variant per opt-in plugin currently offered for try-out (today:
Expand Down Expand Up @@ -411,9 +411,11 @@ make load-image # Uses KIND_CLUSTER_NAME env var (default: r
cd ..
podman build -f cmd/authbridge-proxy/Dockerfile -t authbridge:latest . # proxy-sidecar (default)
podman build -f cmd/authbridge-envoy/Dockerfile -t authbridge-envoy:latest . # envoy-sidecar
# authbridge-lite: the proxy Dockerfile built with exclude_plugin_* tags (auth-only)
# authbridge-lite: the proxy Dockerfile built with a trimmed plugin
# set derived from plugin source by scripts/lite-tags.
LITE_TAGS=$(go -C scripts/lite-tags run .)
podman build -f cmd/authbridge-proxy/Dockerfile \
--build-arg GO_BUILD_TAGS="exclude_plugin_a2aparser,exclude_plugin_ibac,exclude_plugin_inferenceparser,exclude_plugin_mcpparser,exclude_plugin_opa,exclude_plugin_sparc,exclude_plugin_tokenbroker,exclude_plugin_toolprune" \
--build-arg GO_BUILD_TAGS="${LITE_TAGS}" \
-t authbridge-lite:latest .
kind load docker-image authbridge:latest --name rossoctl
kind load docker-image authbridge-envoy:latest --name rossoctl
Expand Down
6 changes: 3 additions & 3 deletions authbridge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ Two container images are published:
|-------|----------|
| `authbridge` | proxy-sidecar combined: authbridge-proxy binary + bundled spiffe-helper |
| `authbridge-envoy` | envoy-sidecar combined: Envoy + ext_proc + bundled spiffe-helper |
| `authbridge-lite` | `authbridge-proxy` built with `exclude_plugin_*` tags — auth-only (jwt-validation + token-exchange; OPA + parsers dropped). A build variant, not a separate binary |
| `authbridge-lite` | `authbridge-proxy` built with `exclude_plugin_*` tags from `authbridge/scripts/lite-tags` (trimmed plugin set). A build variant, not a separate binary |

| Mode | Image | Use Case | How It Works |
|------|-------|----------|-------------|
| `proxy-sidecar` (default) | `authbridge` | HTTP_PROXY-based forward + reverse proxies | Agent routes outbound traffic through forward proxy; reverse proxy validates inbound JWTs |
| `envoy-sidecar` | `authbridge-envoy` | Transparent interception via iptables | Envoy intercepts all traffic, delegates auth to authbridge via ext_proc gRPC |
| `lite` | `authbridge-lite` | The `authbridge-proxy` binary built with `exclude_plugin_*` tags (auth-only: jwt-validation + token-exchange) | For size-constrained deployments that don't need protocol-aware session events |
| `lite` | `authbridge-lite` | The `authbridge-proxy` binary built with `exclude_plugin_*` tags from `authbridge/scripts/lite-tags` (trimmed plugin set) | For size-constrained deployments that don't need protocol-aware session events |

The operator resolves the mode per workload from `AgentRuntime.Spec.AuthBridgeMode` → namespace ConfigMap → deprecated `rossoctl.io/authbridge-mode` annotation → cluster default (`proxy-sidecar`). See operator#361.

Expand Down Expand Up @@ -480,7 +480,7 @@ plugin package from being imported and compiled into the binary.
- [authlib](authlib/README.md) — Shared auth building blocks (Go library)
- [cmd/authbridge-proxy](cmd/authbridge-proxy/) — proxy-sidecar binary (default mode, full plugin set)
- [cmd/authbridge-envoy](cmd/authbridge-envoy/) — envoy-sidecar binary (Envoy + ext_proc, full plugin set)
- `authbridge-lite` image — `cmd/authbridge-proxy` built with `exclude_plugin_*` tags (auth-only); a build variant, not a separate binary
- `authbridge-lite` image — `cmd/authbridge-proxy` built with `exclude_plugin_*` tags from `authbridge/scripts/lite-tags` (trimmed plugin set); a build variant, not a separate binary
- [proxy-init](proxy-init/README.md) — iptables init container (envoy-sidecar mode only)
- [docs/](docs/) — framework architecture and plugin author references

Expand Down
Loading
Loading