Skip to content

Commit 3fd24d1

Browse files
committed
Add SAST Kubesec scanner workflow and related manifests
1 parent 2c0a30e commit 3fd24d1

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed

.github/workflows/SAST-Kubesec.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# https://kubesec.io/
2+
# https://github.com/controlplaneio/kubesec
3+
# https://github.com/controlplaneio/kubesec-action
4+
5+
name: SAST Kubesec Scanner
6+
7+
on:
8+
push:
9+
branches: [main]
10+
pull_request:
11+
branches: [main]
12+
schedule:
13+
- cron: '18 8 * * 6'
14+
15+
permissions:
16+
contents: read # for actions/checkout to fetch code
17+
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
18+
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
19+
20+
jobs:
21+
kubesec-scan:
22+
name: Kubesec Scan
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@v4
27+
28+
- name: Run kubesec scanner (critical-double.yaml)
29+
uses: controlplaneio/kubesec-action@43d0ddff5ffee89a6bb9f29b64cd865411137b14
30+
with:
31+
input: manifests/critical-double.yaml # specify configuration file to scan here
32+
format: template
33+
template: manifests/sarif.tpl
34+
output: kubesec-results.sarif
35+
exit-code: "0"
36+
37+
- name: Upload Kubesec scan results to GitHub Security tab
38+
uses: github/codeql-action/upload-sarif@v3
39+
with:
40+
sarif_file: kubesec-results.sarif
41+
42+
- name: Run kubesec scanner (score-5-pod-serviceaccount.yaml)
43+
uses: controlplaneio/kubesec-action@43d0ddff5ffee89a6bb9f29b64cd865411137b14
44+
with:
45+
input: manifests/score-5-pod-serviceaccount.yaml # specify configuration file to scan here
46+
format: template
47+
template: manifests/sarif.tpl
48+
output: kubesec-results.sarif
49+
exit-code: "0"
50+
51+
- name: Upload Kubesec scan results to GitHub Security tab
52+
uses: github/codeql-action/upload-sarif@v3
53+
with:
54+
sarif_file: kubesec-results.sarif

manifests/critical-double.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: kubesec-test
5+
spec:
6+
containers:
7+
- name: kubesec-demo
8+
image: gcr.io/google-samples/node-hello:1.0
9+
securityContext:
10+
allowPrivilegeEscalation: true
11+
privileged: true

manifests/sarif.tpl

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
{
2+
"$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
3+
"version": "2.1.0",
4+
"runs": [
5+
{{- $run_first := true }}
6+
{{- range $report_index, $report := . }}
7+
{{- if and $report.Valid (not (eq $report.Message "This resource kind is not supported by kubesec")) -}}
8+
{{- if $run_first -}}
9+
{{- $run_first = false -}}
10+
{{ else -}}
11+
,
12+
{{- end }}
13+
{
14+
"tool": {
15+
"driver": {
16+
"name": "Kubesec",
17+
"fullName": "Kubesec Kubernetes Resource Security Policy Validator",
18+
"rules": [
19+
{{- $rule_first := true }}
20+
{{- range .Rules }}
21+
{{- if $rule_first -}}
22+
{{- $rule_first = false -}}
23+
{{ else -}}
24+
,
25+
{{- end }}
26+
{
27+
"id": "{{ .ID }}",
28+
"shortDescription": {
29+
"text": "{{ .Reason }}"
30+
},
31+
"helpUri": "https://github.com/controlplaneio/kubesec",
32+
"help": {
33+
"text": "- Reason: {{ .Reason }}\n- Selector: {{ escapeString .Selector }}\n- Score: {{ .Points }}"
34+
},
35+
"messageStrings": {
36+
"selector": {
37+
"text": {{ escapeString .Selector | printf "%q" }}
38+
}
39+
},
40+
"properties": {
41+
"points": "{{ .Points }}",
42+
{{- if lt .Points 0 -}}
43+
"security-severity": "9.0"
44+
{{ else -}}
45+
"security-severity": "5.0"
46+
{{- end }}
47+
}
48+
}
49+
{{- end -}}
50+
]
51+
}
52+
},
53+
"results": [
54+
{{- $result_first := true }}
55+
{{- range $result_index, $res := joinSlices .Scoring.Advise .Scoring.Critical -}}
56+
{{- if $result_first -}}
57+
{{- $result_first = false -}}
58+
{{ else -}}
59+
,
60+
{{- end }}
61+
{
62+
"ruleId": "{{ $res.ID }}",
63+
{{- if lt $res.Points 0 -}}
64+
"level": "error",
65+
{{ else -}}
66+
"level": "warning",
67+
{{- end }}
68+
"message": {
69+
"text": {{ endWithPeriod $res.Reason | printf "%q" }},
70+
"properties": {
71+
"score": "{{ $res.Points }}",
72+
"selector": {{ escapeString $res.Selector | printf "%q" }}
73+
}
74+
},
75+
"locations": [
76+
{
77+
"physicalLocation": {
78+
"artifactLocation": {
79+
"uri": "{{ $report.FileName }}"
80+
},
81+
"region": {
82+
"startLine": 1,
83+
"endLine": 1
84+
}
85+
}
86+
}
87+
],
88+
"partialFingerprints": {
89+
"primaryLocationLineHash": "hash-{{ $report.FileName }}"
90+
}
91+
}
92+
{{- end -}}
93+
],
94+
"columnKind": "utf16CodeUnits"
95+
}
96+
{{- end -}}
97+
{{- end }}
98+
]
99+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: my-pod
5+
spec:
6+
serviceAccountName: build-robot
7+
automountServiceAccountToken: false
8+
containers:
9+
- name: nginx
10+
image: nginx
11+
securityContext:
12+
runAsNonRoot: true
13+
readOnlyRootFilesystem: true
14+
ports:
15+
- containerPort: 80

0 commit comments

Comments
 (0)