Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

intended audience #13

Open
adeinega opened this issue Nov 26, 2024 · 3 comments
Open

intended audience #13

adeinega opened this issue Nov 26, 2024 · 3 comments
Assignees

Comments

@adeinega
Copy link
Contributor

The aud claim of a service account access token in K8s MUST include the URL of an OAuth server, and MUST NOT include the Kubernetes API server itself.

This ensures that these access tokens cannot be reused / misused. The same principle applies to all other JWTs mentioned in the document + provided examples.

@arndt-s
Copy link
Collaborator

arndt-s commented Nov 27, 2024

@adeinega any particular reason why it must be a URL and not just an identifier?
RFC 7523 uses the following definition:

The JWT MUST contain an "aud" (audience) claim containing a value that identifies the authorization server as an intended audience. The token endpoint URL of the authorization server MAY be used as a value for an "aud" element to identify the authorization server as an intended audience of the JWT.

Regarding the Kubernetes API server - while it surely shouldn't be there if not needed but MUST NOT seem to conflict with workloads that need to communicate with the API server. Do you have something else in mind apart from keeping the scope of the Kubernetes token as small as possible?

@adeinega
Copy link
Contributor Author

I think it could be the authorization server's issuer identifier per https://datatracker.ietf.org/doc/html/rfc8414#section-2, or just about the same but from https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata.

Specifying the token endpoint URL, as you mentioned, makes things even better, however it also needs to be said - there are a few other endpoints that require an OAuth client to be authenticated (I refer specifically to token revocation and introspect endpoints), and that makes it more challenging to use projected ATs.

If workloads need to communicate with the Kubernetes API server, the simplest solution is to use the service account token located at /var/run/secrets/kubernetes.io/serviceaccount.

Having seen so many cases of misuse, I believe any documents we produce should leave as little room as possible for that.

If workloads want to use service account (SA) access tokens as client credentials, they can obtain them through one of two methods:

  1. Token Request API which would also require the workload to know how to use this API and to have all permissions to request an access token with the intended audience and so forth, or
  2. a service account token projected into the file system, for instance, /var/run/secrets/client-abcde/assertion

This approach serves as a protective mechanism against token reuse, misuse, and malicious actions from workloads. By doing this, an AS never receives an assertion it could reply against the Kubernetes API. Additionally, workloads will find it significantly harder (whether intentionally or unintentionally) to share their access tokens with other workloads without detection.

As a random note on this, I'm also curious to see how K8s Token Request API would evolve over the time... In terms of providing a lightweight DPoP mechanism for its SA ATs.

@arndt-s
Copy link
Collaborator

arndt-s commented Dec 2, 2024

Raw notes from discussion amongst authors:

  • Audience should be kept as tight scoped as possible (best to not exceed one)
  • Regarding "aud": Reference rfc8707 to specify that it should be a URI.

@arndt-s arndt-s self-assigned this Dec 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants