Skip to content

docs: Plugin architecture proposal#342

Closed
huang195 wants to merge 3 commits into
rossoctl:mainfrom
huang195:docs/plugin-architecture
Closed

docs: Plugin architecture proposal#342
huang195 wants to merge 3 commits into
rossoctl:mainfrom
huang195:docs/plugin-architecture

Conversation

@huang195

@huang195 huang195 commented Apr 22, 2026

Copy link
Copy Markdown
Member

Summary

Adds docs/plugin-architecture.md — a design proposal for an extensible plugin pipeline in AuthBridge.

Key design decisions

  • One interface: Plugin with OnRequest(ctx) / OnResponse(ctx) — no layered abstractions
  • Identity-first context: every plugin receives AgentIdentity (SPIFFE ID + client_id) alongside caller Claims — security decisions no external proxy can make
  • Mutations on context: plugins modify ctx.Headers / ctx.Body directly, return Continue or Reject
  • Mode-agnostic: thin adapter per deployment mode converts to/from shared Context (formalizes existing adapter pattern)
  • Tighten-only enforcement: built-in plugins cannot be removed; claims are read-only to custom plugins; protected registry prevents name collisions
  • Body access as hard constraint: ext_authz (waypoint) can never provide body; ext_proc requires explicit Envoy config; proxy has full access. Validated at startup.
  • Protocol parsing as a plugin: MCP/A2A parsing populates ctx.Values, enabling tool-level authorization via composition
  • Observability by default: pipeline auto-instruments every plugin with OTel spans and metrics
  • Registry loading (v1): compiled-in via Go import + init() registration
  • Praxis alignment: three concrete integration models (A/B/C) with Phase 1 recommendation

What changed in v2

  • Clarity: grounded in actual codebase — shows real Auth struct, real listener code, real migration seams
  • Plugin terminology: renamed "filter" to "plugin" throughout. AuthBridge extensions are identity-aware security plugins, not generic stream filters
  • Innovation: identity-aware context, tighten-only enforcement mechanisms, auto-observability, tool-level authorization composition, concrete Praxis integration models

Discussion points

  • Body buffering budget for LLM prompts and SSE streaming
  • ext_proc body auto-configuration via operator
  • Multi-turn agent session context
  • Plugin interface versioning strategy
  • Praxis integration timeline

Assisted-By: Claude (Anthropic AI) noreply@anthropic.com

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>
@imolloy

imolloy commented Apr 24, 2026

Copy link
Copy Markdown

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 Context object, the Common Message Format and extensions have gone evolved from our original work and will allow for much more robust plugin systems, while also allowing us to build a strong capability model to prevent overwriting sensitive data, provide the tighten-only semantics, copy-on-write, etc.

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:

  • AgentIdentity : Need to see how this will encode delegation chains
  • Claims : would like to see what this looks like. Just scopes? RAR? etc.
  • Values map[string]any : We've done things like this in the past and found it causes issues (similar Authzen). The CMF and extensions are our solution.
  • Need to designate which plugins can and cannot mutate, which can affect the order and parallel execution
  • token-exchange : this should always be the last item in the pipeline
  • read-only claims: Need to see how this gets enforced in Go. Rust will provide strong separation.
  • Plugin Loading: if we use CPEX, you only need to initiate the library and register the hooks. All plugin loading, configuration, scheduling, etc. will be taken care of, which helps keeps the AuthBridge code base smaller.
  • Identity-Aware Protocol Policy : Check out APL, but why not use a policy language here like Cedar for more robust policies?

@huang195

Copy link
Copy Markdown
Member Author

Thanks Ian — this is really helpful feedback, and the timing is great. A few responses:

Values map[string]any — You're right, and the AuthZEN parallel is exactly the concern. We're thinking about replacing Values with typed extension slots — one struct per protocol domain (MCP, A2A, Security, etc.) with plugins declaring what they read and write. The pipeline would validate wiring at startup so mismatches are caught before any request arrives. This is directly inspired by CMF's typed-slot + capability model.

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:

  • AgentIdentity + delegation chains — agreed, will address in the next revision
  • Claims — currently carries scopes, subject, issuer, audience, client_id. We should discuss whether RAR belongs here
  • token-exchange ordering — good catch, will enforce as last in the outbound chain
  • Read-only claims enforcement — startup validation + unexported setter, but open to hearing how the Rust approach works

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.

