[Openid-specs-authzen] Comments on the Authzen API GW Profile

Michael Schwartz mike at gluu.org
Thu Jan 23 05:05:00 UTC 2025


Nicola,

Thanks for the quick thoughts.

It's an interesting idea, but I don't see the advantage of adding the
handler. Maybe I'm missing it.  But I really like what you did with uri,
path, route, params and query.

Also proposal 2 doesn't look like an authzen request. And I think (hope)
you meant "not having a collision".

Mike

On Wed, Jan 22, 2025, 6:13 PM Nicola Gallo <nicola.gallo at nitroagility.com>
wrote:

> Hi All,
> Nice to meet you. I do agree with Michael.
>
> In my opinion, since the PDP needs to support multiple languages and
> technologies having a collision I would say it is quite important. Relying
> solely on string conventions can also make things harder to
> understand, document as well as extend.
>
> What about introducing the concept of Handler. By "Handler" I mean that
> the PDP could implement multiple types of handlers (schema-based,
> ApiGateway, etc). Each handler would have its own settings associated in
> the properties field. This approach would create a clear separation of
> concerns between context properties and handler properties.
>
> If no specific handler is provided then the schema-based handler would be
> used as a fallback.
>
> What are your thoughts on this?
>
> Below two proposals:
> * PROPOSAL 1*
> {
> "subject": {
> "type": "user",
> "id": "1234567890"
> },
> "action": {
> "name": "GET"
> },
> "resource": {
> "handler": {
> "type": " apigateway",
> "properties": {
> "uri": "https://example.com/api/v1/pets/123?format=json",
> "scheme": "https",
> "hostname": "example.com",
> "path": "/api/v1/pets/123",
> "route": "/api/v1/pets/{id}",
> "params": {
> "id": "123"
> },
> "query": {
> "format": "json"
> }
> }
> },
> "type": "route",
> "id": "/api/v1/pets/{id}",
> "properties": {
> "ip": "10.1.2.3"
> }
> }
> }
>
> PROPOSAL 2
> {
> "handler": {
> "type": " apigateway",
> "properties": {
> "uri": "https://example.com/api/v1/pets/123?format=json",
> "scheme": "https",
> "hostname": "example.com",
> "path": "/api/v1/pets/123",
> "route": "/api/v1/pets/{id}",
> "params": {
> "id": "123"
> },
> "query": {
> "format": "json"
> }
> }
> },
> "subject": {
> "type": "user",
> "id": "1234567890"
> },
> "action": {
> "name": "GET"
> },
> "resource": {
> "type": "route",
> "id": "/api/v1/pets/{id}",
> "properties": {
> "ip": "10.1.2.3"
> }
> }
> }
>
>
> *Nicola Gallo*
>
> Co-founder / Chief Technology Officer
>
>
> *M:*+39 349 3305248 *P:*+39 0835 170 0059 P: +44 20 3966 5620
>
> *E:*nicola.gallo at nitroagility.com *in:*nicolagallo83
> <https://www.linkedin.com/in/nicolagallo83/>
>
> *W:*nitroagility.com <https://www.nitroagility.com/> *in:*nitroagility
> <https://www.linkedin.com/company/20520302>
>
>
> Nitro Agility Srl - C.F./P.IVA: 01364090777 - PEC: nitroagility at pec.it
>
> SEDE LEGALE: VIA F. PARRI 44, 75100 MATERA (MT), ITALY
> <https://www.google.com/maps/search/VIA+F.+PARRI+44,+75100+MATERA+(MT),+ITALY?entry=gmail&source=g>
>
> SEDE OPERATIVA: VIA LUCANA 259, 75100 MATERA (MT), ITALY
> <https://www.google.com/maps/search/VIA+LUCANA+259,+75100+MATERA+(MT),+ITALY?entry=gmail&source=g>
>
>
> CODICE DESTINATARIO: M5UXCR1
>
> This message may contain confidential and/or proprietary information, and
> is intended only for the person/entity to whom it was originally addressed.
> The content of this message may contain private views and opinions, which
> do not constitute a formal disclosure or commitment unless specifically
> stated.
>
>
>
>
> On Thu, 23 Jan 2025 at 00:37, Michael Schwartz via Openid-specs-authzen <
> openid-specs-authzen at lists.openid.net> wrote:
>
>> Here are some more comments about Omri's "AuthZEN REST API Gateway
>> Profile proposal" we've been so heatedly discussing, described here:
>> https://hackmd.io/MTJPf_vzSmubctNtHis99g
>>
>> I know there is a time challenge around the interop, so I'll try to be
>> brief. BTW, I very likely won't be at the meeting next week, so it would be
>> great if we could have this conversation in the mailing list (or the OIDF
>> Slack...).
>>
>> My first suggestion is that the "type" values should be collision
>> resistant. For example, here are some types and what I might like better
>> (just suggestions...)
>>     - In the Subject, *type "user"*. What about:  "OpenID Authzen API GW
>> Profile 0.1 User", "OpenID::Authzen::API-GW::0.1::User", or
>> https://openid.net/authzen/types/User" (today the best practice for
>> OAuth scopes is to use a unique URI)
>>     - In the Action, *type "GET"*, to "OpenID::Authzen::API-GW::GET" (or
>> one of the other formats above)
>>     - In the Resource,* "type": "route"*, -->
>> "OpenID::Authzen::API-GW::0.1::Route"
>>     - In the Context, the type is missing... maybe Contexts don't have
>> types in Authzen... but I would define it anyway as something like
>> "OpenID::Authzen::API-GW::0.1::Context".
>>
>> While you "could" put information anywhere, I find the organization of
>> the request in the current proposal very confusing. I don't understand why
>> half the data about the request is in the resource (like the params), but
>> the other half is in the Context (like the body). There is no clean
>> explanation for that organization. I would like to suggest that an easy
>> explanation might be to say the request itself is put in the resource --
>> url, headers, body. And all the information added by the API GW -- time of
>> day, network, etc. -- is in the Context.
>>
>> Having the Profile version in the type is also important. API GW plugin
>> developers will write against a certain version, so if a PDP is expecting a
>> different version, things may break.
>>
>> I understand that optionality is the enemy of interoperability. But at
>> this phase, I feel like this current proposal is too opinionated. IMHO, we
>> want to invite the API GW community to come up with more innovative ideas
>> for how to add new subject, action, resource or context types. For example
>> we need different actions and resources for GraphQL. So I'd like to see the
>> proposal be more extensible, which always ends up being good for a spec.
>> Maybe a vendor won't support every API GW Profile feature (e.g. a GW may
>> not support GraphQL). Then we're not saying there is one "right" way...
>> we're giving a way to define different ways, and then when adoption becomes
>> clear, we can promote or demote schemas.
>>
>> - Mike
>>
>>
>> On Fri, Jan 17, 2025 at 1:42 AM Omri Gazitt via Openid-specs-authzen <
>> openid-specs-authzen at lists.openid.net> wrote:
>>
>>> Thank you Michael, Michiel, and Julio for your comments.
>>>
>>> I have been pondering this for the last couple of days and have come to
>>> the conclusion that we are trying to represent two separate scenarios in
>>> the same profile.
>>>
>>> Julio is exactly right on all counts:
>>>
>>>    - the proposal I reviewed in the meeting is meant for
>>>    "medium-grained authz", but I agree that fine-grained authz is a valid
>>>    scenario as well
>>>    - the question you're asking in "medium-grained authz" is "can this
>>>    subject invoke the route represented by { HTTP method, HTTP route }"
>>>    - "route" is meant to be an OpenAPI path template, which is widely
>>>    implemented by many HTTP frameworks / API gateways. These pieces of
>>>    software typically make the matched route available in the request or in
>>>    some developer-accessible context
>>>
>>> In the context of this scenario, I also agree that the JWT is
>>> uninteresting, and what you really as the subject is a claim inside the
>>> JWT.  So I agree with the feedback from George, Julio, and Michael that we
>>> don't want the subject to be of type "JWT".
>>>
>>> Julio, your memory is very good. We considered RFC 9493 as a way to
>>> represent subjects, but realized that we were conflating "format" (e.g.
>>> "JWT", "email", etc) and the "type" ("user", "identity", etc).
>>>
>>> Stepping back, I do think we can represent the two scenarios in a single
>>> profile.
>>>
>>> For the generic fine-grained authz scenario (where every field in the
>>> HTTP request information model is essentially an "attribute" that a policy
>>> can reason over), we want the API gateway to pass along most/all of the
>>> fields in the HTTP request information model, and what is placed in the
>>> required fields isn't all that important. The PDP's policy will likely be
>>> written around the various properties in the information model (subject,
>>> action, resource, context) and not the required fields.
>>>
>>> For the medium-grained authz scenario, what we pick for the required
>>> fields actually matters more, because we are designing an authorization
>>> protocol for HTTP routes.
>>>
>>> The "default" mapping for this scenario feels to me like the following
>>> (in pseudo-code):
>>>
>>> {
>>>   "subject": {
>>>     "type": "user",
>>>     "id": "<decode_jwt(request.headers["authorization"]).sub>"
>>>   },
>>>   "action": {
>>>     "name": "<request.method>"
>>>   },
>>>   "resource": {
>>>     "type": "route",  // or "uri" if "route" is not available
>>>     "id": "<request.route>", // or "uri" if "route" is not available
>>>     "properties": {
>>>       // uri components, path parameters, query (or query parameters if
>>> they get parsed)
>>>     },
>>>     "context": {
>>>       "headers": [],
>>>       "body": ...
>>>     }
>>>   }
>>> }
>>>
>>> For the fine-grained authz scenario, each API request (and its
>>> corresponding filter) essentially has its own contract with the PDP.  What
>>> is most important for this scenario is a predictable way of mapping the
>>> HTTP request information model into the AuthZEN information model. The PDP
>>> policy will lift whatever fields it wants out of the AuthZEN request, and
>>> use those fields in the policy.
>>>
>>> For example, if (as Michael suggests) the PDP really wants the encoded
>>> access token as the subject and will process whatever it wants to extract
>>> out of that, this is easy to do by writing a policy that extracts that
>>> field out of context.headers["Authorization"].
>>>
>>> Therefore, it stands to reason that the mapping sketched out above would
>>> work for the (more constrained) medium-grained authz scenario, and the
>>> (less constrained) fine-grained authz scenario.
>>>
>>> On Wed, Jan 15, 2025 at 7:28 AM Julio Auto De Medeiros (BLOOMBERG/ 731
>>> LEX) via Openid-specs-authzen <openid-specs-authzen at lists.openid.net>
>>> wrote:
>>>
>>>> A couple of thoughts:
>>>>
>>>> 1. On the matter of "/api/v1/pets/{id}", my understanding was that no
>>>> replacement/rewriting was being proposed. Authorizing on that would have
>>>> the meaning of "principal can POST on some pet" (non-pet-ID-specific). The
>>>> pet-specific authorization would only happen later, at the actual API
>>>> provider. In other words, the API gateway would only perform
>>>> "medium-grained" (as Omri put it) authorization, and the API provider would
>>>> do fine-grained authorization. I also understood that it didn't mean that
>>>> API gateways weren't allowed do fine-grained authorization, but more of a
>>>> question of picking the example/use case to include in the profile.
>>>>
>>>> 2. George (IIRC) had a good point on the JWT subject 'type', in that
>>>> previously the authzen spec evoked differences between type and "format".
>>>> Subject types would be things "user", "group", "workload", I reckon. So, in
>>>> that spirit, perhaps the example in the profile would better read:
>>>> {
>>>> "subject": {
>>>> "type": "user",
>>>> "id": {
>>>> "format" : "JWT",
>>>> "jwt": "eyJhb..."
>>>> }
>>>> }
>>>> }
>>>>
>>>> Having that said, I'm of the opinion that the JWT doesn't belong in the
>>>> subject at all, but rather in the context. Conceptually, I think the
>>>> subject identifier is of the format 'email' and its value is '
>>>> john.doe at acmecorp.com', the JWT being sent in the 'context' mostly to
>>>> allow for identity validation. But I understand the concern with giving the
>>>> gateway the "burden" of deserializing the JWT to extract the subject ID.
>>>>
>>>> From: openid-specs-authzen at lists.openid.net At: 01/15/25 04:33:30
>>>> UTC-5:00
>>>> To: openid-specs-authzen at lists.openid.net
>>>> Cc: Michiel.Trimpe at VNG.NL
>>>> Subject: Re: [Openid-specs-authzen] Comments on the Authzen API GW
>>>> Profile
>>>>
>>>> Hi Michael,
>>>>
>>>> Please see my responses in-line.
>>>>
>>>> Cheers, Michiel
>>>> ------------------------------
>>>> *From:* Openid-specs-authzen <
>>>> openid-specs-authzen-bounces at lists.openid.net> on behalf of Michael
>>>> Schwartz via Openid-specs-authzen <
>>>> openid-specs-authzen at lists.openid.net>
>>>> *Sent:* 15 January 2025 02:51
>>>> *To:* AuthZEN Working Group List <openid-specs-authzen at lists.openid.net
>>>> >
>>>> *Cc:* Michael Schwartz <mike at gluu.org>
>>>> *Subject:* [Openid-specs-authzen] Comments on the Authzen API GW
>>>> Profile
>>>>
>>>> Here is the feedback on the discussion about the API GW authzen profile
>>>> that I also posted on OpenID Authzen Slack for the official mailing list
>>>> record:
>>>>
>>>> 1. IMHO, the Resource type should be "HTTP_Request" not "path" -- there
>>>> is always way more to an API proxy decision than just a path. And the path
>>>> itself is not even enough to uniquely identify a resource.  The entitlement
>>>> request is to perform an HTTP Request with a certain method and
>>>> context--not to just access a certain path.
>>>>
>>>> > I spent quite a bit of time pondering the alternatives and given that
>>>> we are looking for common identifier for a resource in the context of HTTP
>>>> REST request; the Uniform Resource Identifier (a.k.a. `uri`) does really
>>>> seem like the optimal fit.
>>>>
>>>> 2. We can define a minimum required schema but allow room for
>>>> extension. I guess what I'm wondering is if we can reduce the scope of this
>>>> profile more.
>>>>
>>>> 3. A URL may include schema, host, port, path, query, and fragment.
>>>> Also, I wonder if the host should allow for policies based on the domain,
>>>> i.e. for google.com domain do this.. for gmail.com domain... do
>>>> something else.
>>>>
>>>> > That can be done using a simple "eq 'google.com' or endsWith '.
>>>> google.com'" expression right? Determining what's colloquially
>>>> understood as "the domain" requires an up-to-date TLD list to disambiguate
>>>> e.g. "smtp.local" hostnames which are perfectly valid as well.
>>>>
>>>> 4. The HTTP request includes url , headers, body .  These are all
>>>> things the developer is sending from Postman in the request. IMHO, Context
>>>> should be for data that is external to the resource, like the time of day,
>>>> which you don't send in the Postman request.
>>>>
>>>> > From my perspective the Subject, Action and Resource is the
>>>> information model of the authorization request. In the Dutch standard we'll
>>>> also recommend implementers to define their AuthZEN information model up to
>>>> the same standard of quality as their domain model. That includes defining
>>>> syntax, semantics, constraints and relations for everything in their domain
>>>> specific AuthZEN information model.
>>>> When viewed from that perspective the "raw JWT" token or "raw X509
>>>> certificate" feel more like an implementation detail. That is why I
>>>> suggested moving them to context.
>>>> For headers I can also make a case that they're properties
>>>> describing/annotating the action that you intend to take (e.g.  Accept
>>>> headers request specific the type of content you wish to GET) so that it
>>>> would make sense to include them in the `action` instead.
>>>>
>>>> 5. It's unclear why the sample shows the route as ".../pets/{id}". The
>>>> request would be for an exact path3.  It may seem trivial, but we don't
>>>> want to define any kind of replacement or regex syntax here.
>>>>
>>>> > Route here refers to the something like "path templates" concept as
>>>> described in e.g. https://swagger.io/specification/#paths-object or
>>>> the router concept from SPA's like you e.g.
>>>> https://www.w3schools.com/react/react_router.asp
>>>> That's what you will generally want to base your policies on if they're
>>>> available.
>>>>
>>>> 6. For the resource id (or the subject id), why not make it a hash of
>>>> the properties? That way it will be unique, and represent the totality of
>>>> the request. It's really quick and easy for the API gateway to generate a
>>>> sha-256 hash.
>>>> > What value would that add over leaving it empty then? Consistent JSON
>>>> hashing is also surprisingly difficult as JSON objects are specified
>>>> to be unordered <https://www.rfc-editor.org/rfc/rfc7159.html#section-1>
>>>>  .
>>>>
>>>> 7. I really don't like the subject sent as "JWT" with the value as the
>>>> id. At a minimum, you should use the fingerprint of the token, and not the
>>>> token itself.  Perhaps it would be better to send client claims in the
>>>> subject properties, like client_id, scopes, and allow for extension for
>>>> customers who have custom access token claims?
>>>> > I agree with this for the same reason I gave on #4.
>>>> For me it still feels logical to define it as the value of 'sub' in the
>>>> JWT token by default and provide the additional JWT parameters in the
>>>> `subject.properties` to disambiguate that further if needed. That same
>>>> pattern can then also be applied to X509/mTLS since they also have a
>>>> Subject field that is generally enough but sometimes needs additional
>>>> properties to be provided.
>>>> I can also think of lots of counter examples though. An API gateway
>>>> that resolves several different authentication patterns to the same
>>>> identity probably wouldn't too happy to be forced to have a subject type
>>>> for each authentication pattern.
>>>>
>>>> 8 .For the resource... what about something like this:
>>>>
>>>> "type": "AuthZen::HTTP_REQUEST",
>>>> "id":
>>>> "31d342599750a22f90a1d6b3d765549231e6b3091530f8f813e2f754e9d62422",
>>>> "properties": {
>>>> "header": {
>>>>                  "Accept": "application/json",
>>>>                  "User-Agent": "AuthzenClient/1.0",
>>>>                  "Host": "www.acme.com",
>>>>                  "Content-Type": "multipart/form-data"
>>>>                   },
>>>> "url": {
>>>>                 "scheme": "https",
>>>> "host": "www",
>>>>                 "domain": "acme.com",
>>>>                 "port": 443,
>>>> "path": "/protected",
>>>>                 "query": "query": {
>>>>                            "param1": "value"
>>>>                           }
>>>>                 "fragment": "TOC"
>>>>                 },
>>>>             "body": {
>>>>    "form1": {
>>>>                            "field1": "value1",
>>>>                            "field2": "value2"
>>>>                          }
>>>> }
>>>> }
>>>>
>>>>
>>>> --------------------------------------
>>>> Michael Schwartz
>>>> Glue
>>>> Founder/CEO
>>>> mike at gluu.org
>>>> https://www.linkedin.com/in/nynymike
>>>>
>>>> ------------------------------
>>>> *CONFIDENTIALITY NOTICE*
>>>> This message may contain confidential or legally privileged information.
>>>> If you are not the intended recipient, please immediately advise the
>>>> sender by reply e-mail that you received this message, and delete this
>>>> e-mail from your system.
>>>> Thank you for your cooperation
>>>>
>>>> --
>>>> Openid-specs-authzen mailing listOpenid-specs-authzen at lists.openid.nethttps://lists.openid.net/mailman/listinfo/openid-specs-authzen
>>>>
>>>>
>>>> --
>>>> Openid-specs-authzen mailing list
>>>> Openid-specs-authzen at lists.openid.net
>>>> https://lists.openid.net/mailman/listinfo/openid-specs-authzen
>>>>
>>> --
>>> Openid-specs-authzen mailing list
>>> Openid-specs-authzen at lists.openid.net
>>> https://lists.openid.net/mailman/listinfo/openid-specs-authzen
>>>
>>
>>
>> ------------------------------
>> *CONFIDENTIALITY NOTICE*
>> This message may contain confidential or legally privileged information.
>> If you are not the intended recipient, please immediately advise the
>> sender by reply e-mail that you received this message, and delete this
>> e-mail from your system.
>> Thank you for your cooperation
>> --
>> Openid-specs-authzen mailing list
>> Openid-specs-authzen at lists.openid.net
>> https://lists.openid.net/mailman/listinfo/openid-specs-authzen
>>
>

-- 





*CONFIDENTIALITY NOTICE*

This message may contain confidential or 
legally privileged information.
If you are not the intended recipient, 
please immediately advise the sender by reply e-mail that you received this 
message, and delete this e-mail from your system.
Thank you for your 
cooperation
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openid.net/pipermail/openid-specs-authzen/attachments/20250122/f107a462/attachment-0001.htm>


More information about the Openid-specs-authzen mailing list