Replies: 3 comments 2 replies
-
|
Thanks for the detailed write-up, and the proposal in the PR! One of the main things I'm noticing is that this proposal overlaps significantly with the existing filters system. Many of the hooks described seem to fit into places that are already covered. The part that isn't well-covered are the life-cycle hooks at startup, shutdown, cert-reload, etc. I have some questions to help me understand the gaps a bit better:
Thank you! 🖖 |
Beta Was this translation helpful? Give feedback.
-
|
Thanks @shaneutt ! These are great questions. I think they hint at a framing issue worth fixing in the doc. Let me try to clarify a few points here, and let me know if the proposed changes to the doc make sense, so I can get to them asap. Hooks are not a second filter systemThe doc reads as if hooks and filters are parallel ideas, which lands as "two ways to do the same thing." That's not the intent:
So hooks don't supersede filters and aren't built from them. They are named contracts inside Praxis (sometimes inside filters) where policy or observation code can plug in with a stable, typed contract. The MCP gateway filter is the clearest example: JSON-RPC parsing happens in the filter, but the deny/redact decision happens at a named hook with a Q1: Which reference plugins can't be filters today?Three categories. Things filters genuinely can't do. Anything outside the per-request path: rejecting startup when Things filters could implement but degrade by doing so.
Things filters can do well, and that the hook system piggybacks on. ext-authz is a good example. See Q2. Q2: ext-authz specifically, hook vs. filter?You're right that ext-authz fits a filter cleanly. The hook isn't replacing the filter; it specifies the contract at the decision point, separately from how the decision gets dispatched. Some advantages: tighten-only composition (a A reasonable middle path: ship ext-authz as a filter that internally dispatches the hook, mirroring what the MCP gateway filter does for tool hooks. Same hook names, same plugins, dispatch site is a filter today. Q3: What are the other CPEX hosts?CPEX is host-agnostic. Planned additions are Wasm, Go, and Python runtimes via the Q4: Why a dispatcher framework over focused traits?For lifecycle alone, I agree that focused traits in
Building lifecycle on bespoke traits and the rest differently gives us two extension surfaces, which is exactly the duplication we may want to avoid. One runtime for all three keeps plugin authors on one mental model. Suggested edits to the doc
|
Beta Was this translation helpful? Give feedback.
-
|
There is a lot to think about in relation to this, and the following may touch The PR[63] and related Discussion[188] represent some features that are in part CPEX is solving an organizational/ecosystem problem (shared MessagePayload Praxis filters already do some of this. A request_filter can short-circuit the In Praxis's filter pipeline, a filter that returns a terminal response CPEX though provides some impressive functionality that is potentially not in The delta CPEX adds for policy enforcement is narrow if we consider
Those are real operational niceties, but they don't require a separate plugin Where this can get messy is using a sequence of filters where instead CPEX is ideal is Using a yaml defined sequence of filters for complex work flows is not ideal. It To separate the concerns, Filters vs Policy, to allow for use of CPEX or any A generic delegation model, that could consider Praxis almost as an API would If a configuration says "if " matches a request then hand off This adds another benefit that if an organisation has previous experience in say PR #63 is not so much a delegation interface. It proposes the opposite The main argument for the CPEX proposal is valid, we just need to Footnote: This is not simply reworking ext_proc, a tool to enable extension of Praxis to a number of infrastructure backends becomes in effect the proxy equivalent of vscode or firefox addons. A possible list of "extension points" to allow delegation could be something like the following list. Lifecycle
Per-request (observe / mutate / policy)
Protocol-semantic
Identity / authz
Session
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi folks!
I opened this proposal PR some time ago, but just wanted to share it here in an attempt to get feedback on it.
Any comments are welcome!
Motivation
Praxis enforces built-in security invariants (root refusal, host validation, hop-by-hop stripping, body size ceilings, SNI enforcement, etc.) but offers no way for operators to layer additional policy at these boundaries without directly modifying the proxy. Filters handle per-request transformation; they are an insufficient abstraction for lifecycle events (TLS rotation, startup validation, shutdown), cross-cutting policy (external authorization, identity resolution), and protocol-semantic enforcement (gating MCP tool calls before they reach upstream).
An extensibility surface at security boundaries lets operators strengthen invariants, adding ext-authz, enforcing production hardening, redacting sensitive tool arguments, without weakening the built-in guarantees.
Proposal
A typed, capability-gated hook system embedded in-process via CPEX. Plugins observe or enforce policy at well-defined lifecycle and protocol-semantic points.
Core properties:
v1 scope: hooks across startup, TLS, HTTP lifecycle, identity, and MCP tool invocation. Plugins are compiled-in Rust crates; dynamic loading specified for a later phase.
References
cc: @shaneutt
Beta Was this translation helpful? Give feedback.
All reactions