@araujof

araujof commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

@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:

https://github.com/araujof/kagenti-extensions/blob/docs/authbridge_hook_system/docs/proposals/authbridge-hooks.md

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 map[string]any, capability-gated token and header access, delegation chain support in outbound hooks, and body access as a mode-validated opt-in.

I'd be happy to team up and refine it to cover any missing requirements, adjust scope, and incorporate feedback from others.

@huang195

Copy link
Copy Markdown
Member Author

@araujof Thanks for putting this together — the spec is thorough and clearly builds on lessons learned from the Praxis and Mellea integrations.

We've been thinking about how CPEX fits into AuthBridge's architecture, and we'd like to explore an approach where CPEX runs as a plugin within AuthBridge's Go pipeline rather than replacing it.

The idea:

AuthBridge Go Pipeline (sequential, we own lifecycle)
  ├── jwt-validation        ← built-in Go
  ├── mcp-parser            ← built-in Go
  ├── cpex-bridge           ← Go plugin wrapping CPEX runtime
  │     ├── cpex-plugin-1   ← WASM, native, etc.
  │     ├── cpex-plugin-2
  │     └── ...
  ├── token-exchange        ← built-in Go
  └── ...

Why this direction:

  • AuthBridge's core auth path (JWT validation, token exchange, MCP parsing) is a handful of deterministic Go operations. We'd like to keep those simple and compiled-in — easy to write, easy to debug, no FFI boundary.
  • CPEX brings real value for the extensibility use cases — capability-gated third-party plugins, WASM isolation, parallel policy evaluation, fire-and-forget audit. Running CPEX as a sub-pipeline means that complexity is opt-in for teams that need it.
  • No lock-in either direction — AuthBridge works without CPEX configured, and CPEX plugins get the full enriched context (validated claims, parsed MCP method/tool, agent identity, route) from upstream Go plugins.

What CPEX can do from this position:

  • Tool-level authorization (has claims + MCP context + agent identity)
  • Guardrails — pre-invocation argument inspection, post-response filtering (via OnResponse)
  • Audit with fire-and-forget (has full context)
  • Complex policy orchestration (parallel fan-out to multiple engines)
  • Capability-gated extension access (token isolation, etc.)

What would stay as native Go plugins:

  • JWT validation and token exchange (core auth, deterministic)
  • Protocol parsing (MCP/A2A — or eventually handled by Praxis)
  • Simple inline rules (rate limiting, IP blocking)

Lifecycle hooks: We are open to adding OnStartup / OnShutdown to our Plugin interface, so the CPEX bridge can initialize the Rust runtime and fire S1/S2/S3 hooks internally.

Questions for discussion:

  • Does the CPEX runtime work well as an embedded sub-pipeline, or is it designed to own the full dispatch? Are there constraints that make this model difficult?
  • What does the Go-side integration surface look like? Is cpex-go usable as a library that we call into from a single plugin, or does it expect to own main()?
  • For the typed extension slots and capability gating — we are considering implementing this at the Go pipeline level as well (plugins declare what they read/write, pipeline validates at startup). If CPEX also does capability gating internally, how do the two layers compose? Should we rely on CPEX for gating within its scope and keep the Go layer simple, or implement both independently?

Would be great to discuss this in more detail — happy to set up time if that is easier than async.

5. **Declare what you need** — body access is opt-in per plugin; the pipeline
only buffers the body when at least one plugin requests it
6. **Identity-first** — every plugin receives the agent's own identity and
the caller's validated claims, enabling security decisions no external

@esnible esnible Apr 30, 2026

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.

How will outbound plugins become aware of the caller's validated claims? Don't we need to solve #182 first?

@huang195 huang195 Apr 30, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good point. Per the issue you linked, the easiest path forward is to propagate the token from inbound path to outbound, so it can be used to correlate sessions. Other suggestions are welcome.

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.

