Skip to content

Commit 55a30ff

Browse files
superbrothersKaizhe
authored andcommitted
Add "secret" volume type if serviceaccount token is mounted
1 parent d26cd6c commit 55a30ff

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

advisor/processor/generate.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type Processor struct {
1818
k8sClient *kubernetes.Clientset
1919
resourceNamePrefix map[string]bool
2020
namespace string
21+
serviceAccountMap map[string]v1.ServiceAccount
2122
}
2223

2324
func NewProcessor(kubeconfig string) (*Processor, error) {
@@ -230,6 +231,13 @@ func (p *Processor) GetSecuritySpec() ([]types.ContainerSecuritySpec, []types.Po
230231
cssList := []types.ContainerSecuritySpec{}
231232
pssList := []types.PodSecuritySpec{}
232233

234+
// get and cache service account list in the specified namespace
235+
var err error
236+
p.serviceAccountMap, err = p.getServiceAccountMap()
237+
if err != nil {
238+
return cssList, pssList, err
239+
}
240+
233241
// get security spec from daemonsets
234242
cspList0, pspList0, err := p.getSecuritySpecFromDaemonSets()
235243

advisor/processor/get.go

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,19 @@ const (
2020
ReplicationController = "ReplicationController"
2121
Job = "Job"
2222
CronJob = "CronJob"
23+
24+
volumeTypeSecret = "secret"
2325
)
2426

25-
func getSecuritySpec(metadata types.Metadata, namespace string, spec v1.PodSpec) ([]types.ContainerSecuritySpec, types.PodSecuritySpec) {
27+
func getSecuritySpec(metadata types.Metadata, namespace string, spec v1.PodSpec, sa v1.ServiceAccount) ([]types.ContainerSecuritySpec, types.PodSecuritySpec) {
2628
cssList := []types.ContainerSecuritySpec{}
2729
podSecuritySpec := types.PodSecuritySpec{
2830
Metadata: metadata,
2931
Namespace: namespace,
3032
HostPID: spec.HostPID,
3133
HostNetwork: spec.HostNetwork,
3234
HostIPC: spec.HostIPC,
33-
VolumeTypes: getVolumeTypes(spec),
35+
VolumeTypes: getVolumeTypes(spec, sa),
3436
MountHostPaths: getVolumeHostPaths(spec),
3537
}
3638

@@ -71,10 +73,11 @@ func (p *Processor) getSecuritySpecFromDaemonSets() ([]types.ContainerSecuritySp
7173

7274
for _, ds := range daemonSetList.Items {
7375
p.resourceNamePrefix[ds.Name] = true
76+
sa := p.serviceAccountMap[ds.Spec.Template.Spec.ServiceAccountName]
7477
cspList2, podSecurityPosture := getSecuritySpec(types.Metadata{
7578
Name: ds.Name,
7679
Kind: DaemonSet,
77-
}, ds.Namespace, ds.Spec.Template.Spec)
80+
}, ds.Namespace, ds.Spec.Template.Spec, sa)
7881

7982
pspList = append(pspList, podSecurityPosture)
8083
cspList = append(cspList, cspList2...)
@@ -100,10 +103,11 @@ func (p *Processor) getSecuritySpecFromReplicaSets() ([]types.ContainerSecurityS
100103
}
101104

102105
p.resourceNamePrefix[rs.Name] = true
106+
sa := p.serviceAccountMap[rs.Spec.Template.Spec.ServiceAccountName]
103107
cspList2, psc := getSecuritySpec(types.Metadata{
104108
Name: rs.Name,
105109
Kind: ReplicaSet,
106-
}, rs.Namespace, rs.Spec.Template.Spec)
110+
}, rs.Namespace, rs.Spec.Template.Spec, sa)
107111

108112
pssList = append(pssList, psc)
109113
cssList = append(cssList, cspList2...)
@@ -125,10 +129,11 @@ func (p *Processor) getSecuritySpecFromStatefulSets() ([]types.ContainerSecurity
125129

126130
for _, sts := range statefulSetList.Items {
127131
p.resourceNamePrefix[sts.Name] = true
132+
sa := p.serviceAccountMap[sts.Spec.Template.Spec.ServiceAccountName]
128133
cspList2, pss := getSecuritySpec(types.Metadata{
129134
Name: sts.Name,
130135
Kind: StatefulSet,
131-
}, sts.Namespace, sts.Spec.Template.Spec)
136+
}, sts.Namespace, sts.Spec.Template.Spec, sa)
132137

133138
pssList = append(pssList, pss)
134139
cssList = append(cssList, cspList2...)
@@ -150,10 +155,11 @@ func (p *Processor) getSecuritySpecFromReplicationController() ([]types.Containe
150155

151156
for _, rc := range replicationControllerList.Items {
152157
p.resourceNamePrefix[rc.Name] = true
158+
sa := p.serviceAccountMap[rc.Spec.Template.Spec.ServiceAccountName]
153159
cspList2, pss := getSecuritySpec(types.Metadata{
154160
Name: rc.Name,
155161
Kind: ReplicationController,
156-
}, rc.Namespace, rc.Spec.Template.Spec)
162+
}, rc.Namespace, rc.Spec.Template.Spec, sa)
157163

158164
pssList = append(pssList, pss)
159165
cssList = append(cssList, cspList2...)
@@ -175,10 +181,11 @@ func (p *Processor) getSecuritySpecFromCronJobs() ([]types.ContainerSecuritySpec
175181

176182
for _, cronJob := range jobList.Items {
177183
p.resourceNamePrefix[cronJob.Name] = true
184+
sa := p.serviceAccountMap[cronJob.Spec.JobTemplate.Spec.Template.Spec.ServiceAccountName]
178185
cspList2, pss := getSecuritySpec(types.Metadata{
179186
Name: cronJob.Name,
180187
Kind: CronJob,
181-
}, cronJob.Namespace, cronJob.Spec.JobTemplate.Spec.Template.Spec)
188+
}, cronJob.Namespace, cronJob.Spec.JobTemplate.Spec.Template.Spec, sa)
182189

183190
pssList = append(pssList, pss)
184191
cssList = append(cssList, cspList2...)
@@ -204,10 +211,11 @@ func (p *Processor) getSecuritySpecFromJobs() ([]types.ContainerSecuritySpec, []
204211
}
205212

206213
p.resourceNamePrefix[job.Name] = true
214+
sa := p.serviceAccountMap[job.Spec.Template.Spec.ServiceAccountName]
207215
cspList2, pss := getSecuritySpec(types.Metadata{
208216
Name: job.Name,
209217
Kind: Job,
210-
}, job.Namespace, job.Spec.Template.Spec)
218+
}, job.Namespace, job.Spec.Template.Spec, sa)
211219

212220
pssList = append(pssList, pss)
213221
cssList = append(cssList, cspList2...)
@@ -229,10 +237,11 @@ func (p *Processor) getSecuritySpecFromDeployments() ([]types.ContainerSecurityS
229237

230238
for _, deploy := range deployments.Items {
231239
p.resourceNamePrefix[deploy.Name] = true
240+
sa := p.serviceAccountMap[deploy.Spec.Template.Spec.ServiceAccountName]
232241
cspList2, pss := getSecuritySpec(types.Metadata{
233242
Name: deploy.Name,
234243
Kind: Deployment,
235-
}, deploy.Namespace, deploy.Spec.Template.Spec)
244+
}, deploy.Namespace, deploy.Spec.Template.Spec, sa)
236245

237246
pssList = append(pssList, pss)
238247
cssList = append(cssList, cspList2...)
@@ -266,10 +275,11 @@ func (p *Processor) getSecuritySpecFromPods() ([]types.ContainerSecuritySpec, []
266275
continue
267276
}
268277

278+
sa := p.serviceAccountMap[pod.Spec.ServiceAccountName]
269279
cspList2, podSecurityPosture := getSecuritySpec(types.Metadata{
270280
Name: pod.Name,
271281
Kind: Pod,
272-
}, pod.Namespace, pod.Spec)
282+
}, pod.Namespace, pod.Spec, sa)
273283

274284
pssList = append(pssList, podSecurityPosture)
275285
cssList = append(cssList, cspList2...)
@@ -278,14 +288,35 @@ func (p *Processor) getSecuritySpecFromPods() ([]types.ContainerSecuritySpec, []
278288
return cssList, pssList, nil
279289
}
280290

281-
func getVolumeTypes(spec v1.PodSpec) (volumeTypes []string) {
291+
func (p *Processor) getServiceAccountMap() (map[string]v1.ServiceAccount, error) {
292+
serviceAccountMap := map[string]v1.ServiceAccount{}
293+
294+
serviceAccounts, err := p.k8sClient.CoreV1().ServiceAccounts(p.namespace).List(v12.ListOptions{})
295+
if err != nil {
296+
return serviceAccountMap, err
297+
}
298+
299+
for _, sa := range serviceAccounts.Items {
300+
serviceAccountMap[sa.Name] = sa
301+
}
302+
303+
return serviceAccountMap, nil
304+
}
305+
306+
func getVolumeTypes(spec v1.PodSpec, sa v1.ServiceAccount) (volumeTypes []string) {
282307
volumeTypeMap := map[string]bool{}
283308
for _, v := range spec.Volumes {
284309
if volumeType := getVolumeType(v); volumeType != "" {
285310
volumeTypeMap[getVolumeType(v)] = true
286311
}
287312
}
288313

314+
// If don't opt out of automounting API credentils for a service account
315+
// or a particular pod, "secret" needs to be into PSP allowed volume types.
316+
if mountServiceAccountToken(spec, sa) {
317+
volumeTypeMap[volumeTypeSecret] = true
318+
}
319+
289320
volumeTypes = utils.MapToArray(volumeTypeMap)
290321
return
291322
}
@@ -448,3 +479,17 @@ func getCapabilities(sc *v1.SecurityContext) (addList []string, dropList []strin
448479
}
449480
return
450481
}
482+
483+
func mountServiceAccountToken(spec v1.PodSpec, sa v1.ServiceAccount) bool {
484+
// First Pod's preference is checked
485+
if spec.AutomountServiceAccountToken != nil {
486+
return *spec.AutomountServiceAccountToken
487+
}
488+
489+
// Then service account's
490+
if sa.AutomountServiceAccountToken != nil {
491+
return *sa.AutomountServiceAccountToken
492+
}
493+
494+
return true
495+
}

0 commit comments

Comments
 (0)