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

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

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.

@kramaranya kramaranya force-pushed the legacy-sa-opt-in branch 2 times, most recently from dcf81c3 to 37debda Compare March 27, 2025 12:35
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

Successfully merging this pull request may close these issues.

3 participants