Skip to content

Commit 31278aa

Browse files
Merge pull request step-security#2590 from vamshi-stepsecurity/feat/hardenrunner-runner-label
match group labels
2 parents 403fc4d + ab5d8a8 commit 31278aa

8 files changed

Lines changed: 131 additions & 13 deletions

File tree

remediation/workflow/hardenrunner/addaction.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,33 @@ type HardenRunnerConfig struct {
2424
}
2525

2626
// getJobRunsOnLabels extracts the runs-on labels from a job's yaml.Node.
27-
// Handles both scalar (runs-on: ubuntu-latest) and sequence (runs-on: [self-hosted, linux]) formats.
27+
// Handles scalar (runs-on: ubuntu-latest), sequence (runs-on: [self-hosted, linux]),
28+
// and mapping with labels key (runs-on: {labels: [self-hosted, linux]}) formats.
2829
func getJobRunsOnLabels(jobNode *yaml.Node) []string {
2930
for i := 0; i < len(jobNode.Content); i += 2 {
3031
keyNode := jobNode.Content[i]
3132
if keyNode.Value == "runs-on" && i+1 < len(jobNode.Content) {
32-
valNode := jobNode.Content[i+1]
33-
switch valNode.Kind {
34-
case yaml.ScalarNode:
35-
return []string{valNode.Value}
36-
case yaml.SequenceNode:
37-
var labels []string
38-
for _, item := range valNode.Content {
39-
labels = append(labels, item.Value)
40-
}
41-
return labels
33+
return extractLabels(jobNode.Content[i+1])
34+
}
35+
}
36+
return nil
37+
}
38+
39+
// extractLabels extracts labels from a yaml.Node that can be a scalar, sequence, or mapping with a "labels" key.
40+
func extractLabels(node *yaml.Node) []string {
41+
switch node.Kind {
42+
case yaml.ScalarNode:
43+
return []string{node.Value}
44+
case yaml.SequenceNode:
45+
var labels []string
46+
for _, item := range node.Content {
47+
labels = append(labels, item.Value)
48+
}
49+
return labels
50+
case yaml.MappingNode:
51+
for j := 0; j < len(node.Content); j += 2 {
52+
if node.Content[j].Value == "labels" && j+1 < len(node.Content) {
53+
return extractLabels(node.Content[j+1])
4254
}
4355
}
4456
}

remediation/workflow/hardenrunner/addaction_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,26 @@ func TestRunnerLabelFiltering(t *testing.T) {
209209
wantUpdated: true,
210210
outputFile: "labelScalar.yml",
211211
},
212+
{
213+
name: "both slices overlap",
214+
inputFile: "labelArray.yml",
215+
config: HardenRunnerConfig{
216+
SkipHardenRunner: true,
217+
RunnerLabels: []string{"windows-latest", "ubuntu-latest", "macos-latest"},
218+
},
219+
wantUpdated: true,
220+
outputFile: "labelArray.yml",
221+
},
222+
{
223+
name: "both slices no overlap",
224+
inputFile: "labelArray.yml",
225+
config: HardenRunnerConfig{
226+
SkipHardenRunner: true,
227+
RunnerLabels: []string{"windows-latest", "macos-latest"},
228+
},
229+
wantUpdated: false,
230+
unchanged: true,
231+
},
212232
{
213233
name: "multi-job mixed labels",
214234
inputFile: "labelMultiJob.yml",
@@ -219,6 +239,36 @@ func TestRunnerLabelFiltering(t *testing.T) {
219239
wantUpdated: true,
220240
outputFile: "labelMultiJob.yml",
221241
},
242+
{
243+
name: "mapping with labels array",
244+
inputFile: "labelMapping.yml",
245+
config: HardenRunnerConfig{
246+
SkipHardenRunner: true,
247+
RunnerLabels: []string{"ubuntu-latest"},
248+
},
249+
wantUpdated: true,
250+
outputFile: "labelMapping.yml",
251+
},
252+
{
253+
name: "mapping with labels scalar",
254+
inputFile: "labelMappingScalar.yml",
255+
config: HardenRunnerConfig{
256+
SkipHardenRunner: true,
257+
RunnerLabels: []string{"ubuntu-latest"},
258+
},
259+
wantUpdated: true,
260+
outputFile: "labelMappingScalar.yml",
261+
},
262+
{
263+
name: "mapping with labels no match",
264+
inputFile: "labelMapping.yml",
265+
config: HardenRunnerConfig{
266+
SkipHardenRunner: true,
267+
RunnerLabels: []string{"windows-latest"},
268+
},
269+
wantUpdated: false,
270+
unchanged: true,
271+
},
222272
}
223273

224274
for _, tt := range tests {

testfiles/addaction/input/labelArray.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ on:
33
push:
44
jobs:
55
build:
6-
runs-on: [self-hosted, linux, ubuntu-latest]
6+
# Run on self-hosted runners with ubuntu
7+
runs-on: [self-hosted, linux, ubuntu-latest] # custom runner pool
78
steps:
89
- uses: actions/checkout@v3
910
- run: echo "build"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: test-label-mapping
2+
on:
3+
push:
4+
jobs:
5+
build:
6+
runs-on:
7+
# Use specific runner labels
8+
labels: [self-hosted, linux, ubuntu-latest] # approved labels
9+
steps:
10+
- uses: actions/checkout@v3
11+
- run: echo "build"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: test-label-mapping-scalar
2+
on:
3+
push:
4+
jobs:
5+
build:
6+
runs-on:
7+
group: large-runners
8+
labels: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v3
11+
- run: echo "build"

testfiles/addaction/output/labelArray.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ on:
33
push:
44
jobs:
55
build:
6-
runs-on: [self-hosted, linux, ubuntu-latest]
6+
# Run on self-hosted runners with ubuntu
7+
runs-on: [self-hosted, linux, ubuntu-latest] # custom runner pool
78
steps:
89
- name: Harden the runner (Audit all outbound calls)
910
uses: step-security/harden-runner@v2
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: test-label-mapping
2+
on:
3+
push:
4+
jobs:
5+
build:
6+
runs-on:
7+
# Use specific runner labels
8+
labels: [self-hosted, linux, ubuntu-latest] # approved labels
9+
steps:
10+
- name: Harden the runner (Audit all outbound calls)
11+
uses: step-security/harden-runner@v2
12+
with:
13+
egress-policy: audit
14+
15+
- uses: actions/checkout@v3
16+
- run: echo "build"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: test-label-mapping-scalar
2+
on:
3+
push:
4+
jobs:
5+
build:
6+
runs-on:
7+
group: large-runners
8+
labels: ubuntu-latest
9+
steps:
10+
- name: Harden the runner (Audit all outbound calls)
11+
uses: step-security/harden-runner@v2
12+
with:
13+
egress-policy: audit
14+
15+
- uses: actions/checkout@v3
16+
- run: echo "build"

0 commit comments

Comments
 (0)