docs: Plugin architecture proposal#342
Conversation
Proposes an extensible filter pipeline for AuthBridge with: - Single Filter interface (OnRequest/OnResponse on shared Context) - Mutations directly on context (headers, body, values) - Mode-agnostic pipeline with thin adapters per deployment mode - Registry-based compiled-in plugin loading (v1) - Protocol parsing as a composable filter (not a special layer) - Tighten-only policy (plugins cannot weaken built-in security) - Praxis alignment for potential collaboration Signed-off-by: Hai Huang <hai@us.ibm.com> Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
- Rename "filter" to "plugin" throughout — AuthBridge extensions are security-aware plugins, not generic stream filters - Add "Current Architecture" section grounding the proposal in actual codebase (Auth struct, existing adapter pattern, func type precedent) - Add AgentIdentity to Context — dual SPIFFE/OAuth identity gives plugins security context no external proxy can provide - Add ResolvedRoute to Context for destination-aware policy decisions - Add "Tighten-Only Enforcement" section with concrete mechanisms (required plugins, protected registry, read-only claims) - Add "Observability by Default" section — auto-instrumented spans and metrics per plugin invocation - Add "Identity-Aware Protocol Policy" showing tool-level authorization via MCP parser + tool-policy plugin composition - Add concrete Praxis integration models (A/B/C) with recommendation - Sharpen migration path with real before/after code from ext_proc listener and mapping table from existing Auth fields to built-in plugins - Clarify body access as hard mode constraint (ext_authz: never, ext_proc: requires BUFFERED config, proxy: always) - Add WASM to future loading mechanisms, multi-turn sessions to open questions Signed-off-by: Hai Huang <huang195@gmail.com> Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
- Remove "Observability by Default" section — too prescriptive about implementation details for an architecture proposal - Make AgentIdentity generic: WorkloadID + TrustDomain instead of SPIFFEID. Works with SPIFFE, k8s SA, or any workload identity scheme. - Reframe Praxis section: position as Envoy replacement where AuthBridge benefits indirectly (universal body access, pre-parsed protocol metadata, simpler adapter layer) rather than peer integration models - Update tool-policy example to use trust_domain instead of SPIFFE pattern Signed-off-by: Hai Huang <huang195@gmail.com> Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Hai Huang <huang195@gmail.com>
|
This is a great start, and something that I think we can help build on a deliver. Many of the requirements listed here are things we've worked through with CPEX, and learned what works well and what doesn't work. Here is what I would suggest at a high level, and then I'll give a few more comments. Let us write up a proposal / spec for how to deliver CPEX to provide the plugin capabilities for AuthBridge and share it early next week. This will mirror what we already did for Praxis and Mellea and ContextForge. Given the rewrite in Rust, we can support AuthBridge / Go using Rust + C ABI + Go (cgo). Some things we can then work through are the placement of the hooks (ingress and egress, return response, etc.) and things like the payload and how to configure it. For things like the The other thing this will provide is robust prioritized, parallel, and sequential pipelines with varying semantics (fail on error, fire-and-forget, async versus blocking, etc.). This is all stuff you'll get for free. Let's see how we can provide these capabilities for automatically. Smaller, comments:
|
|
Thanks Ian — this is really helpful feedback, and the timing is great. A few responses:
Policy language — Great point about moving beyond custom YAML rules. Since we're already in the Kuadrant ecosystem (MCP Gateway uses Kuadrant), one option we're exploring is integrating with Authorino for policy evaluation. AuthBridge's role would be enriching the authorization context with protocol-level data (tool name, arguments, method) that Authorino can't extract on its own, then delegating the policy decision via ext_authz. This would give us OPA/Rego, pattern-matching, and SpiceDB support through existing infrastructure. Plugin interface and CPEX integration — Our current thinking is to keep the initial pipeline implementation in Go to match the rest of the AuthBridge codebase and keep the build simple. That said, we want to design the Plugin interface to be open: type Plugin interface {
Name() string
Capabilities() PluginCapabilities
OnRequest(ctx *Context) Action
OnResponse(ctx *Context) Action
}If CPEX provides a bridge implementation behind this interface — bringing the Rust runtime, scheduling, and CMF — that would work well. The interface is the contract, and CPEX would be a first-class way to implement it. This is similar to how CPEX adapts to Praxis and Mellea's extension models. We'd love to see how this could look concretely. Other points:
Would love to see the CPEX spec for AuthBridge when it's ready next week. Having a concrete proposal to compare against will help us find the right integration points. |
|
@huang195 Thanks for sharing the initial proposal! Building on your draft and @imolloy's feedback on CPEX integration, I put together a concrete spec that wires CPEX into AuthBridge as the hook system and plugin runtime: In short, the spec defines typed hooks across the AuthBridge lifecycle (startup, inbound JWT validation, outbound token exchange, and cross-cutting audit), with CPEX embedded in-process via Go bindings to the Rust core. Plugins declare capabilities that gate which Extensions they can access (Security, Http, Delegation, etc.), and all policy results compose through a tighten-only monoid; plugins can deny but never override a deny to allow. It also addresses several points from the discussion: typed extension slots instead of I'd be happy to team up and refine it to cover any missing requirements, adjust scope, and incorporate feedback from others. |
Summary
Adds
docs/plugin-architecture.md— a design proposal for an extensible plugin pipeline in AuthBridge.Key design decisions
PluginwithOnRequest(ctx)/OnResponse(ctx)— no layered abstractionsAgentIdentity(SPIFFE ID + client_id) alongside callerClaims— security decisions no external proxy can makectx.Headers/ctx.Bodydirectly, return Continue or Rejectctx.Values, enabling tool-level authorization via compositionWhat changed in v2
Authstruct, real listener code, real migration seamsDiscussion points
Assisted-By: Claude (Anthropic AI) noreply@anthropic.com