Configuration#

A CPEX config is a single document that declares the plugins and PDP resolvers available, the global settings, and the APL routes. The runtime loads it and the APL visitor wires routes to hooks.

Shape#

plugins:        # the plugins available to policy, by kind
  - name: ...
    kind: ...
    hooks: [...]
    capabilities: [...]
    config: { ... }

global:         # cross-cutting resolvers and stores
  pdp:
    - kind: ...
  session_store:
    kind: ...

routes:         # APL policy, keyed by operation
  <route>:
    args: { ... }
    policy: [ ... ]
    result: { ... }
    post_policy: [ ... ]

Plugins#

Each plugin entry declares how it is identified, where it runs, and what it may see:

FieldMeaning
nameInstance name, referenced from APL (plugin(name), delegate(name, ...)).
kindWhich plugin implementation (for example identity/jwt, audit/logger).
hooksThe hook points it registers on.
modeExecution mode (see Plugins & Pipeline).
priorityOrder within a hook; lower runs first.
on_errorfail, ignore, or disable.
capabilitiesDeclared context access (see Extensions & Capability-Gating).
configPlugin-specific settings.
plugins:
  - name: jwt-user
    kind: identity/jwt
    hooks: [identity.resolve]
    config:
      role: user
      header: X-User-Token
      trusted_issuers:
        - issuer: "https://idp.example.com/realms/agents"
          audiences: ["cpex-gateway"]
          decoding_key:
            kind: jwks_url
            url: "https://idp.example.com/realms/agents/protocol/openid-connect/certs"

  - name: audit-log
    kind: audit/logger
    hooks: [cmf.tool_pre_invoke]
    priority: 90
    capabilities: [read_subject, read_client, read_delegation]

Global#

global.pdp registers PDP resolvers; global.session_store selects where taint labels live (absent it, the in-process memory store is used).

global:
  pdp:
    - kind: cedar-direct
      policy_text: |
        permit(principal, action == Action::"read", resource is Repo)
        when { principal.roles.contains("security") };
  session_store:
    kind: valkey
    endpoint: localhost:6379

Routes#

Routes carry the APL policy. The map-keyed form (keyed by route name) is the canonical form for configs loaded into the runtime:

routes:
  get_compensation:
    policy:
      - "require(role.hr)"
      - "delegate(workday-oauth, target: workday-api, audience: workday-api, permissions: [read_compensation])"
      - "taint(secret, session)"
      - "plugin(audit-log)"
    result:
      ssn: "str | redact(!perm.view_ssn)"

Deployment integrations that wrap CPEX (a gateway or sidecar) often express routes as a list of - tool: entries instead; that form carries the same policy/args/result blocks. See Deployment for that variant, and APL for the policy syntax itself.

Route-level overrides can adjust a plugin’s capabilities or config for a specific operation, so a scanner can be granted read_labels on one sensitive route without widening its access everywhere.