refactor(apl)!: rename authz/authn config keys #111
Conversation
Rename the CPEX/APL config keys for clarity (breaking change): identity -> authentication (global, 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 parse equivalently whether written nested under an `authorization:` block or flat on the section. The field-pipeline keys `args:` / `result:` are intentionally left unchanged: they stay aligned with the `args.*` / `result.*` attribute namespaces that predicates and interpolation read, so renaming only the config block would have introduced a new inconsistency. Legacy `policy:` / `post_policy:` / `identity:` keys are rejected loudly at parse/load time rather than silently ignored, so a dropped authorization or authentication block can never fail open. Internal APL IR (`CompiledRoute`, `Phase`) is unchanged. Refs #105 Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
Update every config example and field reference to the renamed keys (authentication, authorization.pre_invocation / post_invocation), show both the nested and flat authorization forms, and add a BREAKING migration entry to the changelog. The `args:` / `result:` field-pipeline keys and the `args.*` / `result.*` attribute vocabulary are unchanged. Refs #105 Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
Replace the legacy "Attribute Policy Language" expansion with "Authorization Policy Language" across code doc-comments, the crate description, and docs, matching the README and 0.1.x overview. Refs #105 Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
|
Reviewed the rename mechanics end-to-end (parser, config loader, visitor, FFI/Go, docs). The core is solid and the fail-closed posture is real — a couple of things below, one of which I'd fix before merge. What checks out
Would fix before mergeFail-open: a legacy key nested inside the new routes:
- tool: get_employee
authorization:
policy: # <- legacy key, nested under the new wrapper
- "require(authenticated)"deserializes with This is a plausible partial-migration mistake: reading the migration entry Fix: add MinorBoth forms on the same section silently merge (double-execution footgun). Naming (non-blocking)Overall I'm fine with the direction — |
…thz forms Addresses review feedback on #111: 1. Fail-open (blocker): a legacy key nested under the new wrapper (`authorization: { policy: [...] }`) was silently dropped — both phase lists parsed empty with no error, loading a route with no authorization enforced. `AuthorizationYaml` had no unknown-field guard, and the top-level `reject_legacy_keys` can't see keys consumed inside the `authorization` value. Add `#[serde(deny_unknown_fields)]` to `AuthorizationYaml` (safe — no `flatten`); it turns nested legacy keys and typos (`pre_invocaton:`) into load errors. 2. Double-execution footgun: declaring the same phase both nested under `authorization:` and flat on one section concatenated the entries, running effects (`run(...)`, `delegate(...)`) twice. Reject the both-forms-same-section case with a clear error. Cross-scope stacking (e.g. global nested + route flat) is unaffected. 3. Docs: note that `authorization` names *when* the phase runs and can carry obligations/effects (taint, delegate, plugin), not just a pure allow/deny gate. Adds regression tests for the nested-legacy-key, typo, and conflicting-forms cases. Refs #105 Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
|
All three addressed in ece499a:
Suite, clippy, and rustfmt green. |
Summary
Renames the CPEX/APL authorization/authentication config keys for clarity. Breaking change (pre-1.0): old key names no longer parse.
identity:authentication:(global, route, policy-group)policy:authorization.pre_invocation:(or flatpre_invocation:)post_policy:authorization.post_invocation:(or flatpost_invocation:)The two authorization phases parse equivalently whether nested under an
authorization:block or written flat on the section.Closes #105.
Deliberately not renamed
The field-pipeline keys
args:/result:stay as-is. They're aligned with theargs.*/result.*attribute namespaces that predicates and interpolation read (require(args.include_ssn),${args.repo_name},args.ssn | redact) — renaming only the config block would have introduced a new inconsistency. (The issue originally proposedinputs/outputs; we tried it and rolled it back for exactly this reason.)Internal APL IR (
CompiledRoute,Phase) and the runtime attribute namespaces are unchanged.Fail-closed by design
Legacy
policy:/post_policy:/identity:keys are rejected loudly at parse/load time (in both the apl-core parser and cpex-core config loader) rather than silently ignored — a dropped authorization or authentication block would otherwise fail open.Example
Also
Testing
cargo fmt --check,cargo clippy --workspace --all-targets, and fullcargo test --workspace(all 55 suites) pass.praxis-demos/demos/cpexconfigs were migrated to the new surface (separate PR in that repo) and verified to load throughinstall_builtins+load_config_yaml.