Releases: contextforge-org/cpex
Releases · contextforge-org/cpex
Release list
v0.2.0
Added
- CPEX redesign as a Rust framework with Go bindings
- APL (Attribute Policy Language) governance is now bundled into
libcpex_ffi.a. Newcpex_apl_installextern C entry point registers the standard APL plugin/PDP factories (validator/pii-scan,audit/logger,identity/jwt,delegator/oauth,cedar-direct) and installs the APL config visitor on a manager. Call it aftercpex_manager_new_defaultand beforecpex_load_config. Go hosts usePluginManager.EnableAPL(). (#60) - Publish
libcpex_ffi.aas signed GitHub Release artifacts on every semver tag push (linux-amd64-gnu,linux-arm64-gnu,linux-amd64-musl,linux-arm64-musl,darwin-arm64). Cosign keyless signatures + SHA256 checksums; seecrates/cpex-ffi/RELEASE.mdfor the schema and the verify-and-consume recipe. (#60) - FFI ABI versioning:
cpex_ffi_abi_version()extern C accessor exposesFFI_ABI_VERSION. The Go binding checks this ininit()and panics on mismatch. Other language bindings must replicate the check. (#60) - CEL (Common Expression Language) policy decision backend. A new
apl-pdp-celcrate registerskind: cel, letting authors write inline boolean predicates (cel: { expr: ... }) over the common attribute vocabulary (subject.id,delegation.depth,session.labels, ...), evaluated through the existingPdpResolverseam alongside Cedar, OPA, and AuthZen. Expressions compile once and cache by source; compile errors, undeclared-variable references, and non-boolean results fail closed (deny), overridable withon_error: allow. No change to APL evaluation semantics. (#68) - APL authoring ergonomics (backwards-compatible). The
apl:wrapper is now optional — recognized APL terms (policy,post_policy,args,result,pdp,session_store) written directly on a section are honored, with the explicitapl:form still taking precedence.run(name)is accepted as an alias forplugin(name)in both policy steps and field pipelines. Unconditionaldeny('reason')/deny('reason', 'code')now parses as a bare action (e.g. inon_deny:lists), so a reason/code can be attached without a conditional. (#71) - Valkey-backed
SessionStorefor cross-node and cross-restart session label propagation. Selectable via akind: valkeyblock underglobal.apl.session_store(factory pattern mirroringpdp), shipped in theapl-session-valkeycrate and wired intocpex-ffibehind the optionalvalkeycargo feature (the default build and.aartifact are unaffected). Labels live in a Redis SET so appends are an atomic server-side union (SADD); the store is fail-closed (a load/append error denies the request rather than under-labeling), serves primary-only reads, supports an optional sliding TTL, requires TLS for non-localhost endpoints, and SHA-256s session ids out of the keyspace. When no block is configured the default remains the in-process memory store. See the operator runbook atdocs/operations/valkey-session-store.md. (#74) cpexhost facade crate: a single dependency that re-exports the host runtime (PluginManager,AplOptions,register_apl) and the bundled plugin factories, each behind a cargo feature (jwt,oauth,pii,audit,cedar,cel,valkey). Hosts depend oncpexand enable the plugins they want instead of pinningapl-cmf/apl-cpex/apl-pdp-*/apl-session-*individually.install_builtins(&mgr)registers every enabled factory and installs the APL config visitor in one call;register_builtin_plugins,builtin_pdp_factories, andbuiltin_session_store_factoriesexpose the pieces for hosts that assembleAplOptionsthemselves. (#77)cpex-builtinsaggregator crate: the bundled extension set (plugins, PDPs, session stores) behind a 1:1 cargo-feature map, with a declarativeregister_builtins!macro that expands to explicit,#[cfg]-gatedregister_factorycalls (kept explicit rather thaninventory/linkmeso factory symbols survive the linker GC insidelibcpex_ffi.a).register_builtins,builtin_pdps,builtin_session_store_factories, andinstall_builtinsare the single source of truth that both thecpexfacade andcpex-ffinow delegate to. (#72)
Changed
- The
cpexfacade is now engine-only by default:cpex = "0.2"compiles no builtin plugins. The bundled set is opt-in via the newbuiltinsfeature (the common in-process set) orfull(everything, incl. Valkey), with the granular plugin features (jwt,oauth,pii,audit,cedar,cel,valkey) preserved as passthroughs. The registration helpers and concrete factory types are re-exported fromcpex-builtinsand appear only when a builtins feature is enabled.cpex-ffikeeps its prior bundled set (four hook plugins +cedar-direct) by selecting that exactcpex-builtinsfeature subset. No FFI ABI change. (#72) PluginFactoryRegistry::registernow logs atracing::warn!when a registration overwrites an existingkind(last-writer-wins is unchanged, but silent override was a footgun). (#72)- Builtin extension crates moved out of the flat
crates/directory into abuiltins/tree (builtins/plugins/,builtins/pdps/,builtins/session/,builtins/cedarling/) and renamed off theapl-prefix, since they are CPEX plugins that use APL hooks rather than APL itself:apl-pii-scanner→cpex-plugin-pii-scanner,apl-audit-logger→cpex-plugin-audit-logger,apl-identity-jwt→cpex-plugin-identity-jwt,apl-delegator-oauth→cpex-plugin-delegator-oauth,apl-delegator-biscuit→cpex-plugin-delegator-biscuit,apl-pdp-cedar-direct→cpex-pdp-cedar-direct,apl-pdp-cel→cpex-pdp-cel,apl-session-valkey→cpex-session-valkey,apl-cedarling→cpex-cedarling. The policy crates (apl-core,apl-cmf,apl-cpex) keep their names. Config-facingkind:strings and the FFI C ABI are unchanged. (#72) - FFI
FFI_ABI_VERSIONbumped1 → 2: added thecpex_apl_installextern C function and changedcpex_load_configto run registered config visitors (it now callsload_config_yamlinternally soapl:blocks are walked). The Go binding'sexpectedFFIABIVersionis bumped in lockstep. (#60) - Size-first
[profile.release]:opt-level = "z",lto = true,codegen-units = 1,strip = true.libcpex_ffi.ais linked statically into host binaries, so this flows straight into their image size — a representative statically-linked consumer shrank ~21%.panic = "abort"is intentionally not set (the FFI relies oncatch_unwindat its#[no_mangle]boundary). No API or ABI change. (#69) - Trimmed the workspace
tokiofeature floor from["full"]to["rt", "rt-multi-thread", "sync", "time", "macros"]— the union of what the crates actually use;reqwest/hyperstill pullnet/iowhere they need them via feature unification. Drops the unusedfs/process/signalsurface (and thesignal-hook-registrydependency). (#69) SessionStoretrait methods (load_labels/append_labels) now returnResultso backend failures propagate to callers — the error channel fail-closed requires.MemorySessionStoreis infallible and adapts trivially; the CMF invoker (for_request/persist_session) and the route handler propagate the error and fail the request closed on a load/append failure. This is part of the sharedSessionStorecontract that future bridges inherit. (#74)
Removed
- Removed the
cpex-cedarlingcrate (a Sub-step A stub with no real Cedarling calls), itscpex-ffioptional dependency +cedarlingcargo feature, and thecedarlingPDP dialect from the APL grammar (PdpDialect::Cedarlingandcedarling:step recognition). This drops the onlygitdependency in the workspace (the Janssencedarlingcrate, ~200 transitive deps), making every crate publishable to crates.io. Cedarling was wired nowhere — no config, host, or Go binding referenced it — so there is no functional change; the remaining PDPkind:strings (cedar-direct,cel) and the FFI C ABI are unchanged. Acedarling-backed PDP can still be supplied out-of-tree (it degrades toPdpDialect::Custom, alongside the resolver-lessopa/authzen/nemodialects).
Fixed
- Cedar evaluation no longer fails with "recursion limit reached" on hosts that give the FFI a small thread stack (notably musl, whose default is 128 KiB).
cedar-policyaborts whenstacker::remaining_stack()is below its 100 KiB floor; the cedar dispatch inapl-pdp-cedar-directis now wrapped instacker::maybe_grow, so it runs on an adequately sized stack regardless of the host (a no-op when there is already headroom, e.g. glibc's 8 MiB threads). Regression test exercises a real evaluation on a 128 KiB stack. (#69)
v0.2.0-alpha.4
Added
cpexhost facade crate: a single dependency that re-exports the host runtime (PluginManager,AplOptions,register_apl) and the bundled plugin factories, each behind a cargo feature (jwt,oauth,pii,audit,cedar,cel,valkey). Hosts depend oncpexand enable the plugins they want instead of pinningapl-cmf/apl-cpex/apl-pdp-*/apl-session-*individually.install_builtins(&mgr)registers every enabled factory and installs the APL config visitor in one call;register_builtin_plugins,builtin_pdp_factories, andbuiltin_session_store_factoriesexpose the pieces for hosts that assembleAplOptionsthemselves. (#77)
v0.2.0-alpha.3
Added
- CEL (Common Expression Language) policy decision backend. A new
apl-pdp-celcrate registerskind: cel, letting authors write inline boolean predicates (cel: { expr: ... }) over the common attribute vocabulary (subject.id,delegation.depth,session.labels, ...), evaluated through the existingPdpResolverseam alongside Cedar, OPA, and AuthZen. Expressions compile once and cache by source; compile errors, undeclared-variable references, and non-boolean results fail closed (deny), overridable withon_error: allow. No change to APL evaluation semantics. (#68) - APL authoring ergonomics (backwards-compatible). The
apl:wrapper is now optional — recognized APL terms (policy,post_policy,args,result,pdp,session_store) written directly on a section are honored, with the explicitapl:form still taking precedence.run(name)is accepted as an alias forplugin(name)in both policy steps and field pipelines. Unconditionaldeny('reason')/deny('reason', 'code')now parses as a bare action (e.g. inon_deny:lists), so a reason/code can be attached without a conditional. (#71) - Valkey-backed
SessionStorefor cross-node and cross-restart session label propagation. Selectable via akind: valkeyblock underglobal.apl.session_store(factory pattern mirroringpdp), shipped in theapl-session-valkeycrate and wired intocpex-ffibehind the optionalvalkeycargo feature (the default build and.aartifact are unaffected). Labels live in a Redis SET so appends are an atomic server-side union (SADD); the store is fail-closed (a load/append error denies the request rather than under-labeling), serves primary-only reads, supports an optional sliding TTL, requires TLS for non-localhost endpoints, and SHA-256s session ids out of the keyspace. When no block is configured the default remains the in-process memory store. See the operator runbook atdocs/operations/valkey-session-store.md. (#74)
Changed
SessionStoretrait methods (load_labels/append_labels) now returnResultso backend failures propagate to callers — the error channel fail-closed requires.MemorySessionStoreis infallible and adapts trivially; the CMF invoker (for_request/persist_session) and the route handler propagate the error and fail the request closed on a load/append failure. This is part of the sharedSessionStorecontract that future bridges inherit. (#74)
v0.2.0-alpha.2
Changed
- Size-first
[profile.release]:opt-level = "z",lto = true,codegen-units = 1,strip = true.libcpex_ffi.ais linked statically into host binaries, so this flows straight into their image size — a representative statically-linked consumer shrank ~21%.panic = "abort"is intentionally not set (the FFI relies oncatch_unwindat its#[no_mangle]boundary). No API or ABI change. (#69) - Trimmed the workspace
tokiofeature floor from["full"]to["rt", "rt-multi-thread", "sync", "time", "macros"]— the union of what the crates actually use;reqwest/hyperstill pullnet/iowhere they need them via feature unification. Drops the unusedfs/process/signalsurface (and thesignal-hook-registrydependency). (#69)
Fixed
- Cedar evaluation no longer fails with "recursion limit reached" on hosts that give the FFI a small thread stack (notably musl, whose default is 128 KiB).
cedar-policyaborts whenstacker::remaining_stack()is below its 100 KiB floor; the cedar dispatch inapl-pdp-cedar-directis now wrapped instacker::maybe_grow, so it runs on an adequately sized stack regardless of the host (a no-op when there is already headroom, e.g. glibc's 8 MiB threads). Regression test exercises a real evaluation on a 128 KiB stack. (#69)
v0.2.0-alpha.1
Added
- Initial Rust version of CPEX
- Go support via cgo bindings
- APL (Attribute Policy Language) governance is now bundled into
libcpex_ffi.a. Newcpex_apl_installextern C entry point registers the standard APL plugin/PDP factories (validator/pii-scan,audit/logger,identity/jwt,delegator/oauth,cedar-direct) and installs the APL config visitor on a manager. Call it aftercpex_manager_new_defaultand beforecpex_load_config. Go hosts usePluginManager.EnableAPL(). The optionalcedarlingcargo feature adds the Cedarling-backed identity + PDP seams (off by default; the released.astays lean). (#60) - Publish
libcpex_ffi.aas signed GitHub Release artifacts on every semver tag push (linux-amd64-gnu,linux-arm64-gnu,linux-amd64-musl,linux-arm64-musl,darwin-arm64). Cosign keyless signatures + SHA256 checksums; seecrates/cpex-ffi/RELEASE.mdfor the schema and the verify-and-consume recipe. (#60) - FFI ABI versioning:
cpex_ffi_abi_version()extern C accessor exposesFFI_ABI_VERSION. The Go binding checks this ininit()and panics on mismatch. Other language bindings must replicate the check. (#60)
Changed
- FFI
FFI_ABI_VERSIONbumped1 → 2: added thecpex_apl_installextern C function and changedcpex_load_configto run registered config visitors (it now callsload_config_yamlinternally soapl:blocks are walked). The Go binding'sexpectedFFIABIVersionis bumped in lockstep. (#60)