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

Nicola Gallo nicola.gallo at nitroagility.com
Thu Jan 23 18:58:26 UTC 2025


Hi All,

I completely agree with @alex.babeanu at indykite.com’s comments. This is a
great example and a helpful recommendation article. However, I think I
wouldn’t feel as comfortable if it were turned into a formal standard or
specification.

Cheers,

*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

SEDE OPERATIVA: VIA LUCANA 259, 75100 MATERA (MT), ITALY

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 19:02, Michael Schwartz via Openid-specs-authzen <
openid-specs-authzen at lists.openid.net> wrote:

> A few follow-up thoughts... I was just using Cedar syntax as an example
> for expediency, but I mentioned using URIs, URNs, ASNs, etc. are other ways
> to address the issue. But what I think is important is that we prefix the
> following: OpenID, Authzen, and API GW Profile--specifying the version.
> Not just "http" or "graphql", which I don't think is actually
> collision resistant.
>
> Just as an example in another domain, in the DID space, anyone can define
> a DID method. Certain DID methods started to get traction, and
> eventually will become "standardized". I think this is an interesting
> approach, because we can stay open minded here that we might not know best.
> So at the Interop we are showing how to profile Authzen, and the quick
> profile we are using is just an example of one possible profile.
>
> - Mike
>
>
> On Thu, Jan 23, 2025 at 9:51 AM Alex Babeanu <alex.babeanu at indykite.com>
> wrote:
>
>> Hi all,
>>
>> Finally caught up with all this... Was the consensus that this GTWY
>> profile was going to actually be helpful in bringing Gtwy vendors on board??
>>  It does really seem VERY opinionated to me: it's basically telling them
>> HOW to build their product. It seems to me that defining a good AuthZEN
>> protocol that includes the protocol-side things that would be required for
>> their integration (Omri's the JWT Profile draft for example) should be
>> sufficient. This here feels to me like, saying: "here's the OAuth spec, and
>> oh, btw, here's how you MUST implement it". Not sure I like that myself...
>> The AuthZEN protocol spec should be sufficient for all vendors to adopt in
>> the way they see fit. I'm sure they have smart people that can figure it
>> out, especially if the protocol itself makes it obvious what the
>> expectation is...
>>
>> This could therefore be a recommendations article rather than a formal
>> standard/spec. My $0.02...
>>
>> And sry if the decision was already made to go ahead in this direction, I
>> may have missed it - been too busy.
>>
>> Regards,
>>
>> ./\.
>>
>> On Thu, Jan 23, 2025 at 7:39 AM Michiel Trimpe via Openid-specs-authzen <
>> openid-specs-authzen at lists.openid.net> wrote:
>>
>>> *Collision Resistance*
>>> I agree that it's probably wise to include guidance towards ensuring
>>> collision resistance for implementers in the base AuthZEN spec. I came
>>> across a similar section in the OAuth RAR specification
>>> <https://datatracker.ietf.org/doc/html/rfc9396#name-authorization-details-types> recently
>>> which does a fairly good job at explaining this IMO (although I'm not a fan
>>> of URI's as namespaces.)
>>>
>>> After considering the GraphQL case I do agree it might be wise to give
>>> this profile  a top-level namespace like 'http' instead. So then you'd get
>>> something like {"type": "http:route"} and {"type": "http:uri"} and
>>> {"action": "http:get"}
>>> That leaves API gateways free to model GraphQL calls as plain HTTP
>>> request using this profile or to use a (yet to be defined) GraphQL profile
>>> with action types like "graphql:query".
>>>
>>> *What goes where*
>>> Looking at terminology alone it seems logical for me to put:
>>> - information from/about the Uniform *Resource* Identifier in the `
>>> *resource*` section
>>> - the HTTP *method/verb* in the `*action*`section and
>>> - the *subject* as extracted from e.g. the Authorization header in the `
>>> *subject*` section
>>>
>>> I'd personally say 'body' belongs in the `action` section as well since
>>> it's *what* your are PUTting or POSTing.
>>>
>>> Then you get a sentence like "As `mtrimpe`(subject) I `POST
>>> {"json":"string"}`(action) to `http://example.com/json-store`(resource)
>>> <http://example.com/json-store(resource)>."
>>>
>>> Only the headers are a tough one. You can see it as metadata about the
>>> action but we're also parsing the Authorization header to populate the
>>> subject as well. Given that headers are now used for so many purposes I'd
>>> argue that makes most sense to put it in the `context` section.
>>>
>>> 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:* 23 January 2025 00:37
>>> *To:* AuthZEN Working Group List <openid-specs-authzen at lists.openid.net>
>>> *Cc:* Michael Schwartz <mike at gluu.org>
>>> *Subject:* Re: [Openid-specs-authzen] Comments on the Authzen API GW
>>> Profile
>>>
>>> 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
>>>
>>
>>
>> --
>>
>>
>> Alex Babeanu
>> Lead Product Manager, Access Management
>>
>>
>>
>> t. +1 604 728 8130
>> e. alex.babeanu at indykite.com
>> w. www.indykite.com
>>
>
>
> ------------------------------
> *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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openid.net/pipermail/openid-specs-authzen/attachments/20250123/06d90ad9/attachment-0001.htm>


More information about the Openid-specs-authzen mailing list