rules/Azure.Deployment.Rule.ps1

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

#
# Validation rules for Azure deployments
#

#region Rules

# Synopsis: Avoid outputting sensitive deployment values.
Rule 'Azure.Deployment.OutputSecretValue' -Ref 'AZR-000279' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2022_06'; 'Azure.WAF/pillar' = 'Security'; } {
    $Assert.Create($PSRule.Issue.Get('PSRule.Rules.Azure.Template.OutputSecretValue'));
}

# Synopsis: Ensure all properties named used for setting a username within a deployment are expressions (e.g. an ARM function not a string)
Rule 'Azure.Deployment.AdminUsername' -Ref 'AZR-000284' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2022_09'; 'Azure.WAF/pillar' = 'Security'; } {
    RecurseDeploymentSensitive -Deployment $TargetObject
}

# Synopsis: Use secure parameters for any parameter that contains sensitive information.
Rule 'Azure.Deployment.SecureParameter' -Ref 'AZR-000408' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2023_12'; 'Azure.WAF/pillar' = 'Security'; } {
    GetSecureParameter -Deployment $TargetObject
}

# Synopsis: Use secure parameters for setting properties of resources that contain sensitive information.
Rule 'Azure.Deployment.SecureValue' -Ref 'AZR-000316' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
    RecurseSecureValue -Deployment $TargetObject
}

# Synopsis: Ensure Outer scope deployments aren't using SecureString or SecureObject Parameters
Rule 'Azure.Deployment.OuterSecret' -Ref 'AZR-000331' -Type 'Microsoft.Resources/deployments' -If { IsParentDeployment } -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
    $template = @($TargetObject.properties.template);
    if ($template.resources.Length -eq 0) {
        return $Assert.Pass();
    }

    $secureParameters = @($template.parameters.PSObject.properties | Where-Object {
            $_.Value.type -eq 'secureString' -or $_.Value.type -eq 'secureObject'
        } | ForEach-Object {
            $_.Name
        });
    foreach ($deployments in $template.resources) {
        if ($deployments.properties.expressionEvaluationOptions.scope -eq 'outer') {
            foreach ($outerDeployment in $deployments.properties.template.resources) {
                foreach ($property in $outerDeployment.properties) {
                    RecursivePropertiesSecretEvaluation -Resource $outerDeployment -SecureParameters $secureParameters -ShouldUseSecret $False -Property $property
                }
            }
        } else {
            $Assert.Pass()
        }
    }
}

#endregion Rules

#region Helpers

function global:GetSecureParameter {
    param (
        [Parameter(Mandatory = $True)]
        [PSObject]$Deployment
    )
    process {
        $count = 0;
        if ($Null -ne $Deployment.properties.template.parameters.PSObject.properties) {
            foreach ($parameter in $Deployment.properties.template.parameters.PSObject.properties.GetEnumerator()) {
                if (
                    $Assert.Like($parameter, 'Name', @(
                        '*password*'
                        '*secret*'
                        '*token*'
                        '*key'
                        '*keys'
                    )).Result -and
                    $parameter.Name -notLike '*publickey' -and
                    $parameter.Name -notLike '*publickeys' -and
                    $parameter.Name -notLike '*secretname*' -and
                    $parameter.Name -notLike '*secreturl*' -and
                    $parameter.Name -notLike '*secreturi*' -and
                    $parameter.Name -notLike '*secrettype*' -and
                    $parameter.Name -notLike '*secretrotation*' -and
                    $parameter.Name -notLike '*tokenname*' -and
                    $parameter.Name -notLike '*tokentype*' -and
                    $parameter.Name -notLike '*interval*' -and
                    $parameter.Name -notLike '*length*' -and
                    $parameter.Name -notLike '*secretprovider*' -and
                    $parameter.Name -notLike '*secretsprovider*' -and
                    $parameter.Name -notLike '*secretref*' -and
                    $parameter.Name -notLike '*secretid*' -and
                    $parameter.Name -notLike '*disablepassword*' -and
                    $parameter.Name -notLike '*sync*passwords*' -and
                    $parameter.Name -notLike '*keyvaultpath*' -and
                    $parameter.Name -notLike '*keyvaultname*' -and
                    $parameter.Name -notLike '*keyvaulturi*' -and
                    $Assert.NotIn($parameter, 'Name', $Configuration.GetStringValues('AZURE_DEPLOYMENT_NONSENSITIVE_PARAMETER_NAMES')).Result -and
                    $Null -ne $parameter.Value.type -and
                    $parameter.Value.type -ne 'bool' -and
                    $parameter.Value.type -ne 'int'
                ) {
                    $count++
                    $Assert.In($parameter.Value.type, '.', @('secureString', 'secureObject')).ReasonFrom($parameter.Name, $LocalizedData.InsecureParameterType, $parameter.Name, $parameter.Value.type);
                }
            }
        }
        if ($count -eq 0) {
            return $Assert.Pass();
        }
    }
}

function global:RecurseDeploymentSensitive {
    param (
        [Parameter(Mandatory = $True)]
        [PSObject]$Deployment
    )
    process {
        $propertyNames = $Configuration.GetStringValues('AZURE_DEPLOYMENT_SENSITIVE_PROPERTY_NAMES');
        $resources = @($Deployment.properties.template.resources);
        if ($resources.Length -eq 0) {
            return $Assert.Pass();
        }

        foreach ($resource in $resources) {
            if ($resource.type -eq 'Microsoft.Resources/deployments') {
                RecurseDeploymentSensitive -Deployment $resource;
            }
            else {
                foreach ($propertyName in $propertyNames) {
                    $found = $PSRule.GetPath($resource, "$..$propertyName");
                    if ($Null -eq $found -or $found.Length -eq 0) {
                        $Assert.Pass();
                    }
                    else {
                        Write-Debug "Found property name: $propertyName";
                        foreach ($value in $found) {
                            $Assert.Create(![PSRule.Rules.Azure.Runtime.Helper]::HasLiteralValue($value), $LocalizedData.LiteralSensitiveProperty, $propertyName);
                        }
                    }
                }
            }
        }
    }
}

function global:RecursivePropertiesSecretEvaluation {
    param (
        [Parameter(Mandatory = $True)]
        [PSObject]$Resource,

        [Parameter(Mandatory = $True)]
        [PSObject]$Property,

        [Parameter(Mandatory = $True)]
        [AllowEmptyCollection()]
        [PSObject]$SecureParameters,

        [Parameter(Mandatory = $False)]
        [Bool]$ShouldUseSecret = $True
    )
    process {
        $PropertyName = $Property.psObject.properties.Name 
        foreach ($NestedProperty in $Property.PSObject.Properties.Value.PSObject.Properties ) {
            if($NestedProperty.MemberType -eq 'NoteProperty'){
                RecursivePropertiesSecretEvaluation -Resource $Resource -SecureParameters $SecureParameters -Property $NestedProperty -ShouldUseSecret $ShouldUseSecret
            } else {
                CheckPropertyUsesSecureParameter -Resource $Resource -SecureParameters $SecureParameters -PropertyPath "properties.$($PropertyName)" -ShouldUseSecret $ShouldUseSecret
            }
        }
    }
}

function global:CheckPropertyUsesSecureParameter {
    param (
        [Parameter(Mandatory = $True)]
        [PSObject]$Resource,

        [Parameter(Mandatory = $True)]
        [AllowEmptyCollection()]
        [PSObject]$SecureParameters,

        [Parameter(Mandatory = $True)]
        [String]$PropertyPath,

        [Parameter(Mandatory = $False)]
        [Bool]$ShouldUseSecret = $True
    )
    process {
        $propertiesInPath = $PropertyPath.Split(".") # properties.example.name
        $propertyValue = $Resource
        foreach ($aPropertyInThePath in $propertiesInPath) {
            $propertyValue = $propertyValue."$aPropertyInThePath"
        }

        if ($propertyValue) {
            $hasSecureParam = [PSRule.Rules.Azure.Runtime.Helper]::HasSecureValue($propertyValue, $SecureParameters);
            $Assert.Create($hasSecureParam -eq $ShouldUseSecret, $LocalizedData.SecureParameterRequired, $PropertyPath);
        }
        else {
            $Assert.Pass();
        }
    }
}

# Check resource properties that should be set by secure parameters.
function global:RecurseSecureValue {
    param (
        [Parameter(Mandatory = $True)]
        [PSObject]$Deployment
    )
    process {
        $resources = @($Deployment.properties.template.resources);
        if ($resources.Length -eq 0) {
            return $Assert.Pass();
        }

        $secureParameters = @($Deployment.properties.template.parameters.PSObject.properties | Where-Object {
                $_.Value.type -eq 'secureString' -or $_.Value.type -eq 'secureObject'
            } | ForEach-Object {
                $_.Name
            });
        Write-Debug -Message "Secure parameters are: $($secureParameters -join ', ')";

        foreach ($resource in $resources) {
            switch ($resource.type) {
                'Microsoft.Resources/Deployments' { 
                    RecurseSecureValue -Deployment $resource;
                }
                'Microsoft.AAD/DomainServices' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.ldapsSettings.pfxCertificatePassword'
                }
                'Microsoft.ApiManagement/Service' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.hostnameConfigurations.certificatePassword'
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.certificates.certificatePassword'
                }
                'Microsoft.ApiManagement/Service/AuthorizationServers' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.clientSecret'
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.resourceOwnerPassword'
                }
                'Microsoft.ApiManagement/Service/Backends' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.proxy.password"
                }
                'Microsoft.ApiManagement/Service/Certificates' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                }
                'Microsoft.ApiManagement/Service/IdentityProviders' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.clientSecret"
                }
                'Microsoft.ApiManagement/Service/OpenidConnectProviders' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.clientSecret"
                }
                'Microsoft.ApiManagement/Service/Users' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                }
                'Microsoft.Automation/AutomationAccounts/Credentials' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                }
                'Microsoft.Batch/BatchAccounts/Pools' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.userAccounts.linuxUserConfiguration.sshPrivateKey"
                }
                'Microsoft.Blockchain/BlockchainMembers' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.consortiumManagementAccountPassword"
                }
                'Microsoft.Blockchain/BlockchainMembers/TransactionNodes' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                }
                'Microsoft.BotService/BotServices/Connections' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.clientSecret"
                }
                'Microsoft.Compute/VirtualMachineScaleSets' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.virtualMachineProfile.osProfile.adminPassword'
                }
                'Microsoft.Compute/VirtualMachineScaleSets/Virtualmachines' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.osProfile.adminPassword"
                }
                'Microsoft.Compute/VirtualMachines' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.osProfile.adminPassword'
                }
                'Microsoft.ContainerInstance/ContainerGroups' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.imageRegistryCredentials.password"
                }
                'Microsoft.ContainerService/ContainerServices' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.servicePrincipalProfile.secret"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.windowsProfile.adminPassword"
                }
                'Microsoft.ContainerService/ManagedClusters' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.windowsProfile.adminPassword'
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.servicePrincipalProfile.secret'
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.aadProfile.serverAppSecret'
                }
                'Microsoft.ContainerService/OpenShiftManagedClusters' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.authProfile.identityProviders.provider.secret'
                }
                'Microsoft.DBforMariaDB/Servers' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.administratorLoginPassword"
                }
                'Microsoft.DBforMySQL/Servers' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.administratorLoginPassword"
                }
                'Microsoft.DBforPostgreSQL/Servers' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.administratorLoginPassword"
                }
                'Microsoft.DataMigration/Services/Projects' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.sourceConnectionInfo.password"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.targetConnectionInfo.password"
                }
                'Microsoft.DevTestLab/Labs/Formulas' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.formulaContent.properties.password"
                }
                'Microsoft.DevTestLab/Labs/Users/Secrets' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.value"
                }
                'Microsoft.DevTestLab/Labs/Virtualmachines' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                }
                'Microsoft.HDInsight/Clusters' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.securityProfile.domainUserPassword"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.computeProfile.roles.osProfile.linuxOperatingSystemProfile.password"
                }
                'Microsoft.HDInsight/Clusters/Applications' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.computeProfile.roles.osProfile.linuxOperatingSystemProfile.password"
                }
                'Microsoft.KeyVault/Vaults/Secrets' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath 'properties.value'
                }
                'Microsoft.Logic/IntegrationAccounts/Agreements' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.content.x12.receiveAgreement.protocolSettings.securitySettings.passwordValue"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.content.x12.sendAgreement.protocolSettings.securitySettings.passwordValue"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.content.edifact.receiveAgreement.protocolSettings.envelopeSettings.recipientReferencePasswordValue"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.content.edifact.sendAgreement.protocolSettings.envelopeSettings.recipientReferencePasswordValue"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.content.edifact.receiveAgreement.protocolSettings.envelopeSettings.groupApplicationPassword"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.content.edifact.sendAgreement.protocolSettings.envelopeSettings.groupApplicationPassword"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.content.edifact.receiveAgreement.protocolSettings.envelopeOverrides.applicationPassword"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.content.edifact.sendAgreement.protocolSettings.envelopeOverrides.applicationPassword"
                }
                'Microsoft.NetApp/NetAppAccounts' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.activeDirectories.password"
                }
                'Microsoft.Network/ApplicationGateways' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.sslCertificates.properties.password"
                }
                'Microsoft.Network/Connections' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.virtualNetworkGateway1.properties.vpnClientConfiguration.radiusServerSecret"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.virtualNetworkGateway2.properties.vpnClientConfiguration.radiusServerSecret"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.sharedKey"
                }
                'Microsoft.Network/VirtualNetworkGateways' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.vpnClientConfiguration.radiusServerSecret"
                }
                'Microsoft.Network/VirtualWans/P2sVpnServerConfigurations' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.radiusServerSecret"
                }
                'Microsoft.Network/VpnServerConfigurations' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.radiusServerSecret"
                }
                'Microsoft.NotificationHubs/Namespaces/NotificationHubs' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.wnsCredential.properties.secretKey"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.admCredential.properties.clientSecret"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.baiduCredential.properties.baiduSecretKey"
                }
                'Microsoft.ServiceFabricMesh/Applications' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.services.properties.codePackages.imageRegistryCredential.password"
                }
                'Microsoft.ServiceFabricMesh/Secrets/Values' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.value"
                }
                'Microsoft.Sql/ManagedInstances' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.administratorLoginPassword"
                }
                'Microsoft.Sql/Servers' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.administratorLoginPassword"
                }
                'Microsoft.Sql/Servers/Databases/Extensions' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.administratorLoginPassword"
                }
                'Microsoft.Sql/Servers/Databases/SyncGroups' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.hubDatabasePassword"
                }
                'Microsoft.Sql/Servers/Databases/SyncGroups/SyncMembers' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                }
                'Microsoft.Sql/Servers/JobAgents/Credentials' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                }
                'Microsoft.SqlVirtualMachine/SqlVirtualMachines' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.wsfcDomainCredentials.clusterBootstrapAccountPassword"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.wsfcDomainCredentials.clusterOperatorAccountPassword"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.wsfcDomainCredentials.sqlServiceAccountPassword"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.autoBackupSettings.password"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.keyVaultCredentialSettings.servicePrincipalSecret"
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.serverConfigurationsManagementSettings.sqlConnectivityUpdateSettings.sqlAuthUpdatePassword"
                }
                'Microsoft.StorSimple/Managers/Devices/VolumeContainers' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.encryptionKey.value"
                }
                'Microsoft.StorSimple/Managers/StorageAccountCredentials' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.accessKey.value"
                }
                'Microsoft.StreamAnalytics/Streamingjobs' {
                    $objectsWithPasswords = $resource.properties.inputs + $resource.properties.outputs

                    foreach ($objectWithPassword in $objectsWithPasswords) {
                        CheckPropertyUsesSecureParameter -Resource $objectWithPassword -SecureParameters $secureParameters -PropertyPath "properties.datasource.properties.password"
                    }
                }
                'Microsoft.StreamAnalytics/Streamingjobs/Outputs' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.datasource.properties.password"
                }
                'Microsoft.Web/Certificates' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.password"
                }
                'Microsoft.Web/Sourcecontrols' {
                    CheckPropertyUsesSecureParameter -Resource $resource -SecureParameters $secureParameters -PropertyPath "properties.tokenSecret"
                }
                Default {
                    $Assert.Pass();
                }
            }
        }
    }
}


# Check if the TargetObject is a parent deployment, with scoped deployments or a rendered deployment
function global:IsParentDeployment {
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    param ()
    process {
        foreach ($deployment in $TargetObject.properties.template.resources){
            return $Assert.HasField($deployment, 'properties.expressionEvaluationOptions.scope').Result;
        }
    }
}

#endregion Helpers

# SIG # Begin signature block
# MIIoKQYJKoZIhvcNAQcCoIIoGjCCKBYCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAEWKmiSZuA9Ol0
# Z1zraeIfx6RWcNNxQXRNBho3/rhBWKCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
# /Xmfwb1tbWrJUnMTDXpQzTGCGgkwghoFAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIJAxuLUdh3ZBirJ2Bm6ffTZm
# 8eTuraOQUJr0cgAUgWFVMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
# BQAEggEADVO4JQBzEYaObRxVJlx4hZ8X/bjMgu+OhNVtchx9J5DyGN1vOqH+efbf
# KzzlVWNTaO2D5Qocl3aWTZG8pASZ5Riw8PUKMUgn/NFT4HdOm0Hcs6sxT6eVzcq9
# qMnuxOisdeUjS4R88hgTZ/XCOlk8g2zsf/HyQ6Df2+Xm1OH/IegqABv3ZVgbZfl4
# S7JQDMx+OetDRz0aDVTy+lVhotgLSAK6JhAkUXVtwhV6fJD+drWPFEZibVAazOW3
# 4E18ag0CcBdKiOVMSlF8Gciv4AAQZ4eDK/of+iuPFf71Jkl+y5nU82ML6e2lGXq2
# bUmETWCZktfkt6PrsK2DUL1gAYGYvaGCF5MwghePBgorBgEEAYI3AwMBMYIXfzCC
# F3sGCSqGSIb3DQEHAqCCF2wwghdoAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFRBgsq
# hkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
# AwQCAQUABCBBLjV8uydCkkqKh0Xzjb1y8B1jEhTxq+JfLGAnTz1XsgIGZwfy+FyX
# GBIyMDI0MTAxOTEwNDgwMi45NVowBIACAfSggdGkgc4wgcsxCzAJBgNVBAYTAlVT
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy
# aWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo4OTAwLTA1
# RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCC
# EeowggcgMIIFCKADAgECAhMzAAAB7eFfy9X3pV1zAAEAAAHtMA0GCSqGSIb3DQEB
# CwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV
# BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTIzMTIwNjE4NDU0
# MVoXDTI1MDMwNTE4NDU0MVowgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMx
# JzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo4OTAwLTA1RTAtRDk0NzElMCMGA1UE
# AxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEB
# BQADggIPADCCAgoCggIBAKgwwmySuupqnJwvE8LUfvMPuDzw2lsRpDpKNxMhFvMJ
# XJhA2zPxNovWmoVMQA8vVfuiMvj8RoRb5SM2pmz9rIzJbhgikU9k/bHgUExUJ12x
# 4XaL5owyMMeLQtxNBnEzazeYUysJkBZJ8thdgMiKYUHPyPSgtYbLdWAuYFMozjEu
# q/sNlTPwHZKgCZsS2nraeBKXSE6g3vdIXAT5jbhK8ZAxaHKSkb69cPByla/AN75O
# CestHsBNEVc3klLbp2bbLLpJgUxFicwTd0wcJD9RAhBA0LycuYi90qQChYQxe0mw
# YSjdCszZLZIG/g+kdHNG6TNO0/5QBx4bEz0nKvBRA/k4ISZbphyETJENLA/iFT1/
# sHQDKHXg/D28mjuN7A2N4w8iSad7ItKLSu6/ajH/FEa1wn3IE0LkFpGS2PPuy09q
# iNH48MDZ+4G0KjzEqWS3neZRvsBj4JkceqEubvql0wXoEe/ZO/CVUF5BE3bZeNpV
# VHAKCOAmc17C3s96NyulSfSocuAur7UE3UPNi6RaROvvBPTOXSJev422pSRZI6dZ
# F97w3bW0Hq6/dWRbycV0KG1ttlnPbil4u0kRm42s3xd/09M8zNlcMkEjURyJH/3V
# BwahkWZVsVVvatQgCzTX5mR7C9uGYZUN59f2hkbj8riAZSxO9Nb6vUlkzFRPYzCp
# AgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUzhvw7PfeECoER8qUBl/Q0qHgIhkwHwYD
# VR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZO
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIw
# VGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBc
# BggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0
# cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYD
# VR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMC
# B4AwDQYJKoZIhvcNAQELBQADggIBAJ3WArZF354YvR4eL6ITr+oNjyxtuw7h6Zqd
# ynoo837GrlkBq2IFHiOZFGGb71WKTQWjQMtaL83bxsUjt1djDT2ne8KKluPLgSiJ
# +bQ253v/hTfSL37tG9btc5DevHfv5Tu+r2WTrJikYI2nSOUnXzz8K5E+Comd+rkR
# 15p8fYCgbjqEpZN4HsO5dqwa3qykk56cZ51Kt7fgxZmp5MhDSto4i1mcW4YPLj7G
# gPWpHPZBb67aAIdobwBCOFhQzi5OL23qS22PpztdqavbOta5x4OHPuwou20tMnvC
# zlisDYjxxOVswB/YpbQZWMptgZ34tkZ24Qrv/t+zgZSQypznUWw10bWf7OBzvMe7
# agYZ4IGDizxlHRkXLHuOyCb2xIUIpDkKxsC+Wv/rQ12TlN4xHwmzaQ1SJy7YKpnT
# fzfdOy9OCTuIPUouB9LXocS+M3qbhUokqCMns4knNpu1LglCBScmshl/KiyTgPXy
# tmeL2lTA3TdaBOZ3XRZPCJk67iDxSfqIpw8xj+IWpO7ie2TMVTEEGlsUbqTUIg1m
# aiKsRaYK0beXJnYh12aO0h59OQi8ZZvgnHPPuXab8TaQY6LEMkexqFlWbCyg2+HL
# mS7+KdT751cfPD6GW+pNIVPz2sgVWFyaxY8Mk81FJKkyGgnfdXZlr+WQpxuRQzRJ
# tCBL2qx3MIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG
# 9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
# BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEy
# MDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw
# MTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJV
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt
# ZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
# AOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az
# /1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V2
# 9YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oa
# ezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkN
# yjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7K
# MtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRf
# NN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SU
# HDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoY
# WmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5
# C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8
# FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TAS
# BgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1
# Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUw
# UzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNy
# b3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoG
# CCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIB
# hjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fO
# mhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9w
# a2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggr
# BgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNv
# bS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3
# DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEz
# tTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJW
# AAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G
# 82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/Aye
# ixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI9
# 5ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1j
# dEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZ
# KCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xB
# Zj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuP
# Ntq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvp
# e784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCA00w
# ggI1AgEBMIH5oYHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScw
# JQYDVQQLEx5uU2hpZWxkIFRTUyBFU046ODkwMC0wNUUwLUQ5NDcxJTAjBgNVBAMT
# HE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAO4d
# rIpMJpixjEmH6hZPHq5U8XD5oIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# UENBIDIwMTAwDQYJKoZIhvcNAQELBQACBQDqvaVlMCIYDzIwMjQxMDE5MDMyNjI5
# WhgPMjAyNDEwMjAwMzI2MjlaMHQwOgYKKwYBBAGEWQoEATEsMCowCgIFAOq9pWUC
# AQAwBwIBAAICDnIwBwIBAAICEzMwCgIFAOq+9uUCAQAwNgYKKwYBBAGEWQoEAjEo
# MCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG
# 9w0BAQsFAAOCAQEAu/W9eeCeaKNlCzB+g4fKuzzSBBFCRdnVs+edMR2NR+5gBv5F
# fLbNOvrDIR5DL8yPV7znazV0WVbVuBQ4puHTXBuQK+j6PezybEjEWjFRq/9A3z0x
# 9xpYFbp3Uf1mG8EuX+fe5pBb4NbWm78M5l8Ps6fs5dX5eMRmLw8rcWIHcSoNv7sN
# X0Cp+O+lj8PPxrD23nzIrEp17UPBaYlWbpBjDXfnjRvmTlmgAmYBrwyXYvBvFIaw
# 58lXA168020lrPfCO8QrGTqjkRKBGZfKZ9S2cBEO2a+1bBrnJLAsxgPQeAbTtDDE
# w3EcWaecxUz8ri3ruND7RxdMHD3NxYFlJREHZTGCBA0wggQJAgEBMIGTMHwxCzAJ
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv
# c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB7eFfy9X3pV1zAAEAAAHtMA0G
# CWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJ
# KoZIhvcNAQkEMSIEIFxNWEyvCpZh3aqJKO2GB+xEZlvFEUU95LhBBqtVcWefMIH6
# BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQgjS4NaDQIWx4rErcDXqXXCsjCuxIO
# tdnrFJ/QXjFsyjkwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx
# MAITMwAAAe3hX8vV96VdcwABAAAB7TAiBCB0okIVX5veT/qs9iYybqjLGnxt8Oma
# sXNN4VXc9VUWUTANBgkqhkiG9w0BAQsFAASCAgAyMij5MsnjMKQqALvqPMkJ+iIe
# 1Qr8wLkb57PB00W2o2Wq4wXEv4tJSyZLbo7EyXqNtt6oKQCYzgo7IxcEgsaw/XvJ
# E/RuiYT/YcttU0im+BzhL3IomxCFkGxUxEA0DIML/+CNcfPSOqibYup6mECfA3BP
# WoAflvofhNqefoSJFVAMQESIHiL0DuYOPT0XNCSxhLiVDZKuw3NpbYfeMd3pOHbF
# 1nXE8KKTfKxEzzN0Bu8ETPXVeP4MjTJt9hK0wUi/ceiGHaBjCfXAevjd5bq3yIrq
# y6O20brxzXj0faEZxi/Bbgn/5iW5FuKDkJOiCjWO2WXECj+eWyvFmAnN1d0XXKFZ
# yORRYt7PMLgl1VtOaR9VmPOZy4M9/UM8LGss4qv48ZFVbPenl7LJhk3JhRv43D2P
# 2ff/uVfpSR1KximoroegqRcdirOLCvASK+oZUCAQ3eUu8OFwJ6arYbSIkiBA8cY3
# suuLC5cUmkp9nD7V3zxiaLsqpR9ccai5xuSjW9AzI72kYXWskD/Dfcq/iPlgbP7w
# FAQYHf9w+ivZKJNmSb0leLqZQUgQPXT/qWoKyk159SN8B0shYG1r43cxeqwfYVAU
# dEU4kfuqeFajoq+YfXYASHpL+WkkBCYdeuDWb5/+yLsRoRMPG+aOo4s5C/8qaTF2
# r+LlxvnWJ4+KVAfOGQ==
# SIG # End signature block