FYI: Some services use multiple credentials. For example, a bookstore checkout service might use the user's credentials for billing and shipping, but use the bookstores credentials to generate advertisements for similar books. In that scenario, maybe there is NO incoming request and NO incoming token.

@araujof

araujof commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Thanks @huang195! The design direction you described using a "cpex-bridge" makes a lot of sense and aligns well with the spec, and I think we can converge cleanly. It would be great to find time to brainstorm next steps in more detail.

A couple of areas worth digging into are (1) how we define the payloads and extensions (metadata) created at the predefined AuthBridge hook call sites before invoking the CPEX plugin pipeline, and (2) the wire protocol for handling results (e.g., continuation, payload mutation, abort semantics).

Agreement on the layered model

Your framing maps well to the assumptions in the spec:

Your model                          Spec equivalent
─────────────────────────────────   ────────────────────────────────────────────
AuthBridge Go Pipeline              AuthBridge owns the lifecycle, defines hook
  ├── jwt-validation (Go)             call sites, and enforces results
  ├── mcp-parser (Go)
  ├── cpex-bridge (Go plugin)       CPEX PluginManager embedded in-process;
  │     └── CPEX sub-pipeline         invoked at each hook call site
  ├── token-exchange (Go)
  └── ...                           Built-in Go logic runs before/after hooks

AuthBridge's "cpex-bridge" request flow could look like the following at each hook point (sketch):

// 1. AuthBridge constructs typed payload + extensions from call-site context
payload := &InboundPayload{...}
extensions := &cpex.Extensions{
    Meta: &cpex.MetaExtension{
        EntityType: "request",
        EntityName: req.URL.Path,
        Tags:       routeTags,
    },
    Security: &cpex.SecurityExtension{
        Agent: &cpex.AgentIdentity{
            ClientID:    cfg.ClientID,
            WorkloadID:  cfg.SpiffeID,
            TrustDomain: cfg.TrustDomain,
        },
        Token: authHeader,  // capability-gated: only plugins with read_token see this
    },
    Http: &cpex.HttpExtension{
        Method:         req.Method,
        Path:           req.URL.Path,
        Host:           req.Host,
        RequestHeaders: req.Header,
    },
}

// 2. Invoke CPEX: the PluginManager dispatches to all registered plugins
//    (guardrails, policy engines, audit logger, etc.)
result, bg, err := mgr.Invoke("inbound.pre_validation", payload, extensions, ctxTable)
if err != nil {
    return abortWithError(err)
}

// 3. Enforce tighten-only: a deny from any plugin is final
if !result.ContinueProcessing {
    return denyRequest(result.Violation)
}

// 4. Apply mutations (if payload was modified by a transform-mode plugin)
if result.ModifiedPayload != nil {
    applyPayloadMutations(result.ModifiedPayload)
}

// 5. Thread context table into the next hook for state continuity
ctxTable = result.ContextTable

// 6. Background tasks run outside latency budget
defer bg.Wait()

Answering your questions

Does CPEX work well as an embedded sub-pipeline?

Yes, this is the designed integration model. The Go bindings proposal (cpex-go) exposes PluginManager as a component that the host calls into. It does not expect to own main(). The flow is:

  1. Startup: AuthBridge calls cpex.NewPluginManager(yaml)mgr.Initialize()
  2. Per-request: AuthBridge calls mgr.Invoke(hookName, payload, extensions, ctxTable) at each hook call site
  3. Shutdown: AuthBridge calls mgr.Shutdown()

CPEX handles everything inside the invoke boundary (route resolution, phase ordering, parallel dispatch, capability gating, context management). AuthBridge owns everything outside (lifecycle, payload construction, result enforcement, tighten-only semantics).

The FFI boundary (payload, extensions)->result is crossed exactly once per hook invocation, not once per plugin. Plugin-to-plugin dispatch within the CPEX executor is native Rust with zero serialization overhead.

What does the Go-side integration surface look like?

The API is minimal:

// Lifecycle, initializes the plugin manager from configuration, loads and registers plugins to hook points
mgr, err := cpex.NewPluginManagerFromFile("plugins.yaml")
mgr.Initialize()
defer mgr.Shutdown()

