feat: build the CPEX demo against the Praxis Policy Engine - #9
Conversation
Adds a second link, gateway/praxis-policy. praxis depends on the engine by relative path and cargo resolves that lexically rather than through the .praxis symlink, so ../praxis-policy lands inside the gateway directory. patch.crates-io cannot redirect it either, because the engine is unpublished. Bumps praxis-ai to a revision that wants praxis 0.5. The old pin wanted ^0.4, which the patch could not satisfy, so cargo silently pulled 0.4.1 from crates.io and the graph carried two praxis stacks. praxis-ai then built its pipeline from the one without the policy filter, giving 'unknown filter type: policy'. Renames the enabling feature off the old project name. All eleven scenarios pass against the ported engine. Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
praxis now depends on the policy engine by git revision rather than a sibling path, and the patch only redirects praxis-proxy-*, so cargo fetches the engine itself. The second link is dead: verified the gateway builds without it. Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
The demo already showed the same policy expressed for two decision points, Cedar and CEL. OPA is now gated and exposed in the engine the same way, so the demo gains the third: cpex-opa.yaml carries the Rego modules and an `opa` route step, praxis-opa.yaml selects it. Verified against the running stack: all 11 scenarios pass, and OPA is the component deciding rather than passing incidentally. Scenario 04 allows on `visibility=internal` and scenario 05 reports `opa.policy_denied`, so the Rego rule was evaluated in both directions. The gateway needs no change. Its `policy-engine` feature pulls `dep:ppe`, which now carries `opa`, so the lock gains the regorus interpreter. Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
Praxis moved to the engine's single `builtins` umbrella, so the revision this lock pins moves with it. A pure revision swap, 16 entries for 16: the umbrella resolves to the same crates the nine enumerated features did. Verified on a fresh stack under praxis-opa.yaml: 11 scenarios pass, and scenario 05 still reports `X-Policy-Violation: opa.policy_denied` with no Cedar or CEL code present, so the Rego decision point is still the one deciding. Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
|
Heads up — while independently digging into the cpex gateway's Opened #12 as a narrow, standalone fix for that: drops the personal HIL fork patch (verified its remaining changes already landed on Since #12 touches the same |
Thanks for the heads up! The plan is to merge this PR as soon as we publish PPE (which will replace cpex as a dependency in praxis). Merging #12 now, will reconcile with this one. |
Reconciles praxis-proxy#12, which dropped the HIL fork patch and moved the demo onto published praxis. All three conflicts are the same decision, where praxis comes from, and all resolve to this branch: the demo exercises the Praxis Policy Engine, and no published praxis carries the `policy-engine` feature yet. Taken from main: the praxis-ai revision bump. Ours was a strict ancestor of it, 148 commits behind on the same line, so it is a clean upgrade. That bump turned out to introduce the exact problem praxis-proxy#12 describes, and the fix needed here differs from main's. Between the two revisions praxis-ai moved its praxis-proxy-* dependencies from crates.io to a git tag, and `[patch.crates-io]` cannot redirect a git dependency. The graph ended up with two copies of praxis-proxy-filter: the patched local one carrying `policy-engine`, and the tagged one from v0.5.2 without it. The AI server registers filters from its own copy, so the `policy` filter would have silently never loaded. A second `[patch]` on the git source unifies both references on the local checkout; the lock now resolves one copy. Also restored two blocks that git deleted without reporting a conflict, because main removed them and the removals merged cleanly: the `[patch.crates-io]` section itself, and the praxis-resolution step in build-gateway.sh. Without them the tree documents a `.praxis` checkout it never creates and quietly resolves praxis from crates.io. Its default ref is now `main` rather than the retired fork branch. Verified against the running stack, not just a build. All 11 scenarios pass on the OPA config, and each of the three decision points is confirmed to be the one deciding: `opa.policy_denied`, `cedar.default_deny`, `cel.policy_denied`. Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
Builds the HR demo gateway against the new praxis-proxy/policy crates. Depends on praxis-proxy/praxis#943.
Draft until the engine is published, since praxis pins it by git revision rather than a version.
Changes
praxis-ai-proxyto a revision that wants praxis 0.5. The old pin wanted^0.4, which[patch.crates-io]could not satisfy, so cargo silently pulled 0.4.1 from crates.io and the graph carried two praxis stacks. praxis-ai then built its pipeline from the one without the policy filter, producingunknown filter type: 'policy'.policy-engine.The engine itself needs no local checkout: praxis pins it by git revision, and the patch only redirects
praxis-proxy-*, so cargo fetches it.Verification
All 11 scenarios pass: identity, RFC 8693 token exchange, Cedar and CEL decisions, redaction, PII scanning, session taint across requests and principals, and out-of-band CIBA approval.
The policy documents are untouched.
cpex.yamlandcpex-cel.yamlare byte-identical to their pre-port versions, which is the wire-compatibility guarantee demonstrated end to end.