diff --git a/pkg/registry/core/serviceaccount/storage/token.go b/pkg/registry/core/serviceaccount/storage/token.go index 63bffdfdc8e..0079a51cc75 100644 --- a/pkg/registry/core/serviceaccount/storage/token.go +++ b/pkg/registry/core/serviceaccount/storage/token.go @@ -74,6 +74,9 @@ func (r *TokenREST) Create(ctx genericapirequest.Context, name string, obj runti return nil, err } pod = podObj.(*api.Pod) + if name != pod.Spec.ServiceAccountName { + return nil, errors.NewBadRequest(fmt.Sprintf("cannot bind token for serviceaccount %q to pod running with serviceaccount %q", name, pod.Spec.ServiceAccountName)) + } uid = pod.UID case gvk.Group == "" && gvk.Kind == "Secret": secretObj, err := r.secrets.Get(ctx, ref.Name, &metav1.GetOptions{}) diff --git a/test/integration/auth/svcaccttoken_test.go b/test/integration/auth/svcaccttoken_test.go index 0bccbcc5283..259f64fd617 100644 --- a/test/integration/auth/svcaccttoken_test.go +++ b/test/integration/auth/svcaccttoken_test.go @@ -81,6 +81,16 @@ func TestServiceAccountTokenCreate(t *testing.T) { Containers: []v1.Container{{Name: "test-container", Image: "nginx"}}, }, } + otherpod = &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "other-test-pod", + Namespace: sa.Namespace, + }, + Spec: v1.PodSpec{ + ServiceAccountName: "other-" + sa.Name, + Containers: []v1.Container{{Name: "test-container", Image: "nginx"}}, + }, + } secret = &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "test-secret", @@ -220,6 +230,29 @@ func TestServiceAccountTokenCreate(t *testing.T) { checkPayload(t, treq.Status.Token, `"myns"`, "kubernetes.io", "namespace") checkPayload(t, treq.Status.Token, `"test-svcacct"`, "kubernetes.io", "serviceaccount", "name") }) + + t.Run("bound to service account and pod running as different service account", func(t *testing.T) { + treq := &authenticationv1.TokenRequest{ + Spec: authenticationv1.TokenRequestSpec{ + Audiences: []string{"api"}, + ExpirationSeconds: &one, + BoundObjectRef: &authenticationv1.BoundObjectReference{ + Kind: "Pod", + APIVersion: "v1", + Name: otherpod.Name, + }, + }, + } + + sa, del := createDeleteSvcAcct(t, cs, sa) + defer del() + _, del = createDeletePod(t, cs, otherpod) + defer del() + + if resp, err := cs.CoreV1().ServiceAccounts(sa.Namespace).CreateToken(sa.Name, treq); err == nil { + t.Fatalf("expected err but got: %#v", resp) + } + }) } func checkPayload(t *testing.T, tok string, want string, parts ...string) {