|
1 | 1 | { |
2 | 2 | "magic": "E!vIA5L86J2I", |
3 | | - "timestamp": "2026-07-12T00:28:32.529370+00:00", |
| 3 | + "timestamp": "2026-07-14T00:25:02.411424+00:00", |
4 | 4 | "repo": "oauth-wg/draft-ietf-oauth-attestation-based-client-auth", |
5 | 5 | "labels": [ |
6 | 6 | { |
|
5163 | 5163 | "labels": [], |
5164 | 5164 | "body": "<details><summary>Context</summary>\n<p>\nThe WIMSE working group & SPIFFE defines a [Workload Identity Token ](https://datatracker.ietf.org/doc/draft-ietf-wimse-workload-creds/02/) and [WIT-SVID](https://spiffe.io/docs/latest/spiffe-specs/wit-svid/). A key-bound JWT that workloads can use to authenticate themselves to third parties. It is frequently issued to the workload alongside a new key, for instance every hour.\n\nThe adopted [SPIFFE OAuth Client Authentication](https://datatracker.ietf.org/doc/draft-ietf-oauth-spiffe-client-auth/02/) document profiles attestation-based client auth to allow using the key-bound WIT as a mean of client authentication towards an Authorization Server.\n</p>\n</details> \n\n[Workload Identity Tokens](https://datatracker.ietf.org/doc/draft-ietf-wimse-workload-creds/02/) do not necessarily carry the client ID in their subject and a WIT may be used to represent multiple clients at multiple authorization servers.\n\nWorkload Identifiers (which go into the `sub` claim of the WIT) are defined as:\n> A URI-based identifier assigned to a workload. A Workload Identifier MAY refer to a logical workload consisting of multiple instances, or to a specific workload instance, depending on the policy of the trust domain. [..]\n\nsee https://datatracker.ietf.org/doc/draft-ietf-wimse-identifier/03/.\n\nI would like to open discussions if the following sentence \n> The sub (subject) claim MUST specify client_id value of the OAuth Client.\n\ncan be changed to something along the lines of \"The sub (subject) claim MUST specify client_id value of the OAuth Client or adequate mapping MUST exist at the Authorization Server\"", |
5165 | 5165 | "createdAt": "2026-07-10T10:13:23Z", |
5166 | | - "updatedAt": "2026-07-10T10:20:10Z", |
| 5166 | + "updatedAt": "2026-07-13T11:06:40Z", |
5167 | 5167 | "closedAt": null, |
5168 | | - "comments": [] |
| 5168 | + "comments": [ |
| 5169 | + { |
| 5170 | + "author": "tplooker", |
| 5171 | + "authorAssociation": "COLLABORATOR", |
| 5172 | + "body": "Hi @arndt-s thanks for filling the issue, in general it makes sense that generic Workload Identity Tokens may not convey client ID's given their applications outside of OAuth, however I'm struggling to understand how they can then operate within the context of OAuth without the AS knowing what client deployment a workload is associated to. The constraint we've imposed in our draft around requiring the client ID is really only there to respect a fundamental design decision of OAuth, which is that generally the AS needs to know what client deployment a requestor is associated too and the client ID is how that is accomplished.\n\nThat said I wonder if the language change you have requested is necessary, given OAuth does not prescribe a specific format for a client ID, could a workload identifier not actually infact be a client_id?\n\n", |
| 5173 | + "createdAt": "2026-07-13T08:08:19Z", |
| 5174 | + "updatedAt": "2026-07-13T08:08:19Z" |
| 5175 | + }, |
| 5176 | + { |
| 5177 | + "author": "arndt-s", |
| 5178 | + "authorAssociation": "MEMBER", |
| 5179 | + "body": "Hi @tplooker ,\n\nAgreed that the AS needs to be able to associated client deployments to the workload. That's what I'm aiming for with _\"or adequate mapping MUST exist at the Authorization Server\"_. And you are correct, the workload identifier can be the client_id, however, that 1-1 binding only works if workload topology is aligned with the OAuth topology which is almost never the case.\n\nFor instance, 2 Kubernetes cluster behind a load balancer. The same workload runs on both, but they get different SPIFFE-IDs.\n`spiffe://example.com/cluster-a/my-workload`\n`spiffe://example.com/cluster-b/my-workload`\nboth act as the same client ID on the authorization server, have the same consent screen/cookie, share state and so on.\n\nAnother example where sub==client_id does not work is CIMD where the client_id is required to be `https` scheme-ed.", |
| 5180 | + "createdAt": "2026-07-13T11:06:40Z", |
| 5181 | + "updatedAt": "2026-07-13T11:06:40Z" |
| 5182 | + } |
| 5183 | + ] |
5169 | 5184 | }, |
5170 | 5185 | { |
5171 | 5186 | "number": 211, |
|
5179 | 5194 | "labels": [], |
5180 | 5195 | "body": "<details><summary>Context</summary>\n<p>\nThe WIMSE working group & SPIFFE defines a [Workload Identity Token ](https://datatracker.ietf.org/doc/draft-ietf-wimse-workload-creds/02/) and [WIT-SVID](https://spiffe.io/docs/latest/spiffe-specs/wit-svid/). A key-bound JWT that workloads can use to authenticate themselves to third parties. It is frequently issued to the workload alongside a new key, for instance every hour.\n\nThe adopted [SPIFFE OAuth Client Authentication](https://datatracker.ietf.org/doc/draft-ietf-oauth-spiffe-client-auth/02/) document profiles attestation-based client auth to allow using the key-bound WIT as a mean of client authentication towards an Authorization Server.\n</p>\n</details> \n\n[Workload Identity Tokens](https://datatracker.ietf.org/doc/draft-ietf-wimse-workload-creds/02/) are rotated frequently alongside their keys. Requiring refresh tokens to be bound to the same key that is used to authenticate the client limits those to the age of that key. This either makes the refresh tokens short-lived and introduces user experience downsides (re-auth at every key rotation) or requires additional work to rotate refresh tokens to new keys creating burst of rotation traffic at the authorization server at every key rotation.\n\nI would like to open discussions if the \"Refresh token binding\" section could be changed to\n- MUST bind to the client (already covered by general OAuth confidential client)\n- SHOULD be bound to the client instance (if multiple client instances share the same security boundary this may be intentional). E.g. ephemeral workload authenticates the user and retires. A new instance (& new key) comes up and wants to pick up the prior established session.\n- MAY be bound to the same key. + wording that this binds the refresh token lifetime to the lifetime of the key itself.\n\nA new section in the security considerations can highlight the impact of the various options and that stronger binding (to the instance or the key) mitigates token theft across instances.", |
5181 | 5196 | "createdAt": "2026-07-10T10:30:13Z", |
5182 | | - "updatedAt": "2026-07-10T10:30:13Z", |
| 5197 | + "updatedAt": "2026-07-13T15:48:29Z", |
5183 | 5198 | "closedAt": null, |
5184 | | - "comments": [] |
| 5199 | + "comments": [ |
| 5200 | + { |
| 5201 | + "author": "EthanHeilman", |
| 5202 | + "authorAssociation": "NONE", |
| 5203 | + "body": "> This either makes the refresh tokens short-lived and introduces user experience downsides (re-auth at every key rotation) or requires additional work to rotate refresh tokens to new keys creating burst of rotation traffic at the authorization server at every key rotation.\n\nOne of the main selling points of bound-keys is that they can be made non-extractable, i.e. protected with HSM/TPM or other form of trusted hardware or software. The ability to use a refresh token to rotate the public key of the bound token weakens the security offered by the non-extractable keys since an attacker can simply rotate to a public key they control.\n\n> MUST bind to the client (already covered by general OAuth confidential client)\n\nBinding to the client provides better protection against simply stealing the refresh token and then rotating the public key because you must also steal the client secret. In a complex modern enterprise you often want to scope HSM access so that one client-instance can not request signatures from another client-instance, but you can't quite scope the client secret this way as it is a client wide value unlike a bound token and refresh token that are scopes to a client-instance. Allowing the client secret + refresh token to rotate a public key breaks this scoping.\n\n- If the client secret + refresh token can be used to rotate the public key of a session, an attacker that compromises the refresh token and the client secret can bypass the HSM by rotating the public key. The refresh token is a bearer token and thus can't be protected by an HSM making it far more vulnerable than a key bound token.\n- Whereas if the refresh token can not rotate the public key, then even if the client secret, refresh token and the service that can request signatures from the HSM is compromised, the HSM can not be bypassed.\n\n> Requiring refresh tokens to be bound to the same key that is used to authenticate the client limits those to the age of that key. \n\nI can see having a public key for authenticating and a public key for refreshing.\n\n> A new instance (& new key) comes up and wants to pick up the prior established session.\n\nI want to understand this case better, how to do authenticate the new instance if its keying material and secrets are no longer available?\n", |
| 5204 | + "createdAt": "2026-07-12T17:34:09Z", |
| 5205 | + "updatedAt": "2026-07-12T17:34:09Z" |
| 5206 | + }, |
| 5207 | + { |
| 5208 | + "author": "arndt-s", |
| 5209 | + "authorAssociation": "MEMBER", |
| 5210 | + "body": "In SPIFFE a workload receives a key-bound JWT + private key in regular intervals. It is expected to drop the previous JWT+key once a new one is available. This flow may also happen due to a scheduled or on-demand signing key rotation. The key of the workload is software-backed.\n\nInteresting thought to separate the key for authentication and refresh tokens. It solves the problem but also requires additional fields to provide an additional public key (and I suppose proof of possession for that one too).\n\n", |
| 5211 | + "createdAt": "2026-07-13T11:20:14Z", |
| 5212 | + "updatedAt": "2026-07-13T11:20:14Z" |
| 5213 | + }, |
| 5214 | + { |
| 5215 | + "author": "EthanHeilman", |
| 5216 | + "authorAssociation": "NONE", |
| 5217 | + "body": "So SPIFFE is signing these new JWTs and authenticating the key rotation for the workload? Wouldn't the these new SPIFFE issued JWT count as a new authentication/new session? If so couldn't SPIFFE issue a new refresh token along side the JWT? What's the advantage of maintaining the same refresh token?\n\n> The key of the workload is software-backed.\n\nIs this a safe assumption long term? From where I sit it looks it like everyone is scrambling to get all key material into HSM/TPUs or software isolation, i.e. SSMs.", |
| 5218 | + "createdAt": "2026-07-13T15:48:29Z", |
| 5219 | + "updatedAt": "2026-07-13T15:48:29Z" |
| 5220 | + } |
| 5221 | + ] |
5185 | 5222 | }, |
5186 | 5223 | { |
5187 | 5224 | "number": 212, |
|
0 commit comments