-
Notifications
You must be signed in to change notification settings - Fork 327
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
feat(kuma-cp) verify ServiceAccountToken bound to a Pod #2745
Conversation
Signed-off-by: Jakub Dyszkiewicz <jakub.dyszkiewicz@gmail.com>
Codecov Report
@@ Coverage Diff @@
## master #2745 +/- ##
==========================================
- Coverage 51.99% 51.98% -0.01%
==========================================
Files 877 877
Lines 51142 51162 +20
==========================================
+ Hits 26589 26596 +7
- Misses 22437 22449 +12
- Partials 2116 2117 +1
Continue to review full report at Codecov.
|
@@ -57,6 +58,12 @@ func WithStatefulSet(apply bool) DeploymentOptsFn { | |||
} | |||
} | |||
|
|||
func WithServiceAccount(sa string) DeploymentOptsFn { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
func WithServiceAccount(sa string) DeploymentOptsFn { | |
func WithServiceAccount(accountName string) DeploymentOptsFn { |
pkg/xds/auth/k8s/authenticator.go
Outdated
Namespace: namespace, | ||
Name: name, | ||
}, pod); err != nil { | ||
return "", errors.Wrap(err, "could not retrieve Pod to verify identity of a dataplane proxy") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: might be useful to include the namespaced name in the error
pkg/xds/auth/k8s/authenticator.go
Outdated
} | ||
return nil | ||
} | ||
|
||
func (k *kubeAuthenticator) podServiceAccountName(ctx context.Context, name, namespace string) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit:
func (k *kubeAuthenticator) podServiceAccountName(ctx context.Context, name, namespace string) (string, error) { | |
func (k *kubeAuthenticator) podServiceAccountName(ctx context.Context, podName types.NamespacedName) (string, error) { |
pkg/xds/auth/k8s/authenticator.go
Outdated
} | ||
namespace := userInfo[2] | ||
if namespace != proxyNamespace { | ||
return errors.Errorf("authentication failed: token belongs to a namespace (%q) different from proxyId (%q)", namespace, proxyNamespace) | ||
return errors.Errorf("token belongs to a namespace (%q) different from proxyId (%q)", namespace, proxyNamespace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: the parentheses in this error seem a bit out of place since no other error format uses them
pkg/xds/auth/k8s/authenticator.go
Outdated
_, proxyNamespace, err := util_k8s.CoreNameToK8sName(dataplane.Meta.GetName()) | ||
if err != nil { | ||
return err | ||
return errors.Errorf("token must belong to a k8s system account, got %q", tokenReview.Status.User.Username) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return errors.Errorf("token must belong to a k8s system account, got %q", tokenReview.Status.User.Username) | |
return errors.Errorf("user %q is not a service account", tokenReview.Status.User.Username) |
pkg/xds/auth/k8s/authenticator.go
Outdated
} | ||
serviceAccountName, err := k.podServiceAccountName(ctx, proxyName, proxyNamespace) | ||
if err != nil { | ||
return errors.Wrap(err, "could not retrieve Pods Service Account to verify identity of a dataplane proxy") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error message substantially repeats the one in podServiceAccountName
. Maybe trim or or the other?
Same in authZoneIngress
.
…dual-satoken Signed-off-by: Jakub Dyszkiewicz <jakub.dyszkiewicz@gmail.com>
Signed-off-by: Jakub Dyszkiewicz <jakub.dyszkiewicz@gmail.com>
Signed-off-by: Jakub Dyszkiewicz <jakub.dyszkiewicz@gmail.com> (cherry picked from commit 0b2a7bf)
Signed-off-by: Jakub Dyszkiewicz <jakub.dyszkiewicz@gmail.com>
Signed-off-by: Jakub Dyszkiewicz <jakub.dyszkiewicz@gmail.com>
Signed-off-by: Jakub Dyszkiewicz <jakub.dyszkiewicz@gmail.com>
Summary
When authenticating kuma-dp on Kubernetes, we are carrying ServiceAccountToken and verify it in Kuma CP.
So far, we were only verifying the namespace of this Service Account Token but not the name of the token itself.
That means that any kuma-dp in one namespace could impersonate others in the same namespace.
I think this was done this way because if as a team member you manage Deployment and ServiceAccount objects in one namespace. There is no built-in mechanism in Kubernetes to prevent a user from using another ServiceAccount in a namespace for your Deployment.
However, there are cases where users are not responsible for managing Deployment objects but some high-level provisioner does that for them.
Alternatively, you could have a controller or OPA for Kubernetes that would restrict ServiceAccountToken to given Deployment.
Therefore Kuma should be more strict about verifying the token to not only verify a namespace of a token but check the Pod for the
serviceAccountTokenName
and also verify a token name.Issues resolved
No issues.
Documentation
Testing
Backwards compatibility
backport-to-stable
label if the code is backwards compatible. Otherwise, list breaking changes.