JWT scope claim compression using a bitmap
raphael.medaer.me
raphael.medaer.me
I initally parsed it as "[The] James Webb Telescope ([which is a tele]scope) [team] claim [they can] compress [pictures somehow] using a bitmap".
Is the article really about Java Web Toolkit?
E.g. are large JWT tokens bad because they take longer to send? Then compare durations between both implementations. Or are large JWT tokens bad because they exceed some maximum supported token size? Then compare how many scopes are supported by the standard approach and new approach before hitting limit.
Another thought: the proposed compression scheme requires that each token producer & consumer needs to depend upon a centralised scope list that defines the single source of truth of which scope is associated with which index for all scopes in the ecosystem.
If we assume we've set that up, why not generalise and say the centralised shared scope list is actually a centralised JWT compression standard that defines how to compress and decompress the entire JWT.
This could be implemented as something like https://facebook.github.io/zstd/ running in dictionary compression mode, where a custom compression dictionary is created that is good at compressing the expected distribution of possible JWT values. As long as each JWT producer and consumer is using the same version of the centrally managed compression dictionary the compression & decompression could still occur locally.
In practise in any given JWT ecosystem perhaps there's a subset of scopes that commonly appear together. If common enough that entire subset of common scopes could be encoded in 1 or 0 bits using a custom compression scheme tuned to the frequency of observed JWT scopes, instead of compressing each scope independently.
The justification for that number is that JWTs may or may not need to be included in headers. More headers may or may not be added if Proxies/LBs/etc are involved between communicating machines. Some webservers have default header limits around 8kb, and that's how we get to this number.
Indeed the goal is to limit the size of JWT tokens. I can't tell you if it really improves the performances for now. I already started a spreadsheet to compare the bitmap scope list against the space-separated list. Although I need some real examples and metrics to do a relevant analysis of the impact.
One of the questions you raised is about the scopes commonly used. Should we defined a shared dictionary/registry ? Maybe. I would propose to open an issue on Github to discuss about that. Here it is: https://github.com/rmedaer/rmedaer.github.io/issues/2
If there is more interest in this proposal, I would propose to create a dedicated repository where ~~I~~ we could discuss, compare and challenge it.
Kind regards,
At work we just implemented some M2M auth using JWT[1]. The other party requires a full certificate chain as our identification and RS256 as algorithm, so our "compact" tokens end up around 8k in size.
At least the auth token we get back lasts a couple of minutes.
[1]: https://difi.github.io/felleslosninger/maskinporten_protocol...
Do you have some statistics about that ? For instance, do you know how many scopes are usually requested, on average ?
But if you're interested maybe try to contact the Difi folks running Maskinporten, from my impression there's a high chance there's someone willing to share there.
Maskinporten is being phased in as the primary M2M auth solution for any Norwegian gov't agency, so they're bound to get a lot more "users" (agencies), and hence scopes, going forward.
The format could be a simple json file listing supported dictionary items in order grouped by the key used in the JWT json itself.
Maybe a special claim could point to the url or use "wk" as a special value to direct it to the .well-known path on the issuer?
This is why you can’t have a blacklist of manually expired tokens, one of the most commonly raised issues in JWT.
But, isn't there's a difference between needing to centrally coordinate a common protocol vs central management of state of individual tokens? JWT protocol itself can be regarded as some centralised definition of how different services agree to interoperate with JWT tokens, that all token producers and consumers must implement. It doesn't logically follow that we need a distributed DB that must be queried at runtime when processing tokens to implement JWT support. Similarly for nonstandard variations on JWT protocol that are independent of the state stored in any given token -- all services would need to embed some library that can understand the new (centrally defined) protocol, but there would not need to be any dependency on an external database at runtime.
Even with standard usage of JWT tokens, does there not need to be some degree of agreement and coordination between token producers about what a particular scope string means & agreement between different services in the same ecosystem not to use the same scope string to mean two completely different things?
I agree with you on this point. Actually there are already some "common" scopes, for instance OpenID Connect defines some scopes ("openid", "profile", "email", ...): https://openid.net/specs/openid-connect-core-1_0.html#ScopeC...
However I don't think (to be confirmed) there is a IANA registry for scopes (source: https://www.iana.org/protocols)
But there is one for claims in JWT:
Even though there are gradations in how much you do of one versus the other, and you can ship code as data in the db—you don't have to do that.
If you talk about claim names, they basically aim to be short. For instance, claims defined in RFC7519 Section 4.1 (https://tools.ietf.org/html/rfc7519#section-4.1) are only 3 characters long. As explained in the same section:
"All the names are short because a core goal of JWTs is for the representation to be compact."I have to disagree on this one, being able to specify which resources an OAuth client can tinker with is useful (e.g. only read access to x,y and z repos).
I'm also curious on how often these use cases are of needing many scopes / a god JWT, vs. production usage and keeping a narrow scope for the task at hand. There's also the other option (if in charge of authoring the resource server) to have broader scopes that encompass several others.
This makes sense because permissions are often managed by groups (read write, read only, user, admin, etc...), so employees can request a specific group to access some business application(s). This causes issues when an employee invariably has a hundred groups, adding multiple kilobytes to the token, more than is permitted by HTTP headers.
https://developer.okta.com/docs/guides/validate-id-tokens/ov...
Obvious benefit is that you can still represent a scope that is not included in the ones used to train the dictionary (vs. the proposed approach that breaks down in this case)
I guess it also depends on use case. If you are in domains such as banking with elevated security requirements, then probably you want to hit userinfo endpoint else you can continue with token validation with cached or stored keys.
I tried in this post to not talk about the "transport". Indeed JWTs can be used with HTTP/1.1, HTTP/2 or even SIP. Furthermore HPACK maybe disabled in some cases. Here is what the RFC 7541 (HPACK) says about Authorization header (https://tools.ietf.org/html/rfc7541#section-7.1.3):
"An encoder might also choose not to index values for header fields that are considered to be highly valuable or sensitive to recovery, such as the Cookie or Authorization header fields."But the issue you are trying to mitigate (heavy tokens due to complex scope strategy) is a symptom of a bigger problem that has caused OAuth-using folks to scratch their heads for a long while. (of course, also realtes to non-Oauth JWTs)
Tldr: The new "Cloud native" way of solving for this is to not push your "Permissions" thru the token.
Basically, you limit the scopes included in a token to just a few basic ones (essentially assigning the user to a "Role" - think RBAC)....
... and then you use a modern Authorization approach (e.g. CNCF Open Policy Agent) to implement the detailed/fine grain authorization.
Its hella cool, declarative, distributed, and infinitely scalable...
... and it obviates the whole "heavy JWT" issue before it starts....
Source: This is what I do day in day out in my day job....