Split out kube-cert-agent service account and bindings.

Followup on the previous comment to split apart the ServiceAccount of the kube-cert-agent and the main concierge pod. This is a bit cleaner and ensures that in testing our main Concierge pod never requires any privileged permissions.

Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
Matt Moyer 2021-05-03 16:31:48 -05:00
parent b80cbb8cc5
commit 165bef7809
No known key found for this signature in database
GPG Key ID: EAE88AD172C5AE2D
6 changed files with 54 additions and 22 deletions

View File

@ -22,6 +22,13 @@ metadata:
labels: #@ labels()
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
namespace: #@ namespace()
labels: #@ labels()
---
apiVersion: v1
kind: ConfigMap
metadata:
name: #@ defaultResourceNameWithSuffix("config")
@ -47,7 +54,7 @@ data:
impersonationTLSCertificateSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-tls-serving-certificate") @)
impersonationCACertificateSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-ca-certificate") @)
impersonationSignerSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-signer-ca-certificate") @)
serviceAccount: (@= defaultResourceName() @)
agentServiceAccount: (@= defaultResourceNameWithSuffix("kube-cert-agent") @)
labels: (@= json.encode(labels()).rstrip() @)
kubeCertAgent:
namePrefix: (@= defaultResourceNameWithSuffix("kube-cert-agent-") @)

View File

@ -24,9 +24,6 @@ rules:
- apiGroups: [ flowcontrol.apiserver.k8s.io ]
resources: [ flowschemas, prioritylevelconfigurations ]
verbs: [ get, list, watch ]
- apiGroups: [ policy ]
resources: [ podsecuritypolicies ]
verbs: [ use ]
- apiGroups: [ security.openshift.io ]
resources: [ securitycontextconstraints ]
verbs: [ use ]
@ -67,6 +64,34 @@ roleRef:
name: #@ defaultResourceNameWithSuffix("aggregated-api-server")
apiGroup: rbac.authorization.k8s.io
#! Give permission to the kube-cert-agent Pod to run privileged.
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
namespace: #@ namespace()
labels: #@ labels()
rules:
- apiGroups: [ policy ]
resources: [ podsecuritypolicies ]
verbs: [ use ]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
namespace: #@ namespace()
labels: #@ labels()
subjects:
- kind: ServiceAccount
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
namespace: #@ namespace()
roleRef:
kind: Role
name: #@ defaultResourceNameWithSuffix("kube-cert-agent")
apiGroup: rbac.authorization.k8s.io
#! Give permission to various objects within the app's own namespace
---
apiVersion: rbac.authorization.k8s.io/v1

View File

