impersonator: run as a distinct SA with minimal permissions

This change updates the impersonation proxy code to run as a
distinct service account that only has permission to impersonate
identities.  Thus any future vulnerability that causes the
impersonation headers to be dropped will fail closed instead of
escalating to the concierge's default service account which has
significantly more permissions.

Signed-off-by: Monis Khan <mok@vmware.com>
This commit is contained in:
Monis Khan
2021-06-09 19:00:54 -04:00
parent 918c50f6a7
commit 898f2bf942
5 changed files with 315 additions and 11 deletions

View File

@@ -29,6 +29,18 @@ metadata:
labels: #@ labels()
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
namespace: #@ namespace()
labels: #@ labels()
annotations:
#! we need to create this service account before we create the secret
kapp.k14s.io/change-group: "impersonation-proxy.concierge.pinniped.dev/serviceaccount"
secrets: #! make sure the token controller does not create any other secrets
- name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
---
apiVersion: v1
kind: ConfigMap
metadata:
name: #@ defaultResourceNameWithSuffix("config")
@@ -134,6 +146,8 @@ spec:
mountPath: /etc/config
- name: podinfo
mountPath: /etc/podinfo
- name: impersonation-proxy
mountPath: /var/run/secrets/impersonation-proxy.concierge.pinniped.dev/serviceaccount
livenessProbe:
httpGet:
path: /healthz
@@ -156,6 +170,12 @@ spec:
- name: config-volume
configMap:
name: #@ defaultResourceNameWithSuffix("config")
- name: impersonation-proxy
secret:
secretName: #@ defaultResourceNameWithSuffix("impersonation-proxy")
items: #! make sure our pod does not start until the token controller has a chance to populate the secret
- key: token
path: token
- name: podinfo
downwardAPI:
items:
@@ -265,3 +285,16 @@ spec:
loadBalancerIP: #@ data.values.impersonation_proxy_spec.service.load_balancer_ip
#@ end
annotations: #@ data.values.impersonation_proxy_spec.service.annotations
---
apiVersion: v1
kind: Secret
metadata:
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
namespace: #@ namespace()
labels: #@ labels()
annotations:
#! wait until the SA exists to create this secret so that the token controller does not delete it
#! we have this secret at the end so that kubectl will create the service account first
kapp.k14s.io/change-rule: "upsert after upserting impersonation-proxy.concierge.pinniped.dev/serviceaccount"
kubernetes.io/service-account.name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
type: kubernetes.io/service-account-token

View File

@@ -28,12 +28,6 @@ rules:
resources: [ securitycontextconstraints ]
verbs: [ use ]
resourceNames: [ nonroot ]
- apiGroups: [ "" ]
resources: [ "users", "groups", "serviceaccounts" ]
verbs: [ "impersonate" ]
- apiGroups: [ "authentication.k8s.io" ]
resources: [ "*" ] #! What we really want is userextras/* but the RBAC authorizer only supports */subresource, not resource/*
verbs: [ "impersonate" ]
- apiGroups: [ "" ]
resources: [ nodes ]
verbs: [ list ]
@@ -64,6 +58,35 @@ roleRef:
name: #@ defaultResourceNameWithSuffix("aggregated-api-server")
apiGroup: rbac.authorization.k8s.io
#! Give minimal permissions to impersonation proxy service account
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
labels: #@ labels()
rules:
- apiGroups: [ "" ]
resources: [ "users", "groups", "serviceaccounts" ]
verbs: [ "impersonate" ]
- apiGroups: [ "authentication.k8s.io" ]
resources: [ "*" ] #! What we really want is userextras/* but the RBAC authorizer only supports */subresource, not resource/*
verbs: [ "impersonate" ]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
labels: #@ labels()
subjects:
- kind: ServiceAccount
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
namespace: #@ namespace()
roleRef:
kind: ClusterRole
name: #@ defaultResourceNameWithSuffix("impersonation-proxy")
apiGroup: rbac.authorization.k8s.io
#! Give permission to the kube-cert-agent Pod to run privileged.
---
apiVersion: rbac.authorization.k8s.io/v1