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

Project serviceAccountToken volume expirationSeconds is ignored and always produces a token with an expiry of ten years #1579

Open
strideynet opened this issue Mar 4, 2024 · 4 comments
Assignees

Comments

@strideynet
Copy link

strideynet commented Mar 4, 2024

What happened?

When configuring a projected serviceAccountVolume volume you are usually able to set an expirationSeconds that controls the expiry time of the token e.g

        - name: join-sa-token
          projected:
            sources:
              - serviceAccountToken:
                  path: join-sa-token
                  # 600 seconds is the minimum that Kubernetes supports. We
                  # recommend this value is used.
                  expirationSeconds: 600
                  # `example.teleport.sh` must be replaced with the name of
                  # your Teleport cluster.
                  audience: example.teleport.sh

See https://kubernetes.io/docs/concepts/storage/projected-volumes/#serviceaccounttoken for the Kubernetes side documentation of this.

When inspecting a token produced by this configuration within vcluster, we see that instead of producing an expiry of 600 seconds, one of 10 years is produced instead.

This is problematic for two reasons:

  • It leaves these tokens vulnerable to long-term use if exfiltrated. If someone has configured some sort of federated trust with the Kubernetes cluster, and these tokens are being validated by another service as an OIDC Identity Token, that service will continue to trust the token for 10 years.
  • Some services (e.g Teleport) enforce a limitation that it will only trust tokens with a short expiry (e.g 30 minutes) to mitigate the above risk.

This issue was reported by a customer of ourselves (Teleport) so I have limited details on the actual cluster configuration.

What did you expect to happen?

The expirationSeconds should be respected and used for the service account tokens expiry:

        - name: my-token
          projected:
            sources:
              - serviceAccountToken:
                  path: my-token
                  expirationSeconds: 600
                  audience: example.com

How can we reproduce it (as minimally and precisely as possible)?

Add a Projected Service Account token to your PodSpec with a specified expirationSeconds and inspect the mounted JWTs expiry.

Anything else we need to know?

This looks to be caused by a hardcoded value here:

expirationSeconds := int64(10 * 365 * 24 * 60 * 60)
- instead the value from the projected volume should be used.

Host cluster Kubernetes version

k version
Client Version: v1.28.4
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.2+k3s1

Host cluster Kubernetes distribution

# Write here

vlcuster version

v version
vcluster version 0.17.1

Vcluster Kubernetes distribution(k3s(default)), k8s, k0s)

# Write here

OS and Arch

OS: 
Arch:
@strideynet
Copy link
Author

I'm waiting for our customer to send over the versions - I'll add them to the issue once I've received them

@strideynet
Copy link
Author

Potential dupe of #969 ?

@ThomasK33
Copy link
Member

Hey @strideynet, thanks for opening the issues.

Yeah, this issue is a duplicate of #969.

As noted in the other issue, the implementation was initially done the same way as Kubernetes and has remained the same.
However, replacing the expiration value is more complex than using the value in the projected volumes spec because the syncer makes calls against the vCluster's API server using the token requests API and then stores the resulting tokens in a secret on the host.
Therefore, the syncer would need logic to regenerate the token periodically (if I recall correctly, Kubernetes updates PSATs after 75 or 80% of their expiration time) and then update the secret.

Additionally, there would need to be a mechanism to store and load the token-regeneration dates, crons, or whatever the actual implementation may use, as a syncer restart should maintain this regeneration schedule.

Since you already pointed out this issue's code location, could you create a PR to add the necessary changes?

@strideynet
Copy link
Author

Since you already pointed out this issue's code location, could you create a PR to add the necessary changes?

Unfortunately, since we don't use VCluster (although it looks neat!), it'll be difficult for me to carve out time to look at this.

@deniseschannon deniseschannon added the bug label May 8, 2024 — with Linear
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants