rules/AzureDevOps.Organization.Security.Policies.Rule.ps1
|
# Azure DevOps organization Security Policies rules # Synopsis: Debug rule to confirm target object type and properties Rule 'Azure.DevOps.Organization.Security.Policies.Debug' ` -Ref 'ADO-OSP-DEBUG' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -Tag @{ release = 'GA' } ` -Level Information { # Description: Verifies that the target object has the expected type and properties. Reason 'Debug rule failed to verify target object properties.' Recommend 'Ensure the input JSON contains the correct ObjectType and properties.' try { Write-Verbose "Debug: TargetObject Type: $($TargetObject.ObjectType)" Write-Verbose "Debug: TargetObject Properties: $($TargetObject | Get-Member -MemberType NoteProperty | ForEach-Object { $_.Name })" Write-Verbose "Debug: Raw Policy Values:" Write-Verbose " disallowSecureShell: $($TargetObject.'policy.disallowSecureShell')" Write-Verbose " allowRequestAccessToken: $($TargetObject.'policy.allowRequestAccessToken')" Write-Verbose " allowTeamAdminsInvitationsAccessToken: $($TargetObject.'policy.allowTeamAdminsInvitationsAccessToken')" Write-Verbose " allowFeedbackCollection: $($TargetObject.'policy.allowFeedbackCollection')" Write-Verbose " enforceAADConditionalAccess: $($TargetObject.'policy.enforceAADConditionalAccess')" Write-Verbose " disallowOAuthAuthentication: $($TargetObject.'policy.disallowOAuthAuthentication')" Write-Verbose " logAuditEvents: $($TargetObject.'policy.logAuditEvents')" Write-Verbose " artifactsExternalPackageProtectionToken: $($TargetObject.'policy.artifactsExternalPackageProtectionToken')" Write-Verbose " allowAnonymousAccess: $($TargetObject.'policy.allowAnonymousAccess')" Write-Verbose " disallowAadGuestUserAccess: $($TargetObject.'policy.disallowAadGuestUserAccess')" $Assert.Pass() } catch { Write-Error "Debug rule exception: $_" $Assert.Fail("Debug rule failed due to an exception.") } } # Synopsis: The target should satisfy its applicable organizational policy Rule 'Azure.DevOps.Organization.Security.Policies.DisallowSecureShell' ` -Ref 'ADO-OSP-001' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -If { (Get-AzDevOpsPolicyAssessment -TargetObject $TargetObject -RuleId 'Azure.DevOps.Organization.Security.Policies.DisallowSecureShell' -Policy $Configuration.assessmentPolicies.'Azure.DevOps.Organization.Security.Policies.DisallowSecureShell').Outcome -in @('Pass', 'Fail') } ` -Tag @{ release = 'GA'; assessment = 'Policy' } ` -Level Error { $assessment = Get-AzDevOpsPolicyAssessment -TargetObject $TargetObject -RuleId 'Azure.DevOps.Organization.Security.Policies.DisallowSecureShell' -Policy $Configuration.assessmentPolicies.'Azure.DevOps.Organization.Security.Policies.DisallowSecureShell' Reason $assessment.ReasonCode Recommend 'Apply the referenced organizational policy or collect the missing evidence.' $Assert.HasFieldValue($assessment, 'Outcome', 'Pass') } # Synopsis: Request access token should be disabled Rule 'Azure.DevOps.Organization.Security.Policies.DisallowRequestAccessToken' ` -Ref 'ADO-OSP-002' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -Tag @{ release = 'GA' } ` -Level Error { # Description: Disabling request access tokens prevents unauthorized access requests. Reason 'Request access token is not disabled.' Recommend 'Disable request access token in Azure DevOps organization security settings.' # Links: https://learn.microsoft.com/en-us/azure/devops/organizations/security/manage-personal-access-tokens try { Write-Verbose "Checking policy.allowRequestAccessToken: $($TargetObject.'policy.allowRequestAccessToken')" if ($TargetObject.'policy.allowRequestAccessToken' -eq $false) { $Assert.Pass() } else { $Assert.Fail('Request access token is not disabled.') } } catch { Write-Error "Rule ADO-OSP-002 exception: $_" $Assert.Fail("Rule failed due to an exception.") } } # Synopsis: Team admins should not manage invitations Rule 'Azure.DevOps.Organization.Security.Policies.DisallowTeamAdminsInvitations' ` -Ref 'ADO-OSP-003' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -Tag @{ release = 'GA' } ` -Level Error { # Description: Preventing team admins from managing invitations centralizes user management. Reason 'Team admins are allowed to manage invitations.' Recommend 'Disable team admin invitation management in Azure DevOps organization settings.' # Links: https://learn.microsoft.com/en-us/azure/devops/organizations/security/permissions try { Write-Verbose "Checking policy.allowTeamAdminsInvitationsAccessToken: $($TargetObject.'policy.allowTeamAdminsInvitationsAccessToken')" if ($TargetObject.'policy.allowTeamAdminsInvitationsAccessToken' -eq $false) { $Assert.Pass() } else { $Assert.Fail('Team admins are allowed to manage invitations.') } } catch { Write-Error "Rule ADO-OSP-003 exception: $_" $Assert.Fail("Rule failed due to an exception.") } } # Synopsis: Feedback collection should be disabled Rule 'Azure.DevOps.Organization.Security.Policies.DisallowFeedbackCollection' ` -Ref 'ADO-OSP-004' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -Tag @{ release = 'GA' } ` -Level Warning { # Description: Disabling feedback collection protects user privacy. Reason 'Feedback collection is not disabled.' Recommend 'Disable feedback collection in Azure DevOps organization settings.' # Links: https://learn.microsoft.com/en-us/azure/devops/organizations/settings/privacy try { Write-Verbose "Checking policy.allowFeedbackCollection: $($TargetObject.'policy.allowFeedbackCollection')" if ($TargetObject.'policy.allowFeedbackCollection' -eq $false) { $Assert.Pass() } else { $Assert.Fail('Feedback collection is not disabled.') } } catch { Write-Error "Rule ADO-OSP-004 exception: $_" $Assert.Fail("Rule failed due to an exception.") } } # Synopsis: Azure AD conditional access should be enforced Rule 'Azure.DevOps.Organization.Security.Policies.EnforceAADConditionalAccess' ` -Ref 'ADO-OSP-005' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -Tag @{ release = 'GA' } ` -Level Error { # Description: Enforcing Azure AD conditional access enhances security by requiring additional authentication checks. Reason 'Azure AD conditional access is not enforced.' Recommend 'Enable Azure AD conditional access in Azure DevOps organization settings.' # Links: https://learn.microsoft.com/en-us/azure/devops/organizations/security/conditional-access try { Write-Verbose "Checking policy.enforceAADConditionalAccess: $($TargetObject.'policy.enforceAADConditionalAccess')" if ($TargetObject.'policy.enforceAADConditionalAccess' -eq $true) { $Assert.Pass() } else { $Assert.Fail('Azure AD conditional access is not enforced.') } } catch { Write-Error "Rule ADO-OSP-005 exception: $_" $Assert.Fail("Rule failed due to an exception.") } } # Synopsis: The target should satisfy its applicable organizational policy Rule 'Azure.DevOps.Organization.Security.Policies.DisallowOAuthAuthentication' ` -Ref 'ADO-OSP-006' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -If { (Get-AzDevOpsPolicyAssessment -TargetObject $TargetObject -RuleId 'Azure.DevOps.Organization.Security.Policies.DisallowOAuthAuthentication' -Policy $Configuration.assessmentPolicies.'Azure.DevOps.Organization.Security.Policies.DisallowOAuthAuthentication').Outcome -in @('Pass', 'Fail') } ` -Tag @{ release = 'GA'; assessment = 'Policy' } ` -Level Error { $assessment = Get-AzDevOpsPolicyAssessment -TargetObject $TargetObject -RuleId 'Azure.DevOps.Organization.Security.Policies.DisallowOAuthAuthentication' -Policy $Configuration.assessmentPolicies.'Azure.DevOps.Organization.Security.Policies.DisallowOAuthAuthentication' Reason $assessment.ReasonCode Recommend 'Apply the referenced organizational policy or collect the missing evidence.' $Assert.HasFieldValue($assessment, 'Outcome', 'Pass') } # Synopsis: Audit event logging should be enabled Rule 'Azure.DevOps.Organization.Security.Policies.EnableLogAuditEvents' ` -Ref 'ADO-OSP-007' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -Tag @{ release = 'GA' } ` -Level Error { # Description: Enabling audit event logging ensures that all actions are tracked for security and compliance. Reason 'Audit event logging is not enabled.' Recommend 'Enable audit event logging in Azure DevOps organization settings.' # Links: https://learn.microsoft.com/en-us/azure/devops/organizations/audit/auditing try { Write-Verbose "Checking policy.logAuditEvents: $($TargetObject.'policy.logAuditEvents')" if ($TargetObject.'policy.logAuditEvents' -eq $true) { $Assert.Pass() } else { $Assert.Fail('Audit event logging is not enabled.') } } catch { Write-Error "Rule ADO-OSP-007 exception: $_" $Assert.Fail("Rule failed due to an exception.") } } # Synopsis: External package protection for artifacts should be enabled Rule 'Azure.DevOps.Organization.Security.Policies.EnableArtifactsProtection' ` -Ref 'ADO-OSP-008' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -Tag @{ release = 'GA' } ` -Level Error { # Description: Enabling external package protection ensures secure artifact management. Reason 'External package protection for artifacts is not enabled.' Recommend 'Enable external package protection in Azure DevOps organization settings.' # Links: https://learn.microsoft.com/en-us/azure/devops/artifacts/security try { Write-Verbose "Checking policy.artifactsExternalPackageProtectionToken: $($TargetObject.'policy.artifactsExternalPackageProtectionToken')" if ($TargetObject.'policy.artifactsExternalPackageProtectionToken' -eq $true) { $Assert.Pass() } else { $Assert.Fail('External package protection for artifacts is not enabled.') } } catch { Write-Error "Rule ADO-OSP-008 exception: $_" $Assert.Fail("Rule failed due to an exception.") } } # Synopsis: The target should satisfy its applicable organizational policy Rule 'Azure.DevOps.Organization.Security.Policies.DisallowAnonymousAccess' ` -Ref 'ADO-OSP-009' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -If { (Get-AzDevOpsPolicyAssessment -TargetObject $TargetObject -RuleId 'Azure.DevOps.Organization.Security.Policies.DisallowAnonymousAccess' -Policy $Configuration.assessmentPolicies.'Azure.DevOps.Organization.Security.Policies.DisallowAnonymousAccess').Outcome -in @('Pass', 'Fail') } ` -Tag @{ release = 'GA'; assessment = 'Policy' } ` -Level Error { $assessment = Get-AzDevOpsPolicyAssessment -TargetObject $TargetObject -RuleId 'Azure.DevOps.Organization.Security.Policies.DisallowAnonymousAccess' -Policy $Configuration.assessmentPolicies.'Azure.DevOps.Organization.Security.Policies.DisallowAnonymousAccess' Reason $assessment.ReasonCode Recommend 'Apply the referenced organizational policy or collect the missing evidence.' $Assert.HasFieldValue($assessment, 'Outcome', 'Pass') } # Synopsis: The target should satisfy its applicable organizational policy Rule 'Azure.DevOps.Organization.Security.Policies.DisallowAadGuestUserAccess' ` -Ref 'ADO-OSP-010' ` -Type 'Azure.DevOps.Organization.Security.Policies' ` -If { (Get-AzDevOpsPolicyAssessment -TargetObject $TargetObject -RuleId 'Azure.DevOps.Organization.Security.Policies.DisallowAadGuestUserAccess' -Policy $Configuration.assessmentPolicies.'Azure.DevOps.Organization.Security.Policies.DisallowAadGuestUserAccess').Outcome -in @('Pass', 'Fail') } ` -Tag @{ release = 'GA'; assessment = 'Policy' } ` -Level Error { $assessment = Get-AzDevOpsPolicyAssessment -TargetObject $TargetObject -RuleId 'Azure.DevOps.Organization.Security.Policies.DisallowAadGuestUserAccess' -Policy $Configuration.assessmentPolicies.'Azure.DevOps.Organization.Security.Policies.DisallowAadGuestUserAccess' Reason $assessment.ReasonCode Recommend 'Apply the referenced organizational policy or collect the missing evidence.' $Assert.HasFieldValue($assessment, 'Outcome', 'Pass') } |