@ -122,8 +122,8 @@ func validateNames(names *NamesConfigSpec) error {
if names.ImpersonationSignerSecret == "" {
missingNames = append(missingNames, "impersonationSignerSecret")
}
if names.ServiceAccount == "" {
missingNames = append(missingNames, "serviceAccount")
if names.AgentServiceAccount == "" {
missingNames = append(missingNames, "agentServiceAccount")
}
if len(missingNames) > 0 {
return constable.Error("missing required names: " + strings.Join(missingNames, ", "))

View File

@ -43,7 +43,7 @@ func TestFromPath(t *testing.T) {
impersonationCACertificateSecret: impersonationCACertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
labels:
myLabelKey1: myLabelValue1
myLabelKey2: myLabelValue2
@ -73,7 +73,7 @@ func TestFromPath(t *testing.T) {
ImpersonationTLSCertificateSecret: "impersonationTLSCertificateSecret-value",
ImpersonationCACertificateSecret: "impersonationCACertificateSecret-value",
ImpersonationSignerSecret: "impersonationSignerSecret-value",
ServiceAccount: "serviceAccount-value",
AgentServiceAccount: "agentServiceAccount-value",
},
Labels: map[string]string{
"myLabelKey1": "myLabelValue1",
@ -100,7 +100,7 @@ func TestFromPath(t *testing.T) {
impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value
impersonationCACertificateSecret: impersonationCACertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantConfig: &Config{
DiscoveryInfo: DiscoveryInfoSpec{
@ -122,7 +122,7 @@ func TestFromPath(t *testing.T) {
ImpersonationTLSCertificateSecret: "impersonationTLSCertificateSecret-value",
ImpersonationCACertificateSecret: "impersonationCACertificateSecret-value",
ImpersonationSignerSecret: "impersonationSignerSecret-value",
ServiceAccount: "serviceAccount-value",
AgentServiceAccount: "agentServiceAccount-value",
},
Labels: map[string]string{},
KubeCertAgentConfig: KubeCertAgentSpec{
@ -137,7 +137,7 @@ func TestFromPath(t *testing.T) {
wantError: "validate names: missing required names: servingCertificateSecret, credentialIssuer, " +
"apiService, impersonationConfigMap, impersonationLoadBalancerService, " +
"impersonationTLSCertificateSecret, impersonationCACertificateSecret, " +
"impersonationSignerSecret, serviceAccount",
"impersonationSignerSecret, agentServiceAccount",
},
{
name: "Missing apiService name",
@ -151,7 +151,7 @@ func TestFromPath(t *testing.T) {
impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value
impersonationCACertificateSecret: impersonationCACertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: apiService",
},
@ -167,7 +167,7 @@ func TestFromPath(t *testing.T) {
impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value
impersonationCACertificateSecret: impersonationCACertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: credentialIssuer",
},
@ -183,7 +183,7 @@ func TestFromPath(t *testing.T) {
impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value
impersonationCACertificateSecret: impersonationCACertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: servingCertificateSecret",
},
@ -199,7 +199,7 @@ func TestFromPath(t *testing.T) {
impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value
impersonationCACertificateSecret: impersonationCACertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: impersonationConfigMap",
},
@ -215,7 +215,7 @@ func TestFromPath(t *testing.T) {
impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value
impersonationCACertificateSecret: impersonationCACertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: impersonationLoadBalancerService",
},
@ -231,7 +231,7 @@ func TestFromPath(t *testing.T) {
impersonationLoadBalancerService: impersonationLoadBalancerService-value
impersonationCACertificateSecret: impersonationCACertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: impersonationTLSCertificateSecret",
},
@ -247,7 +247,7 @@ func TestFromPath(t *testing.T) {
impersonationLoadBalancerService: impersonationLoadBalancerService-value
impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: impersonationCACertificateSecret",
},
@ -263,7 +263,7 @@ func TestFromPath(t *testing.T) {
impersonationLoadBalancerService: impersonationLoadBalancerService-value
impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value
impersonationCACertificateSecret: impersonationCACertificateSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: impersonationSignerSecret",
},
@ -277,7 +277,7 @@ func TestFromPath(t *testing.T) {
apiService: pinniped-api
impersonationLoadBalancerService: impersonationLoadBalancerService-value
impersonationSignerSecret: impersonationSignerSecret-value
serviceAccount: serviceAccount-value
agentServiceAccount: agentServiceAccount-value
`),
wantError: "validate names: missing required names: impersonationConfigMap, " +
"impersonationTLSCertificateSecret, impersonationCACertificateSecret",

View File

@ -41,7 +41,7 @@ type NamesConfigSpec struct {
ImpersonationTLSCertificateSecret string `json:"impersonationTLSCertificateSecret"`
ImpersonationCACertificateSecret string `json:"impersonationCACertificateSecret"`
ImpersonationSignerSecret string `json:"impersonationSignerSecret"`
ServiceAccount string `json:"serviceAccount"`
AgentServiceAccount string `json:"agentServiceAccount"`
}
// ServingCertificateConfigSpec contains the configuration knobs for the API's

View File

@ -121,7 +121,7 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
agentConfig := kubecertagent.AgentConfig{
Namespace: c.ServerInstallationInfo.Namespace,
ServiceAccountName: c.NamesConfig.ServiceAccount,
ServiceAccountName: c.NamesConfig.AgentServiceAccount,
ContainerImage: *c.KubeCertAgentConfig.Image,
NamePrefix: *c.KubeCertAgentConfig.NamePrefix,
ContainerImagePullSecrets: c.KubeCertAgentConfig.ImagePullSecrets,