microsoft/hve-core

Public

mirrored fromhttps://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
fix/dependabot-uuid-postcss-overrides

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/tests/security/Test-WorkflowPermissions.Tests.ps1

279lines · modecode

1#Requires -Modules Pester
2
3# Copyright (c) Microsoft Corporation.
4# SPDX-License-Identifier: MIT
5
6using module ../../security/Modules/SecurityClasses.psm1
7
8BeforeAll {
9 $scriptPath = Join-Path $PSScriptRoot '../../security/Test-WorkflowPermissions.ps1'
10 . $scriptPath
11
12 Import-Module (Join-Path $PSScriptRoot '../Mocks/GitMocks.psm1') -Force
13 Save-CIEnvironment
14
15 $script:FixturesPath = Join-Path $PSScriptRoot '../Fixtures/Workflows'
16}
17
18AfterAll {
19 Restore-CIEnvironment
20 Remove-Module CIHelpers -Force -ErrorAction SilentlyContinue
21 Remove-Module SecurityHelpers -Force -ErrorAction SilentlyContinue
22}
23
24Describe 'Write-SecurityLog integration' -Tag 'Unit' {
25 BeforeAll {
26 Mock Write-Host { }
27 }
28
29 It 'Should not throw for Info level' {
30 { Write-SecurityLog -Message 'Test info' -Level Info } | Should -Not -Throw
31 }
32
33 It 'Should not throw for Warning level' {
34 { Write-SecurityLog -Message 'Test warning' -Level Warning } | Should -Not -Throw
35 }
36
37 It 'Should not throw for Error level' {
38 { Write-SecurityLog -Message 'Test error' -Level Error } | Should -Not -Throw
39 }
40
41 It 'Should not throw for Success level' {
42 { Write-SecurityLog -Message 'Test success' -Level Success } | Should -Not -Throw
43 }
44}
45
46Describe 'Test-WorkflowPermissions' -Tag 'Unit' {
47 Context 'File with top-level permissions block' {
48 It 'Should return null for workflow with permissions' {
49 $testPath = Join-Path $TestDrive 'with-permissions'
50 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
51 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-with-permissions.yml') -Destination $testPath
52
53 $filePath = Join-Path $testPath 'workflow-with-permissions.yml'
54 $result = Test-WorkflowPermissions -FilePath $filePath
55
56 $result | Should -BeNullOrEmpty
57 }
58 }
59
60 Context 'File with empty permissions block' {
61 It 'Should return null for workflow with empty permissions' {
62 $testPath = Join-Path $TestDrive 'empty-permissions'
63 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
64 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-empty-permissions.yml') -Destination $testPath
65
66 $filePath = Join-Path $testPath 'workflow-empty-permissions.yml'
67 $result = Test-WorkflowPermissions -FilePath $filePath
68
69 $result | Should -BeNullOrEmpty
70 }
71 }
72
73 Context 'File without permissions block' {
74 It 'Should return a violation' {
75 $testPath = Join-Path $TestDrive 'without-permissions'
76 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
77 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
78
79 $filePath = Join-Path $testPath 'workflow-without-permissions.yml'
80 $result = Test-WorkflowPermissions -FilePath $filePath
81
82 $result | Should -Not -BeNullOrEmpty
83 }
84
85 It 'Should set ViolationType to MissingPermissions' {
86 $testPath = Join-Path $TestDrive 'without-permissions-type'
87 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
88 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
89
90 $filePath = Join-Path $testPath 'workflow-without-permissions.yml'
91 $result = Test-WorkflowPermissions -FilePath $filePath
92
93 $result.ViolationType | Should -Be 'MissingPermissions'
94 }
95
96 It 'Should set Severity to High' {
97 $testPath = Join-Path $TestDrive 'without-permissions-sev'
98 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
99 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
100
101 $filePath = Join-Path $testPath 'workflow-without-permissions.yml'
102 $result = Test-WorkflowPermissions -FilePath $filePath
103
104 $result.Severity | Should -Be 'High'
105 }
106
107 It 'Should set Type to workflow-permissions' {
108 $testPath = Join-Path $TestDrive 'without-permissions-wftype'
109 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
110 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
111
112 $filePath = Join-Path $testPath 'workflow-without-permissions.yml'
113 $result = Test-WorkflowPermissions -FilePath $filePath
114
115 $result.Type | Should -Be 'workflow-permissions'
116 }
117
118 It 'Should set Line to 0 for file-level violation' {
119 $testPath = Join-Path $TestDrive 'without-permissions-line'
120 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
121 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
122
123 $filePath = Join-Path $testPath 'workflow-without-permissions.yml'
124 $result = Test-WorkflowPermissions -FilePath $filePath
125
126 $result.Line | Should -Be 0
127 }
128
129 It 'Should include FullPath in Metadata' {
130 $testPath = Join-Path $TestDrive 'without-permissions-meta'
131 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
132 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
133
134 $filePath = Join-Path $testPath 'workflow-without-permissions.yml'
135 $result = Test-WorkflowPermissions -FilePath $filePath
136
137 $result.Metadata.FullPath | Should -Be $filePath
138 }
139 }
140}
141
142Describe 'ConvertTo-PermissionsSarif' -Tag 'Unit' {
143 Context 'With violations' {
144 It 'Should produce valid SARIF structure' {
145 $violation = [DependencyViolation]::new()
146 $violation.File = 'test.yml'
147 $violation.Line = 0
148 $violation.Type = 'workflow-permissions'
149 $violation.Name = 'test.yml'
150 $violation.Severity = 'High'
151 $violation.ViolationType = 'MissingPermissions'
152 $violation.Description = 'Missing top-level permissions'
153 $violation.Remediation = 'Add permissions block'
154
155 $sarif = ConvertTo-PermissionsSarif -Violations @($violation)
156
157 $sarif.'$schema' | Should -Not -BeNullOrEmpty
158 $sarif.version | Should -Be '2.1.0'
159 $sarif.runs | Should -HaveCount 1
160 $sarif.runs[0].tool.driver.name | Should -Be 'Test-WorkflowPermissions'
161 }
162
163 It 'Should include missing-permissions rule' {
164 $violation = [DependencyViolation]::new()
165 $violation.File = 'test.yml'
166 $violation.Line = 0
167 $violation.Type = 'workflow-permissions'
168 $violation.Name = 'test.yml'
169 $violation.Severity = 'High'
170 $violation.ViolationType = 'MissingPermissions'
171 $violation.Description = 'Missing top-level permissions'
172 $violation.Remediation = 'Add permissions block'
173
174 $sarif = ConvertTo-PermissionsSarif -Violations @($violation)
175
176 $sarif.runs[0].tool.driver.rules[0].id | Should -Be 'missing-permissions'
177 $sarif.runs[0].results | Should -HaveCount 1
178 }
179 }
180
181 Context 'Without violations' {
182 It 'Should produce valid SARIF with empty results' {
183 $sarif = ConvertTo-PermissionsSarif -Violations @()
184
185 $sarif.version | Should -Be '2.1.0'
186 $sarif.runs[0].results | Should -HaveCount 0
187 }
188 }
189}
190
191Describe 'Invoke-WorkflowPermissionsCheck' -Tag 'Integration' {
192 BeforeAll {
193 Mock Write-CIAnnotation { } -ModuleName CIHelpers
194 Mock Write-Host { }
195 }
196
197 Context 'Scanning directory with mixed workflows' {
198 It 'Should detect missing permissions' {
199 $testPath = Join-Path $TestDrive 'mixed-scan'
200 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
201 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-with-permissions.yml') -Destination $testPath
202 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
203
204 $outputPath = Join-Path $TestDrive 'mixed-results.json'
205
206 $exitCode = Invoke-WorkflowPermissionsCheck -Path $testPath -OutputPath $outputPath
207
208 $exitCode | Should -Be 0
209 Test-Path $outputPath | Should -BeTrue
210 }
211
212 It 'Should fail with FailOnViolation when violations exist' {
213 $testPath = Join-Path $TestDrive 'fail-scan'
214 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
215 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
216
217 $outputPath = Join-Path $TestDrive 'fail-results.json'
218
219 $exitCode = Invoke-WorkflowPermissionsCheck -Path $testPath -OutputPath $outputPath -FailOnViolation
220
221 $exitCode | Should -Be 1
222 }
223
224 It 'Should return exit code 0 when all workflows have permissions' {
225 $testPath = Join-Path $TestDrive 'pass-scan'
226 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
227 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-with-permissions.yml') -Destination $testPath
228
229 $outputPath = Join-Path $TestDrive 'pass-results.json'
230
231 $exitCode = Invoke-WorkflowPermissionsCheck -Path $testPath -OutputPath $outputPath -FailOnViolation
232
233 $exitCode | Should -Be 0
234 }
235 }
236
237 Context 'Exclusion filtering' {
238 It 'Should exclude specified files' {
239 $testPath = Join-Path $TestDrive 'exclude-scan'
240 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
241 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
242
243 $outputPath = Join-Path $TestDrive 'exclude-results.json'
244
245 $exitCode = Invoke-WorkflowPermissionsCheck -Path $testPath -OutputPath $outputPath -ExcludePaths 'workflow-without-permissions.yml' -FailOnViolation
246
247 $exitCode | Should -Be 0
248 }
249 }
250
251 Context 'Output formats' {
252 It 'Should produce SARIF output' {
253 $testPath = Join-Path $TestDrive 'sarif-scan'
254 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
255 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-without-permissions.yml') -Destination $testPath
256
257 $outputPath = Join-Path $TestDrive 'sarif-results.json'
258
259 Invoke-WorkflowPermissionsCheck -Path $testPath -Format sarif -OutputPath $outputPath
260
261 $content = Get-Content $outputPath -Raw | ConvertFrom-Json
262 $content.version | Should -Be '2.1.0'
263 $content.'$schema' | Should -Not -BeNullOrEmpty
264 }
265
266 It 'Should produce JSON output by default' {
267 $testPath = Join-Path $TestDrive 'json-scan'
268 New-Item -ItemType Directory -Path $testPath -Force | Out-Null
269 Copy-Item -Path (Join-Path $script:FixturesPath 'workflow-with-permissions.yml') -Destination $testPath
270
271 $outputPath = Join-Path $TestDrive 'json-results.json'
272
273 Invoke-WorkflowPermissionsCheck -Path $testPath -OutputPath $outputPath
274
275 $content = Get-Content $outputPath -Raw | ConvertFrom-Json
276 $content.ScanPath | Should -Not -BeNullOrEmpty
277 }
278 }
279}
280