// Invocation (typed, deserializes result payload into P)
result, bg, err := cpex.Invoke[InboundPayload](mgr,
    "inbound.post_validation", payload, extensions, ctxTable)

How do two capability-gating layers compose?

The spec already relies on CPEX's capability model for all extension access. The Go pipeline doesn't implement a parallel gating mechanism; it constructs the full Extensions struct and hands it to CPEX. CPEX filters the extensions per plugin based on declared capabilities. The Go side trusts CPEX's gating and doesn't duplicate it.

Where the Go layer adds value is in controlling what it puts into Extensions in the first place. For example, Security.Token is only populated at hooks where the raw token is contextually relevant. This means plugins can't request a token at startup because it hasn't been extracted yet.

What this gives us concretely

The layered model unlocks several capabilities:

  • Tool-level authorization: A plugin at inbound.post_validation receives Security.Subject (claims, scopes) + Meta.EntityName (tool name from MCP context) → can enforce fine-grained policies
  • Guardrails: Transform-mode plugin at outbound.pre_exchange inspects/modifies payload before token exchange fires
  • Audit: Fire-and-forget plugin at *.completed hooks logs full context without affecting latency
  • Parallel policy fan-out: Concurrent-mode plugins at validation hooks (e.g., OPA + Cedar + custom) run in parallel, merged with tighten-only semantics
  • State across hooks: ContextTable threads per-plugin state from inbound.received through inbound.completed; useful for correlation, metrics, rate-limit counters
  • Zero cost when unused: If no plugins: section in config, hook call sites short-circuit with a nil-check

Next steps

I'd suggest we:

  1. Converge on the hook types: we could start with a small set of hooks to demonstrate value.
  2. Validate the cpex-go API surface against the invocation patterns
  3. Prototype the bridge: define a simple and generic interface for AuthBridge plugins with a minimal cpex-bridge integration that wires mgr.Invoke() into one inbound hook (e.g., inbound.post_validation) and one outbound hook (outbound.pre_exchange) to validate the integration end-to-end

@huang195

Copy link
Copy Markdown
Member Author

Thanks Fred — good to see alignment on the layered model.

