Quick Start#

This walks through standing up CPEX as an enforcement point and running the scenario: the get_employee route that authorizes by role and redacts a field by permission.

1. Add CPEX#

cargo add cpex --features builtins

The builtins feature compiles in the bundled plugins and PDPs (JWT identity, OAuth delegation, PII scanner, audit logger, Cedar, CEL). For a smaller build, opt into a granular subset: jwt, cedar, pii, and so on (see Builtins).

2. Register the runtime#

Create a PluginManager, register the enabled builtin factories, and install the APL config visitor in one call:

use std::sync::Arc;
use cpex::PluginManager;

let mgr = Arc::new(PluginManager::default());
cpex::install_builtins(&mgr);

After this, the manager knows every builtin kind your features enabled, and APL routes can reference them.

3. Write the policy#

APL configs loaded into the manager use the map-keyed routes: form, keyed by route name. This route authorizes by role and redacts on the wire by permission:

routes:
  get_employee:
    args:
      employee_id: "str"
    policy:
      - "require(authenticated)"
      - "require(role.hr)"
    result:
      ssn: "str | redact(!perm.view_ssn)"
      salary: "int | redact(!role.hr)"
      employee_id: "str | mask(4)"

The require(authenticated) and require(role.hr) predicates read attributes resolved from the caller’s verified token. How those attributes get populated is covered in Identity; for now, an identity plugin (for example identity/jwt) resolves the subject and roles before policy runs.

4. Run it#

Load the config into the manager and dispatch operations through it. The four phases run automatically: args validates employee_id, policy authorizes, result redacts. See crates/cpex-core/examples for runnable end-to-end programs that load a config and invoke a route.

The outcome matches the scenario:

  • An HR caller with view_ssn receives the full record.
  • An HR caller without view_ssn receives the record with ssn redacted before it leaves CPEX.
  • A non-HR caller is denied at require(role.hr); the call never reaches the backend.

Next#

  • APL: the full language: predicates, effects, field pipelines, phases.
  • Identity: resolving callers into the attributes policy reads.
  • PDP Integration: delegating decisions to Cedar, CEL, or an external engine.
  • Delegation: minting scoped downstream credentials.