Skip to content

Commit c32b6fb

Browse files
committed
add service account to security context struct
Signed-off-by: kaizhe <[email protected]>
1 parent 49d3faa commit c32b6fb

File tree

3 files changed

+61
-28
lines changed

3 files changed

+61
-28
lines changed

advisor/processor/get.go

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package processor
22

33
import (
4+
"fmt"
5+
46
"github.com/sysdiglabs/kube-psp-advisor/advisor/types"
57

68
"k8s.io/api/core/v1"
7-
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
v1meta "k8s.io/apimachinery/pkg/apis/meta/v1"
810
)
911

1012
const (
@@ -23,14 +25,15 @@ func (p *Processor) getSecuritySpecFromDaemonSets() ([]types.ContainerSecuritySp
2325
cspList := []types.ContainerSecuritySpec{}
2426
pspList := []types.PodSecuritySpec{}
2527

26-
daemonSetList, err := clientset.AppsV1().DaemonSets(p.namespace).List(v12.ListOptions{})
28+
daemonSetList, err := clientset.AppsV1().DaemonSets(p.namespace).List(v1meta.ListOptions{})
2729

2830
if err != nil {
2931
return cspList, pspList, err
3032
}
3133

3234
for _, ds := range daemonSetList.Items {
33-
sa := p.serviceAccountMap[ds.Spec.Template.Spec.ServiceAccountName]
35+
sa := p.GetServiceAccount(ds.Namespace, ds.Spec.Template.Spec.ServiceAccountName)
36+
3437
cspList2, podSecurityPosture := p.gen.GetSecuritySpecFromPodSpec(types.Metadata{
3538
Name: ds.Name,
3639
Kind: DaemonSet,
@@ -48,7 +51,7 @@ func (p *Processor) getSecuritySpecFromReplicaSets() ([]types.ContainerSecurityS
4851
cssList := []types.ContainerSecuritySpec{}
4952
pssList := []types.PodSecuritySpec{}
5053

51-
replicaSetList, err := clientset.AppsV1().ReplicaSets(p.namespace).List(v12.ListOptions{})
54+
replicaSetList, err := clientset.AppsV1().ReplicaSets(p.namespace).List(v1meta.ListOptions{})
5255

5356
if err != nil {
5457
return cssList, pssList, err
@@ -59,7 +62,7 @@ func (p *Processor) getSecuritySpecFromReplicaSets() ([]types.ContainerSecurityS
5962
continue
6063
}
6164

62-
sa := p.serviceAccountMap[rs.Spec.Template.Spec.ServiceAccountName]
65+
sa := p.GetServiceAccount(rs.Namespace, rs.Spec.Template.Spec.ServiceAccountName)
6366
cspList2, psc := p.gen.GetSecuritySpecFromPodSpec(types.Metadata{
6467
Name: rs.Name,
6568
Kind: ReplicaSet,
@@ -77,14 +80,14 @@ func (p *Processor) getSecuritySpecFromStatefulSets() ([]types.ContainerSecurity
7780
cssList := []types.ContainerSecuritySpec{}
7881
pssList := []types.PodSecuritySpec{}
7982

80-
statefulSetList, err := clientset.AppsV1().StatefulSets(p.namespace).List(v12.ListOptions{})
83+
statefulSetList, err := clientset.AppsV1().StatefulSets(p.namespace).List(v1meta.ListOptions{})
8184

8285
if err != nil {
8386
return cssList, pssList, err
8487
}
8588

8689
for _, sts := range statefulSetList.Items {
87-
sa := p.serviceAccountMap[sts.Spec.Template.Spec.ServiceAccountName]
90+
sa := p.GetServiceAccount(sts.Namespace, sts.Spec.Template.Spec.ServiceAccountName)
8891
cspList2, pss := p.gen.GetSecuritySpecFromPodSpec(types.Metadata{
8992
Name: sts.Name,
9093
Kind: StatefulSet,
@@ -102,14 +105,14 @@ func (p *Processor) getSecuritySpecFromReplicationController() ([]types.Containe
102105
cssList := []types.ContainerSecuritySpec{}
103106
pssList := []types.PodSecuritySpec{}
104107

105-
replicationControllerList, err := clientset.CoreV1().ReplicationControllers(p.namespace).List(v12.ListOptions{})
108+
replicationControllerList, err := clientset.CoreV1().ReplicationControllers(p.namespace).List(v1meta.ListOptions{})
106109

107110
if err != nil {
108111
return cssList, pssList, err
109112
}
110113

111114
for _, rc := range replicationControllerList.Items {
112-
sa := p.serviceAccountMap[rc.Spec.Template.Spec.ServiceAccountName]
115+
sa := p.GetServiceAccount(rc.Namespace, rc.Spec.Template.Spec.ServiceAccountName)
113116
cspList2, pss := p.gen.GetSecuritySpecFromPodSpec(types.Metadata{
114117
Name: rc.Name,
115118
Kind: ReplicationController,
@@ -127,14 +130,14 @@ func (p *Processor) getSecuritySpecFromCronJobs() ([]types.ContainerSecuritySpec
127130
cssList := []types.ContainerSecuritySpec{}
128131
pssList := []types.PodSecuritySpec{}
129132

130-
jobList, err := clientset.BatchV1beta1().CronJobs(p.namespace).List(v12.ListOptions{})
133+
jobList, err := clientset.BatchV1beta1().CronJobs(p.namespace).List(v1meta.ListOptions{})
131134

132135
if err != nil {
133136
return cssList, pssList, err
134137
}
135138

136139
for _, cronJob := range jobList.Items {
137-
sa := p.serviceAccountMap[cronJob.Spec.JobTemplate.Spec.Template.Spec.ServiceAccountName]
140+
sa := p.GetServiceAccount(cronJob.Namespace, cronJob.Spec.JobTemplate.Spec.Template.Spec.ServiceAccountName)
138141
cspList2, pss := p.gen.GetSecuritySpecFromPodSpec(types.Metadata{
139142
Name: cronJob.Name,
140143
Kind: CronJob,
@@ -152,7 +155,7 @@ func (p *Processor) getSecuritySpecFromJobs() ([]types.ContainerSecuritySpec, []
152155
cssList := []types.ContainerSecuritySpec{}
153156
pssList := []types.PodSecuritySpec{}
154157

155-
jobList, err := clientset.BatchV1().Jobs(p.namespace).List(v12.ListOptions{})
158+
jobList, err := clientset.BatchV1().Jobs(p.namespace).List(v1meta.ListOptions{})
156159

157160
if err != nil {
158161
return cssList, pssList, err
@@ -162,7 +165,7 @@ func (p *Processor) getSecuritySpecFromJobs() ([]types.ContainerSecuritySpec, []
162165
if len(job.OwnerReferences) > 0 {
163166
continue
164167
}
165-
sa := p.serviceAccountMap[job.Spec.Template.Spec.ServiceAccountName]
168+
sa := p.GetServiceAccount(job.Namespace, job.Spec.Template.Spec.ServiceAccountName)
166169
cspList2, pss := p.gen.GetSecuritySpecFromPodSpec(types.Metadata{
167170
Name: job.Name,
168171
Kind: Job,
@@ -180,14 +183,14 @@ func (p *Processor) getSecuritySpecFromDeployments() ([]types.ContainerSecurityS
180183
cssList := []types.ContainerSecuritySpec{}
181184
pssList := []types.PodSecuritySpec{}
182185

183-
deployments, err := clientset.AppsV1().Deployments(p.namespace).List(v12.ListOptions{})
186+
deployments, err := clientset.AppsV1().Deployments(p.namespace).List(v1meta.ListOptions{})
184187

185188
if err != nil {
186189
return cssList, pssList, err
187190
}
188191

189192
for _, deploy := range deployments.Items {
190-
sa := p.serviceAccountMap[deploy.Spec.Template.Spec.ServiceAccountName]
193+
sa := p.GetServiceAccount(deploy.Namespace, deploy.Spec.Template.Spec.ServiceAccountName)
191194
cspList2, pss := p.gen.GetSecuritySpecFromPodSpec(types.Metadata{
192195
Name: deploy.Name,
193196
Kind: Deployment,
@@ -205,7 +208,7 @@ func (p *Processor) getSecuritySpecFromPods() ([]types.ContainerSecuritySpec, []
205208
cssList := []types.ContainerSecuritySpec{}
206209
pssList := []types.PodSecuritySpec{}
207210

208-
pods, err := clientset.CoreV1().Pods(p.namespace).List(v12.ListOptions{})
211+
pods, err := clientset.CoreV1().Pods(p.namespace).List(v1meta.ListOptions{})
209212

210213
if err != nil {
211214
return cssList, pssList, err
@@ -216,7 +219,7 @@ func (p *Processor) getSecuritySpecFromPods() ([]types.ContainerSecuritySpec, []
216219
continue
217220
}
218221

219-
sa := p.serviceAccountMap[pod.Spec.ServiceAccountName]
222+
sa := p.GetServiceAccount(pod.Namespace, pod.Spec.ServiceAccountName)
220223
cspList2, podSecurityPosture := p.gen.GetSecuritySpecFromPodSpec(types.Metadata{
221224
Name: pod.Name,
222225
Kind: Pod,
@@ -232,14 +235,32 @@ func (p *Processor) getSecuritySpecFromPods() ([]types.ContainerSecuritySpec, []
232235
func (p *Processor) getServiceAccountMap() (map[string]v1.ServiceAccount, error) {
233236
serviceAccountMap := map[string]v1.ServiceAccount{}
234237

235-
serviceAccounts, err := p.k8sClient.CoreV1().ServiceAccounts(p.namespace).List(v12.ListOptions{})
238+
serviceAccounts, err := p.k8sClient.CoreV1().ServiceAccounts(p.namespace).List(v1meta.ListOptions{})
236239
if err != nil {
237240
return serviceAccountMap, err
238241
}
239242

243+
// service account is an namespaced object
240244
for _, sa := range serviceAccounts.Items {
241-
serviceAccountMap[sa.Name] = sa
245+
key := fmt.Sprintf("%s:%s", sa.Namespace, sa.Name)
246+
serviceAccountMap[key] = sa
242247
}
243248

244249
return serviceAccountMap, nil
245250
}
251+
252+
func (p *Processor) GetServiceAccount(ns, saName string) v1.ServiceAccount {
253+
if saName == "" {
254+
saName = "default"
255+
}
256+
257+
key := fmt.Sprintf("%s:%s", ns, saName)
258+
259+
sa, exists := p.serviceAccountMap[key]
260+
261+
if !exists {
262+
return v1.ServiceAccount{}
263+
}
264+
265+
return sa
266+
}

advisor/types/securityspec.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type ContainerSecuritySpec struct {
5757
RunAsUser *int64 `json:"runAsUser,omitempty"`
5858
RunAsGroup *int64 `json:"runAsGroup,omitempty"`
5959
HostPorts []int32 `json:"hostPorts,omitempty"`
60+
ServiceAccount string `json:"serviceAccount,omitempty"`
6061
}
6162

6263
type PodSecuritySpec struct {
@@ -67,6 +68,7 @@ type PodSecuritySpec struct {
6768
HostIPC bool `json:"hostIPC,omitempty"`
6869
VolumeTypes []string `json:"volumeTypes,omitempty"`
6970
MountHostPaths map[string]bool `json:"mountedHostPath,omitempty"`
71+
ServiceAccount string `json:"serviceAccount,omitempty"`
7072
}
7173

7274
type Metadata struct {

generator/generator.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func getVolumeTypes(spec v1.PodSpec, sa *v1.ServiceAccount) (volumeTypes []strin
4141
}
4242
}
4343

44-
// If don't opt out of automounting API credentils for a service account
44+
// If don't opt out of automounting API credentials for a service account
4545
// or a particular pod, "secret" needs to be into PSP allowed volume types.
4646
if sa == nil || mountServiceAccountToken(spec, *sa) {
4747
volumeTypeMap[volumeTypeSecret] = true
@@ -257,6 +257,7 @@ func (pg *Generator) GetSecuritySpecFromPodSpec(metadata types.Metadata, namespa
257257
HostIPC: spec.HostIPC,
258258
VolumeTypes: getVolumeTypes(spec, sa),
259259
MountHostPaths: getVolumeHostPaths(spec),
260+
ServiceAccount: getServiceAccountName(spec),
260261
}
261262

262263
for _, container := range spec.InitContainers {
@@ -278,6 +279,7 @@ func (pg *Generator) GetSecuritySpecFromPodSpec(metadata types.Metadata, namespa
278279
RunAsGroup: getRunAsGroup(container.SecurityContext, spec.SecurityContext),
279280
RunAsUser: getRunAsUser(container.SecurityContext, spec.SecurityContext),
280281
HostPorts: getHostPorts(container.Ports),
282+
ServiceAccount: getServiceAccountName(spec),
281283
}
282284
cssList = append(cssList, csc)
283285
}
@@ -301,6 +303,7 @@ func (pg *Generator) GetSecuritySpecFromPodSpec(metadata types.Metadata, namespa
301303
RunAsGroup: getRunAsGroup(container.SecurityContext, spec.SecurityContext),
302304
RunAsUser: getRunAsUser(container.SecurityContext, spec.SecurityContext),
303305
HostPorts: getHostPorts(container.Ports),
306+
ServiceAccount: getServiceAccountName(spec),
304307
}
305308
cssList = append(cssList, csc)
306309
}
@@ -389,7 +392,8 @@ func (pg *Generator) GeneratePSP(
389392
runAsNonRootCount++
390393
}
391394

392-
if sc.RunAsUser != nil {
395+
// runAsUser is set and not to root
396+
if sc.RunAsUser != nil && *sc.RunAsUser != 0 {
393397
runAsUser[*sc.RunAsUser] = true
394398
runAsUserCount++
395399
}
@@ -399,7 +403,7 @@ func (pg *Generator) GeneratePSP(
399403
}
400404

401405
// set host ports
402-
// TODO: need to integrate with listening port during the runtime, might cause false positive.
406+
//TODO: need to integrate with listening port during the runtime, might cause false positive.
403407
//for _, port := range sc.HostPorts {
404408
// psp.Spec.HostPorts = append(psp.Spec.HostPorts, v1beta1.HostPortRange{Min: port, Max: port})
405409
//}
@@ -419,12 +423,10 @@ func (pg *Generator) GeneratePSP(
419423
if runAsUserCount == len(cssList) {
420424
psp.Spec.RunAsUser.Rule = v1beta1.RunAsUserStrategyMustRunAs
421425
for uid := range runAsUser {
422-
if psp.Spec.RunAsUser.Rule == v1beta1.RunAsUserStrategyMustRunAsNonRoot && uid != 0 {
423-
psp.Spec.RunAsUser.Ranges = append(psp.Spec.RunAsUser.Ranges, v1beta1.IDRange{
424-
Min: uid,
425-
Max: uid,
426-
})
427-
}
426+
psp.Spec.RunAsUser.Ranges = append(psp.Spec.RunAsUser.Ranges, v1beta1.IDRange{
427+
Min: uid,
428+
Max: uid,
429+
})
428430
}
429431
}
430432

@@ -647,3 +649,11 @@ func (pg *Generator) FromPodObjString(podObjString string) (string, error) {
647649

648650
return "", fmt.Errorf("K8s Object not one of supported types")
649651
}
652+
653+
func getServiceAccountName(spec v1.PodSpec) string {
654+
if spec.ServiceAccountName == "" {
655+
return "default"
656+
}
657+
658+
return spec.ServiceAccountName
659+
}

0 commit comments

Comments
 (0)