[Openid-specs-authzen] Feedback on Authzen Authorization API 1.0 – draft 01
Andrew Clymer
andy at rocksolidknowledge.com
Wed Oct 2 08:26:03 UTC 2024
This is a +1 from me.
## Common actions naming pattern
Common action names follow a can_* naming pattern. Moreover, all
the examples in the repository follow this pattern. Why is it
"can_read" and not "read"? Semantically, it feels weird to have
an action which is "can_read" instead of "read". The client is
requesting whether the user can "read", not whether the user can
"can_read".
Proposition: remove the "can_" from the examples and from the
common actions.
We are the first IdentityServer partner to become a Certified B Corporation™.
Head to our mission statement to read more about the ways we’re using business as a force for good.
Rock Solid Knowledge Ltd is a company registered in England and Wales under number 6811209.
Registered office: C2, Vantage Office Park, Old Gloucester Road, Bristol, BS16 1GW, United Kingdom
Vat registered: GB948 1966 72
________________________________
From: Openid-specs-authzen <openid-specs-authzen-bounces at lists.openid.net> on behalf of Gabriel Corona via Openid-specs-authzen <openid-specs-authzen at lists.openid.net>
Sent: 02 October 2024 07:47
To: openid-specs-authzen at lists.openid.net <openid-specs-authzen at lists.openid.net>
Cc: Gabriel Corona <gabriel.corona at free.fr>
Subject: [Openid-specs-authzen] Feedback on Authzen Authorization API 1.0 – draft 01
Hello,
You will find below my feedback on the Authorization API 1.0 –
draft 01. For context, I did not follow the development of this
specification so this is the point-of-view of a potential naive
implementer
Regards,
## Common actions naming pattern
Common action names follow a can_* naming pattern. Moreover, all
the examples in the repository follow this pattern. Why is it
"can_read" and not "read"? Semantically, it feels weird to have
an action which is "can_read" instead of "read". The client is
requesting whether the user can "read", not whether the user can
"can_read".
Proposition: remove the "can_" from the examples and from the
common actions.
## Request Identification (X-Request-ID) does not seem useful
The HTTP binding introduces a X-Request-ID without any
reason/motivation. There is no explanation about why this would
be beeded. This looks like a implementation detail of some
existing implementations and feels quite out of place in the
specification.
Note: RFC6648 deprecated the usage of the "X-" prefix.
("Deprecates the "X-" convention for newly defined parameters in
application protocols, including new parameters for established
protocols.")
Proposition: remove X-Request-ID.
Proposition 2: explain why this would be needed and remove the
"X-" prefix.
## Example Context
The example context is supposed to be an example and therefore it
appears it is not normative. However, this is not stated
explicitly and the wording ("REQUIRED") seems to implies that it
might be normative. This might need to be clarified.
This section is either too precise (if this is merely an example)
or too ambiguous if this is supposed to be interoperable.
### Reason field is underspecified
If the example context section is not normative, there lacks a
standard/normative way to express a failure reason. If this
section is normative, the reason field is underspecified:
> A Reason Field is a JSON object that has keys and values of
> type string.
The content of the reason field is not specified. The examples
seems to indicate that this should be a mapping from locale to
strings but this is not explained explicitely. This make it
impossible to communicate reason phrases in an standard way.
Moreover an example uses:
"reason_user": {
"en-403": "Insufficient privileges. Contact your administrator",
"es-403": "Privilegios insuficientes. Póngase en contacto con su
administrador"
}
while I would expect,
"reason_user": {
"en": "Insufficient privileges. Contact your administrator",
"es": "Privilegios insuficientes. Póngase en contacto con su
administrador"
}
Proposition: specifiy that this is a mapping from locale to
localized messages and replace "en-403" by "en" in the examples.
### The semantic of the reason "id" is not clear
If the example context section is normative the explanation for
the reason ID should probably be clarified:
> id: REQUIRED. A string value that specifies the reason within
> the scope of a particular response.
The text does not explain where/how this ID could be used.
I believe this is intended to the administrator, maybe changing
the example this way would be clearer:
{
"id": "C076E82F",
"reason_admin": {
"en": "Request failed policy C076E82F"
},
"reason_user": {
"en-403": "Insufficient privileges. Contact your administrator",
"es-403": "Privilegios insuficientes. Póngase en contacto con su
administrador"
}
}
### Usage of the reason object is not specified
Section 6.2.3.1.2 explains that:
> A Reason Object specifies a particular reason.
But it is not explained anywhere explicitly in the draft where it
should be used. The examples suggests that this may be used in
the "context" of the response but this is not stated explicitely
and the specification suggests we could include anything we want
in the context.
Proposition: define a "reason" field in the access evaluation
response.
{
"decision": false,
"reason": {
"id": "C076E82F",
"reason_admin": {
"en": "Request failed policy C076E82F"
},
"reason_user": {
"en": "Insufficient privileges. Contact your administrator",
"es": "Privilegios insuficientes. Póngase en contacto con su
administrador"
}
}
}
### Returning multiple reasons
The draft specified that multiple failure reasons might be
returned:
> in which it presents the reasons that an authorization request
> failed.
>
> * A list of identifiers representing the items (policies,
> graph nodes, tuples)
> that were used in the decision-making process.
>
> * A list of reasons as to why access is permitted or denied.
However, no example is provided for returning multiple reasons.
Should we expect a flat list of reasons of a nested structure
representing failure reasons?
Proposition: define a "reasons" field in the access evaluation
response.
{
"decision": false,
"reasons": [
{
"id": "C076E82F",
"reason_admin": {
"en": "Request failed policy C076E82F"
},
"reason_user": {
"en": "Insufficient privileges. Contact your administrator",
"es": "Privilegios insuficientes. Póngase en contacto con
su administrador"
}
}
]
}
## Lack of compatibility with Subject Identifiers for SET
The draft includes a reference to RFC9493 (Subject Identifiers
for SET) in the references section but this is never used in the
main content. The identifier format in this draft is not
compatible with Subject Identifiers for SET.
In Subject Identifiers for SET, identifiers look like:
{
"format": "email",
"email": "user at example.com"
}
{
"format": "iss_sub",
"iss": "https://issuer.example.com/",
"sub": "145234573"
}
{
"format": "opaque",
"id": "11112222333344445555"
}
{
"format": "did",
"url": "did:example:123456"
}
{
"format": "uri",
"uri": "https://user.example.com/"
}
Authorization API only support plain string id:
{
"type": "user",
"id": "alice at acmecorp.com"
}
The specification should specify how it relates (or does not
relate) to RFC9493 and reference RFC9493 somehow in the main
content.
## The examples are ambiguous
The example are ambiguous, for example, 6.2.4 gives this example:
{
"decision": true,
"context": {
"id": "0",
"reason_admin": {
"en": "Request failed policy C076E82F"
},
"reason_user": {
"en-403": "Insufficient privileges. Contact your administrator",
"es-403": "Privilegios insuficientes. Póngase en contacto con
su administrador"
}
}
}
The decision is true (accepted) bur error messages are included.
Proposition: set the decision value to false (rejected). I guess
this should be,
{
"decision": false, <- changed
"context": {
"id": "0",
"reason_admin": {
"en": "Request failed policy C076E82F"
},
"reason_user": {
"en-403": "Insufficient privileges. Contact your administrator",
"es-403": "Privilegios insuficientes. Póngase en contacto con
su administrador"
}
}
}
## Content negotiation of the error response
The body of the error responses might be suitable for content
negotiation. This way, an implementation might support problem
details (RFC 7807) when the status code is not 200.
## Content negotiation of the returned language
If the application supports 250 languages, should it return a
"reason_user" (or "reason_admin") for each of them? Can the PDP
rely on Accept-Language or another mechanism to choose which
languages it should provide?
## Misc. nitpick
* 7.1.1 is "HTTPS Access Evaluation Request" but 7.1.2 is
"Access Evaluation HTTPS Response". The same naming pattern
should be used.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openid.net/pipermail/openid-specs-authzen/attachments/20241002/4c603aa6/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image407751.png
Type: image/png
Size: 67887 bytes
Desc: image407751.png
URL: <http://lists.openid.net/pipermail/openid-specs-authzen/attachments/20241002/4c603aa6/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image497184.png
Type: image/png
Size: 31014 bytes
Desc: image497184.png
URL: <http://lists.openid.net/pipermail/openid-specs-authzen/attachments/20241002/4c603aa6/attachment-0003.png>
More information about the Openid-specs-authzen
mailing list