On extensions mapping: we've gone through CPEX's extension types and not everything is relevant to AuthBridge (e.g., CompletionExtension, LLMExtension, FrameworkExtension are application-level concerns we don't handle at the proxy layer). But for the ones that are relevant, we're defining our own Go structs that keep the same shape to make the translation layer at the bridge boundary as thin as possible:

  • MCPExtension — three-variant (tool/resource/prompt), mirrors CPEX's MCP slot
  • DelegationExtension — structured hops with origin/actor/scopes, mirrors CPEX's delegation
  • SecurityExtension — labels + blocked flag (subset of CPEX's — caller identity is already a top-level field in our Context, so we don't need SubjectExtension)
  • A2AExtension — ours (CPEX doesn't have a dedicated one)
  • Custom map[string]any — escape hatch

The Go pipeline populates these before calling into the CPEX bridge. Because the shapes align, the bridge adapter should be a straightforward field-to-field mapping.

Agree on starting small for next steps.

@mrsabath mrsabath left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well-structured plugin architecture proposal. All codebase references verified against current main — the Auth struct composition, ext_proc listener line count (~170 → actual 174), and directory structure all check out. The design principles (single interface, tighten-only enforcement, mode-agnostic adapters) are sound, and the active CPEX integration discussion shows good community convergence.

Areas reviewed: Documentation accuracy, codebase reference verification, security (no secrets), commit conventions
Commits: 3 commits, all signed-off ✓
CI: All checks passing ✓

"path", ctx.Path,
"agent", ctx.Agent.ClientID,
"caller", ctx.Claims.Subject)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: ctx.Response is referenced here, but the Context struct definition (line 87) has no Response field — it only defines request-side fields (Method, Host, Path, Headers, Body) plus identity fields (Agent, Claims, Route) and Values.

Consider either:

  1. Adding a Response *ResponseInfo field to the Context struct definition, or
  2. Reworking this example to use fields that exist on the proposed Context (e.g., ctx.Values["response_status"])

Minor inconsistency — doesn't block the proposal.

forward proxy listeners are similar. The adapter pattern already exists in
the codebase — this proposal formalizes it and opens it to extension.

The `ActorTokenSource` and `AudienceDeriver` function types are the existing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Good grounding — the "~170 lines" claim for ext_proc checks out (actual: 174 lines) and the Auth struct composition matches current main. Anchoring proposals in verifiable codebase facts makes the doc credible and reviewable.

@evaline-ju

Copy link
Copy Markdown
Contributor

More addressing the broader discussion:

(1) Since there’s been the push in previous solutions on BBR - I think it’s worth addressing in this earlier design and discussion stage how this solution here differentiates and what use cases it enables to justify the complexity

Specifically https://github.com/kubernetes-sigs/gateway-api-inference-extension/tree/main/pkg/bbr/framework has the

(2) For the request -> response ordering, if I’m understanding correctly, currently the example Go pipeline should end up with:

Request: jwt-validation -> mcp-parser -> guardrail through cpex-bridge -> token-exchange
Response: token-exchange->guardrail through cpex-bridge -> mcp-parser -> jwt-validation

Particularly on the guardrail through cpex-bridge -> mcp-parser OnResponse runs, if a tool call response had to be parsed for a guardrail, should each guardrail be expected to work on (unmarshal, etc) pctx.Body and not a parsed MCP tool result, or likely risk duplicating mcp-parser logic? The current extension metadata structs also seem fairly catered towards requests.

Some consistency could be created through the cpex bridge eventually, but not account for the plugins generally - is this the intended experience?

@huang195

huang195 commented May 1, 2026

Copy link
Copy Markdown
Member Author

Thanks Evaline — both good points.

(1) Differentiation from BBR

They operate at different layers. BBR is inference routing — model selection, body transformation, load balancing. AuthBridge's pipeline is auth-layer: JWT validation, RFC 8693 token exchange, SPIFFE delegation chains, and protocol-level authorization (is this agent allowed to call tool X with these scopes?).

BBR doesn't handle workload identity, per-hop token exchange with audience narrowing, or delegation chain tracking. The two could coexist — BBR at the inference gateway, AuthBridge at the agent-to-agent auth boundary. We should make this layering explicit in the doc.

(2) Response ordering and guardrails

You're right — strict LIFO creates a problem. If guardrails run OnResponse before mcp-parser, they'd have to re-parse MCP tool results from raw body bytes.

The plan is to support explicit response ordering separate from request ordering:

  • Request: jwt-validation → mcp-parser → guardrails → token-exchange
  • Response: mcp-parser → guardrails → ... (parser populates typed extensions first, guardrails inspect parsed results)

The extension metadata also needs response-side variants — tool result, status, output content — so guardrails work with pctx.Extensions.MCP.Result rather than raw bytes. We'll address response ordering explicitly in the next revision of the proposal.

@evaline-ju

Copy link
Copy Markdown
Contributor

Thanks @huang195! I had a couple more questions on the response ordering details

The plan is to support explicit response ordering separate from request ordering

With the protocol plugins being associated with their parsers, is there going to be a way for plugin writers to ‘declare’ what protocols their plugins should work with - mcp, a2a, potentially both (if possible) since that would affect what parsers should be expected to run first?

We'll address response ordering explicitly in the next revision of the proposal.

And also related to the above, overall, how should a persona configuring the AuthBridge plugins know how to do the plugin ordering? Will they need deep knowledge of each plugin or be able to quickly inspect some info (specifically is it enough to just be based on the extension.x.result input to the plugin?)

@araujof

araujof commented May 6, 2026

Copy link
Copy Markdown
Contributor

@huang195 we finished the first version of CPEX Go. I created a short specification of the implemented public API in this document. It contains a summary of the consumption API, and includes examples so you can see how it works.

Our next step is to agree on the interface for the AuthBridge plugin and data types. Once we have that, we will refactor our initial spec targeting cpex-bridge and the integration point we discussed, and prototype it.

cc: @mrsabath @imolloy

@huang195

Copy link
Copy Markdown
Member Author

closing this PR as it's easier just to iterate on the current code instead of over design.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants