Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [Unreleased]

### Changed

- **BREAKING — APL authz/authn config keys renamed** for clarity. The old key names no longer parse; a config using them fails to load with an error naming the replacement (a dropped authorization or authentication block would otherwise fail open, so the rejection is deliberate). Migration:
- `identity:` → `authentication:` (at `global`, per-route, and policy-group scope)
- `policy:` → `authorization.pre_invocation:` (or flat `pre_invocation:`)
- `post_policy:` → `authorization.post_invocation:` (or flat `post_invocation:`)

The two authorization phases may be written either nested under an `authorization:` block or flat directly on the section; the forms are equivalent. The field-pipeline keys `args:` / `result:` are unchanged (they stay aligned with the `args.*` / `result.*` attribute namespaces that predicates and interpolation read). Internal APL IR is unchanged. (#105)

## [0.2.0] - 2026-06-26

### Added

- CPEX redesign as a Rust framework with Go bindings
- APL (Attribute Policy Language) governance is now bundled into `libcpex_ffi.a`. New `cpex_apl_install` extern 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 after `cpex_manager_new_default` and before `cpex_load_config`. Go hosts use `PluginManager.EnableAPL()`. (#60)
- APL (Authorization Policy Language) governance is now bundled into `libcpex_ffi.a`. New `cpex_apl_install` extern 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 after `cpex_manager_new_default` and before `cpex_load_config`. Go hosts use `PluginManager.EnableAPL()`. (#60)
- Publish `libcpex_ffi.a` as 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; see `crates/cpex-ffi/RELEASE.md` for the schema and the verify-and-consume recipe. (#60)
- FFI ABI versioning: `cpex_ffi_abi_version()` extern C accessor exposes `FFI_ABI_VERSION`. The Go binding checks this in `init()` and panics on mismatch. Other language bindings must replicate the check. (#60)
- CEL (Common Expression Language) policy decision backend. A new `apl-pdp-cel` crate registers `kind: cel`, letting authors write inline boolean predicates (`cel: { expr: ... }`) over the common attribute vocabulary (`subject.id`, `delegation.depth`, `session.labels`, ...), evaluated through the existing `PdpResolver` seam 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 with `on_error: allow`. No change to APL evaluation semantics. (#68)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ One policy defines three distinct enforcement pipelines, one for each entity.
routes:
# HR lookup: gate on role, scope a downstream token, redact by permission, taint the session.
- tool: get_compensation
policy:
pre_invocation:
- "require(role.hr)"
- "delegate(workday-oauth, target: workday-api, permissions: [read_compensation])"
- "taint(secret, session)"
Expand All @@ -59,7 +59,7 @@ routes:

# Repo search: gate on team, decide with CEL (or Cedar), require the scoped grant.
- tool: search_repos
policy:
pre_invocation:
- "require(team.engineering | team.security)"
- cel:
expr: "(role.engineer && args.visibility == 'internal') || role.security"
Expand All @@ -69,7 +69,7 @@ routes:

# Outbound email: refuse if the session already touched secret data.
- tool: send_email
policy:
pre_invocation:
- "require(perm.email_send)"
- "run(pii-scan)"
- "security.labels contains \"secret\": deny('write-down blocked', 'session_tainted')"
Expand Down
2 changes: 1 addition & 1 deletion builtins/pdps/cedar-direct/tests/visitor_pdp_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ global:
routes:
- tool: get_document
apl:
policy:
pre_invocation:
- cedar:
action: 'Action::"read"'
resource:
Expand Down
10 changes: 5 additions & 5 deletions builtins/pdps/cel/tests/visitor_cel_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ global:
routes:
- tool: get_document
apl:
policy:
pre_invocation:
- cel:
expr: |
subject.id == "alice" && has(role.reader) && role.reader
Expand Down Expand Up @@ -177,7 +177,7 @@ global:
routes:
- tool: get_document
apl:
policy:
pre_invocation:
- cel:
expr: |
subject.id == "alice"
Expand Down Expand Up @@ -208,7 +208,7 @@ global:
routes:
- tool: get_document
apl:
policy:
pre_invocation:
- cel:
expr: |
nonexistent.field == "value"
Expand Down Expand Up @@ -250,7 +250,7 @@ global:
routes:
- tool: get_document
apl:
policy:
pre_invocation:
- cel:
on_deny:
- deny
Expand Down Expand Up @@ -294,7 +294,7 @@ global:
routes:
- tool: get_document
apl:
policy:
pre_invocation:
- cel:
expr: |
meta.entity_name == "get_document"
Expand Down
10 changes: 7 additions & 3 deletions crates/apl-cmf/tests/end_to_end.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ routes:
get_employee:
args:
employee_id: "str"
policy:
pre_invocation:
- "require(authenticated)"
- "delegation.depth > 2: deny"
result:
Expand Down Expand Up @@ -260,7 +260,7 @@ async fn args_attributes_flow_into_bag_for_policy_use() {
let yaml = r#"
routes:
guarded_route:
policy:
pre_invocation:
- "args.include_ssn == true: deny"
"#;
let routes = compile_config(yaml).unwrap().routes;
Expand All @@ -285,7 +285,11 @@ routes:
.await;
match r.decision {
Decision::Deny { rule_source, .. } => {
assert!(rule_source.contains("policy"), "got source {}", rule_source);
assert!(
rule_source.contains("pre_invocation"),
"got source {}",
rule_source
);
},
d => panic!("expected Deny on include_ssn, got {:?}", d),
}
Expand Down
2 changes: 1 addition & 1 deletion crates/apl-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

[package]
name = "apl-core"
description = "APL — Attribute Policy Language core (compiler + evaluator)"
description = "APL — Authorization Policy Language core (compiler + evaluator)"
version.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions crates/apl-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
// SPDX-License-Identifier: Apache-2.0
// Authors: Teryl Taylor
//
// APL core — Attribute Policy Language compiler + evaluator.
// APL core — Authorization Policy Language compiler + evaluator.
//
// This crate is the language nucleus. It does not depend on CPEX directly;
// the bridge from cpex-core extensions into the AttributeBag lives in
// `apl-cmf`, and the `PolicyEvaluator` implementation lives in `apl-cpex`.
//
// See docs/specs/apl-design.md for the full design.

#![doc = "APL — Attribute Policy Language. See docs/specs/apl-design.md."]
#![doc = "APL — Authorization Policy Language. See docs/specs/apl-design.md."]

pub mod attributes;
pub mod evaluator;
Expand Down
Loading
Loading