Skip to content

Add manual opt-in for legacy service account tokens #357

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

Open
wants to merge 3 commits into
base: sig-auth-acceptance
Choose a base branch
from

Conversation

kramaranya
Copy link
Contributor

Fixes #336

@kramaranya kramaranya changed the title WIP: Add manual opt-in for legacy service account tokens Add manual opt-in for legacy service account tokens Feb 10, 2025
@kramaranya
Copy link
Contributor Author

@stlaz @ibihim could you please review this pr?

Copy link
Collaborator

@ibihim ibihim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unit tests might not have been necessary, but fixing the e2e-tests would be crucial :)

You also need to regenerate the README.md with the make generate.

@ibihim
Copy link
Collaborator

ibihim commented Feb 13, 2025

/lgtm

@ibihim
Copy link
Collaborator

ibihim commented Feb 14, 2025

@kramaranya, I think we have an audience token test, right? we might be able to drop it, if we do not have any tests without audience set, right? Maybe we could have a negative test case then, that the server fails if it isn't set?

Copy link
Collaborator

@stlaz stlaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will legacy SA tokens be denied when the new flag is unset but audiences are set?
Will they be accepted if both are set?

Please add e2e tests for all possible scenarios, I don't think I've found legacy SA tokens creation in the e2e tests.

@kramaranya
Copy link
Contributor Author

@kramaranya, I think we have an audience token test, right? we might be able to drop it, if we do not have any tests without audience set, right? Maybe we could have a negative test case then, that the server fails if it isn't set?

@ibihim If I understood you correctly, I've already added a negative test for this scenario (empty audiences when legacy tokens are not allowed) -- https://github.com/brancz/kube-rbac-proxy/pull/357/files#diff-770d985644314c26e2d1c0e8fb70e4714408a9888a4e2749a633144697201bacR191-R203

Copy link
Collaborator

@stlaz stlaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll have to create the legacy SA token separately

),
),
Then: kubetest.Actions(
kubetest.ClientSucceeds(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're attempting to use a legacy token but the proxy does is not supposed to accept these in this case. This should fail.

kubetest.ClientSucceeds(
client,
legacyCommand,
&kubetest.RunOptions{TokenAudience: "kube-rbac-proxy"},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need the options in this case, right?

kubetest.ClientSucceeds(
client,
command,
&kubetest.RunOptions{TokenAudience: ""},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is equal to it being nil, right?


func testLegacyTokenFlag(client kubernetes.Interface) kubetest.TestSuite {
return func(t *testing.T) {
legacyCommand := `curl --connect-timeout 5 -v -s -k --fail -H "Authorization: Bearer $(cat /var/run/secrets/tokens/requestedtoken)" https://kube-rbac-proxy.default.svc.cluster.local:8443/metrics`
Copy link
Collaborator

@stlaz stlaz Mar 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/var/run/secrets/tokens/requestedtoken does not actually house the legacy tokens. The below code appears to be creating such tokens:

if opts != nil && opts.TokenAudience != "" {
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
Name: "requestedtoken",
VolumeSource: corev1.VolumeSource{
Projected: &corev1.ProjectedVolumeSource{
Sources: []corev1.VolumeProjection{{
ServiceAccountToken: &corev1.ServiceAccountTokenProjection{
Audience: opts.TokenAudience,
Path: "requestedtoken",
},
}},
},
},
})
pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts,
corev1.VolumeMount{
Name: "requestedtoken",
MountPath: "/var/run/secrets/tokens",
},
)
}

We may actually want to rename the directory from /var/run/secrets/tokens to something else, like /var/run/projected/tokens, I personally find it a bit confusing.

You'll have to follow https://kubernetes.io/docs/concepts/configuration/secret/#serviceaccount-token-secrets to create a token secret along with your other manifests. Use a different directory than for the short-lived SA tokens so that we can distinguish these two in tests.

func testLegacyTokenFlag(client kubernetes.Interface) kubetest.TestSuite {
return func(t *testing.T) {
legacyCommand := `curl --connect-timeout 5 -v -s -k --fail -H "Authorization: Bearer $(cat /var/run/secrets/tokens/requestedtoken)" https://kube-rbac-proxy.default.svc.cluster.local:8443/metrics`
command := `curl --connect-timeout 5 -v -s -k --fail -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kube-rbac-proxy.default.svc.cluster.local:8443/metrics`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this command should actually have /var/run/secrets/tokens/requestedtoken as an input for the token

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LegacyAllowedNoAudience test checks a scenario with no audience set. But /var/run/secrets/tokens/requestedtoken sets an audience, so it wouldn't match our no-audience case.

if opts != nil && opts.TokenAudience != "" {
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
Name: "requestedtoken",
VolumeSource: corev1.VolumeSource{
Projected: &corev1.ProjectedVolumeSource{
Sources: []corev1.VolumeProjection{{
ServiceAccountToken: &corev1.ServiceAccountTokenProjection{
Audience: opts.TokenAudience,
Path: "requestedtoken",

That's why I use the default token /var/run/secrets/kubernetes.io/serviceaccount/token instead.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The /var/run/secrets/kubernetes.io/serviceaccount/token will also contain an audience.

@kramaranya kramaranya force-pushed the legacy-sa-opt-in branch 2 times, most recently from dcf81c3 to 37debda Compare March 27, 2025 12:35
@stlaz stlaz added the sig-auth-acceptance issues created during review for sig-auth-acceptance label Apr 8, 2025
args:
- "--secure-port=8443"
- "--upstream=http://127.0.0.1:8081/"
- "--auth-token-audiences=kube-rbac-proxy,https://kubernetes.default.svc.cluster.local"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I was wondering why the test was passing. This and the below configs were supposed to be the same, the difference should only be in "--allow-legacy-serviceaccount-tokens=true", not in audiences.

https://kubernetes.default.svc.cluster.local is an "implicit" audience, so when you use the legacy SA token, IIRC this is returned when there are no other audiences present. However, this implicit audience can be different depending on kube-apiserver configuration, and so we couldn't make a simple guidance on how to config the audiences.

@ibihim Should we treat the --allow-legacy-serviceaccount-tokens that allows empty --auth-token-audiences but will fail if there are audiences set? Or would we actually allow both legacy and bound SA tokens, the latter retains the audience check if audiences are set? Doing that might get unnecessarily complicated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sig-auth-acceptance issues created during review for sig-auth-acceptance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants