Skip to content

ARAP: the base Task Handle surface and extensibility #665

Open

Description

@mcguinness

Four smaller questions about what belongs in the base profile. None blocks a deployment; together they decide how much of the surface a conforming implementation must carry.

Question Recommendation Status
1 progress and links.review sit on the base Task Handle Move them to registered extension members #751, open
2 Composition with obligations is undefined Point at Obligations Core and state two consequences #753, blocked on #697
3 The extension-point list is closed Replace the closure with the recursive rule #753, blocked on #697
4 Two optional capabilities are proposed Decline both for this draft Settled, no text

Problem

1. The Task Handle exposes workflow-engine surface. progress, including awaiting, which carries approver identifiers, and links.review, an approver action URL, are workflow state. The Introduction places workflow engines, approver-facing inboxes, and enumeration APIs out of scope. links.ticket and display are requester-facing and are not in question.

2. Composition with obligations is undefined. A denied Decision can carry both context.access_request and obligations; a re-evaluation permit can carry obligations. The profile defines neither ordering nor precedence, and its own Decision Context Members table says so rather than guessing.

3. The extension-point list is closed. Members may appear only at the listed locations, and no other object may be extended without a revision of the specification. The AuthZEN extensibility model proposes instead that any named object carries registered, namespaced members, with the registered name as the signal that the extension applies.

4. Two optional capabilities are proposed and undecided. Recovery of a lost Task Handle by a different principal, and an advertised maximum pending duration.

Recommendations

1. Move progress and links.review to registered extension members

They are useful and they are not needed for interoperability, and moving them makes the scope statement true rather than aspirational. A deployment that wants them registers nothing new; the members keep their names and semantics.

#751 does this. One judgment call in it: links.review was already registered at task.links, but progress had nowhere to go, because task was not an extension point and the registry requires each entry to name one, so the PR adds task as a single named location. A companion profile would also have worked, since the existing text allows "a profile that explicitly redefines" an object. Doing it in the base avoids a separate document for two members the base already defines.

The PR also closes something the move opened. The forward-compatibility rule lets an implementation pass unrecognized members through when echoing wire content, so a PEP that does not implement review could forward task.links whole to an end client, which is the disclosure the existing MUST NOT prevents. A relation name does not establish who a URL is for, so unrecognized relations are now covered too.

2. Point at Obligations Core for composition with obligations

#697 settles the strength model this issue was waiting on, and writes our half from the other side in authzen-obligations-core-1_0.md:

A DENY MAY carry both access_request and obligations in its context. The PEP executes the obligations as required for a DENY. Independently, it MAY pursue the access request. Neither member changes the meaning of the other, and the decision remains a DENY. A later re-evaluation that follows an approval is a new evaluation.

Our job shrinks to a pointer plus the two consequences a reader here will look for: there is no ordering between executing a denial's obligations and pursuing the Access Request, and a re-evaluation is a new evaluation whose obligations are subject to the same fail-closed rule as any other permit. The rules stay in the defining document, and #753 carries the pointer.

3. Adopt the recursive extension rule

The model replaces the fixed list, and names our objects among those it covers:

Extensibility is a recursive rule, not a fixed list. Any named object in the protocol MAY carry registered, namespaced extension members. […] objects defined by profiles, such as the task and result objects of {{ARAP}}, callback documents, and catalog documents.

#753 removes the closure, keeps the enumeration as a reader's inventory, and leaves enumerated-value extensibility alone, since the recursive rule is about members and not values. The recursive rule also makes the task row #751 adds redundant rather than wrong, which is why #751 did not have to wait.

4. Decline both optional capabilities for this draft

Cross-principal recovery of a lost Task Handle is better served by the authorized-task-caller rules already in the profile, and an advertised maximum pending duration duplicates task.expires_at without adding a decision the PEP can act on. Either can return as a companion profile if a deployment needs it. No text, so nothing to open.

Dependencies

#753 is stacked on #751 and blocked on #697, because it takes a normative dependency on a document that exists only in that PR.

Also recorded here

This profile is entirely advisory, and the model says so for us. It states that twice, and it is true by design: the Decision Context Members table already asserts that no member widens a denial or narrows a permit for a non-implementer. #753 asserts it here rather than leaving another document to assert it on our behalf, because it has a concrete consequence. An Extension Identifier is registered only by an extension defining a mandatory-to-understand member, so we register none and a PEP never lists us in supported_mandatory_extensions. A member a PEP could not safely ignore would change that, which is what the single-use approval in #737 would be.

#697 breaks a reference here. It deletes authzen-obligations-profile-1_0.md and drops it from the publish matrix, so our {{OBLIGATIONS}} target stops resolving on merge. #753 repoints all three citations at Obligations Core; raised on #697 as well.

The registry authority question is separate. The model establishes an AuthZEN JSON Members registry covering the same ground as our member-names registry and requests it from IANA as core does, while this profile files under OpenID Foundation Registry Considerations and states it has no IANA actions. Which is correct is #597's question, unresolved, with a live argument that IANA will not create registries for an OpenID Foundation document at all. Filed separately as #755.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions