Resource hierarchy: convey ancestors in resource.properties and define subtree coverage
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- json, typescript
- Domain
- api, authorization
Research direction
Start with the Resource Properties and Metadata sections referenced in the issue, then review the related issues #597, #755, and erratum #601 to understand the open capability naming questions. The proposal is complete enough to compare a profile with a normative section and assess the ancestors versus parent options, but the issue leaves these decisions open. Done means agreeing on the hierarchy representation, subtree coverage semantics, depth limit, and capability signaling.
Written by the indexing model from the issue text.
Description
Problem
Many resource servers expose resources as a tree: for example service > host > database > table, or
organization > project > bucket > object. An access grant is often given on a node and applies to everything
below it ("alice may read host prod" covers every database of prod).
The Authorization API has no notion of containment. A Resource is a type, an id that is "scoped to the
type", and free properties. In a tree, an id is unique only below its parent (two hosts can each have a
database named analytics), so type and id alone cannot name a node, and a PDP that does not own the tree
cannot tell which grant applies.
Related issues and text:
- #11 asked about complex or nested asset attributes in an early draft and was closed as no longer
applicable. It is not about containment. - The transitivity recommendation for searches (§ Search) illustrates group membership only. #269 discussed
a folder-contains-document example, and the text of PR #292 as first merged used one, but that example is
not in the current text. - #329 (closed, won't fix) keeps
typeandidrequired in evaluations. A hierarchy convention has to keep
them.
What we do today (outside the specification)
The PEP sends the chain of ancestors in resource.properties:
{
"subject": { "type": "user", "id": "alice" },
"action": { "name": "query.run.read" },
"resource": {
"type": "database",
"id": "analytics",
"properties": {
"ancestors": [ { "type": "service", "id": "db" }, { "type": "host", "id": "prod" } ]
}
}
}
ancestors is ordered from the root to the parent of the resource. Each entry is a Resource reference with
type and id. A grant on the resource or on any entry of the chain applies.
The specification says that receivers MUST ignore unknown fields in request and response bodies. It does not
say it for unknown keys inside properties, but the certification scenarios accept additional properties
(c-2-2-8). A PDP that does not know ancestors therefore ignores it, and decides on the resource alone.
Proposal
A small profile, "Resource Hierarchy", that only fixes what is now left open:
- The name and the shape of the property:
resource.properties.ancestors, an array of{type, id}ordered
from the root to the parent, with the rules above. - The meaning for a PDP that supports the profile: a grant (or a policy) that applies to an ancestor applies
to the resource. The profile says nothing about how the PDP stores its policies. - A depth limit, to keep requests bounded (we use 4 levels below the service).
- A capability URN,
urn:openid:authzen:capability:<name>by the convention of the existing profiles,
announced in the PDP metadata. Profiles define a URN when they add response vocabulary that a PEP must
understand and enforce (token issuance profile, § Discovery). Profiles that add only advisory request
context keys or registered action names define none (token exchange and authorization claims).ancestors
is a request key, but it is not advisory: a PDP that ignores it misses a grant on an ancestor, and, because
ids are scoped below their parent, it can apply a grant ondatabase:analyticsof one host to the database
of the same name on another host. A PEP therefore needs to know whether the PDP honours it.
Example
The PDP holds one grant: alice may query.run.read on host:prod of the service db.
A question on a database of prod. The chain names the host, so the grant on the host applies:
{
"subject": { "type": "user", "id": "alice" },
"action": { "name": "query.run.read" },
"resource": {
"type": "database",
"id": "analytics",
"properties": {
"ancestors": [ { "type": "service", "id": "db" }, { "type": "host", "id": "prod" } ]
}
}
}
{ "decision": true }
The same database name on another host. The ids are scoped below their parent, so the chain tells the two
apart and the grant does not apply:
{
"subject": { "type": "user", "id": "alice" },
"action": { "name": "query.run.read" },
"resource": {
"type": "database",
"id": "analytics",
"properties": {
"ancestors": [ { "type": "service", "id": "db" }, { "type": "host", "id": "staging" } ]
}
}
}
{ "decision": false }
A question on the host itself, which has the service as its only ancestor. The grant names this node, so it
applies. A question on the service has no ancestors and the grant does not apply, because a grant covers a
node and what is below it, never what is above:
{
"subject": { "type": "user", "id": "alice" },
"action": { "name": "query.run.read" },
"resource": {
"type": "host",
"id": "prod",
"properties": { "ancestors": [ { "type": "service", "id": "db" } ] }
}
}
{ "decision": true }
A PDP that supports the profile announces the capability in its metadata (the URN name is only an
illustration):
{
"policy_decision_point": "https://pdp.example.com",
"access_evaluation_endpoint": "https://pdp.example.com/access/v1/evaluation",
"capabilities": [ "urn:openid:authzen:capability:resource-hierarchy" ]
}
A PEP that finds no such capability knows that a grant on an ancestor may not be honoured, and can fall back
to evaluating each node, or refuse to rely on subtree grants.
On the registry: the core defines it (Specification Required) and registers no URN. Profiles define URNs, and
whether these are registered is open in #597 and #755. The metadata member is capabilities (§ Metadata); the
text also says supported_capabilities, see the erratum #601.
Questions
- Is a profile the right place for this, or do you prefer a short normative section next to "Resource
Properties"? ancestors(the whole chain) orparent(one level, recursive)? The chain avoids a lookup in the PDP; a
recursiveparentis shorter for deep trees.- Should the ids of the chain be required to be scoped (unique below their own parent), as in the example?
- Dominant language
- TypeScript
- Stars
- 170
- Forks
- 46
- Avg merge
- 18h 5m
- Merged PRs (30d)
- 43
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openid/authzen
-
Certification Scenario §7.2.2, §7.3.2 and §7.4.2: identical results, or identical fixture results?Possibly taken @alexolivier claimed this 4 days ago. Openauthorization-api certification
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Search interop runner compares results as JSON strings, so member order decides PASS/FAILMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
openid/authzen#693 · 3 comments ·
Maintainers usually reply within 1 day
-
certification
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
openid/authzen#640 · 1 comment ·
Maintainers usually reply within 1 day
-
access-requests
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
openid/authzen#578 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 35/100
Maintainers usually reply within 1 day
Similar issues
-
area: cli bug flake ready-for-agent
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
gazetta-studio/gazetta-studio#1772 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
microsoft/playwright#43875 · 1 comment ·
Maintainers usually reply within 1 day
-
documentation good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
feature
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
calagopus/panel#285 · 1 comment ·
Maintainers usually reply within 1 day