rules/Azure.Storage.Rule.ps1
# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # # Validation rules for Azure Storage Accounts # # Synopsis: Storage Accounts not using geo-replicated storage (GRS) or zone-redundant (ZRS) may be at risk. Rule 'Azure.Storage.UseReplication' -Ref 'AZR-000195' -Type 'Microsoft.Storage/storageAccounts' -If { (ShouldStorageReplicate) } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Reliability'; } { $Assert.In($TargetObject, 'sku.name', @( 'Standard_GRS' 'Standard_RAGRS' 'Standard_GZRS' 'Standard_RAGZRS' 'Premium_ZRS' 'Standard_GZRS' 'Standard_RAGZRS' 'Standard_ZRS' )); } # Synopsis: Enable soft delete on Storage Accounts Rule 'Azure.Storage.SoftDelete' -Ref 'AZR-000197' -Type 'Microsoft.Storage/storageAccounts', 'Microsoft.Storage/storageAccounts/blobServices' -If { !(IsCloudShell) -and !(IsHnsStorage) -and !(IsFileStorage) } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Reliability'; } { $services = @($TargetObject); if ($PSRule.TargetType -eq 'Microsoft.Storage/storageAccounts') { $services = @(GetSubResources -ResourceType 'Microsoft.Storage/storageAccounts/blobServices'); } if ($services.Length -eq 0) { return $Assert.Fail($LocalizedData.SubResourceNotFound, 'Microsoft.Storage/storageAccounts/blobServices'); } foreach ($service in $services) { $Assert.HasFieldValue($service, 'properties.deleteRetentionPolicy.enabled', $True); } } # Synopsis: Use containers configured with a private access type that requires authorization. Rule 'Azure.Storage.BlobAccessType' -Ref 'AZR-000199' -Type 'Microsoft.Storage/storageAccounts', 'Microsoft.Storage/storageAccounts/blobServices/containers' -If { !(IsFileStorage) } -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Security'; } { $containers = @($TargetObject); if ($PSRule.TargetType -eq 'Microsoft.Storage/storageAccounts') { $containers = @(GetSubResources -ResourceType 'Microsoft.Storage/storageAccounts/blobServices/containers'); } if ($containers.Length -eq 0) { return $Assert.Pass(); } foreach ($container in $containers) { $Assert.HasDefaultValue($container, 'Properties.publicAccess', 'None'). Reason($LocalizedData.PublicAccessStorageContainer, $container.name, $container.Properties.publicAccess); } } # Synopsis: Use Storage naming requirements Rule 'Azure.Storage.Name' -Ref 'AZR-000201' -Type 'Microsoft.Storage/storageAccounts' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } -Labels @{ 'Azure.CAF' = 'naming' } { # https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftstorage # Between 3 and 24 characters long $Assert.GreaterOrEqual($TargetObject, 'Name', 3) $Assert.LessOrEqual($TargetObject, 'Name', 24) # Lowercase letters and numbers Match 'Name' '^[a-z0-9]{3,24}$' -CaseSensitive } # Synopsis: Enable soft delete on Storage Accounts file shares. Rule 'Azure.Storage.FileShareSoftDelete' -Ref 'AZR-000298' -Type 'Microsoft.Storage/storageAccounts', 'Microsoft.Storage/storageAccounts/fileServices' -If { (IsFileStorage) -and !(IsCloudShell) -and !(IsHnsStorage) } -Tag @{ release = 'GA'; ruleSet = '2022_09'; 'Azure.WAF/pillar' = 'Reliability'; } { $services = @($TargetObject); if ($PSRule.TargetType -eq 'Microsoft.Storage/storageAccounts') { $services = @(GetSubResources -ResourceType 'Microsoft.Storage/storageAccounts/fileServices'); } if ($services.Length -eq 0) { return $Assert.Fail($LocalizedData.SubResourceNotFound, 'Microsoft.Storage/storageAccounts/fileServices'); } foreach ($service in $services) { $Assert.HasFieldValue($service, 'properties.shareDeleteRetentionPolicy.enabled', $True); $Assert.HasFieldValue($service, 'properties.shareDeleteRetentionPolicy.days', 7); } } # Synopsis: Enable container soft delete on Storage Accounts. Rule 'Azure.Storage.ContainerSoftDelete' -Ref 'AZR-000289' -Type 'Microsoft.Storage/storageAccounts', 'Microsoft.Storage/storageAccounts/blobServices' -If { !(IsCloudShell) -and !(IsHnsStorage) -and !(IsFileStorage) } -Tag @{ release = 'GA'; ruleSet = '2022_09'; 'Azure.WAF/pillar' = 'Reliability'; } { $services = @($TargetObject); if ($PSRule.TargetType -eq 'Microsoft.Storage/storageAccounts') { $services = @(GetSubResources -ResourceType 'Microsoft.Storage/storageAccounts/blobServices'); } if ($services.Length -eq 0) { return $Assert.Fail($LocalizedData.SubResourceNotFound, 'Microsoft.Storage/storageAccounts/blobServices'); } foreach ($service in $services) { $Assert.HasFieldValue($service, 'properties.containerDeleteRetentionPolicy.enabled', $True); $Assert.GreaterOrEqual($service, 'properties.containerDeleteRetentionPolicy.days', 1); } } # Synopsis: Enable Malware Scanning in Microsoft Defender for Storage. Rule 'Azure.Storage.Defender.MalwareScan' -Alias 'Azure.Storage.DefenderCloud.MalwareScan' -Ref 'AZR-000384' -Type 'Microsoft.Storage/storageAccounts' -If { IsPublicNetworkAccessEnabled } -Tag @{ release = 'GA'; ruleSet = '2024_03'; 'Azure.WAF/pillar' = 'Security'; } -Labels @{ 'Azure.MCSB.v1/control' = @('DP-2', 'LT-1') } { $malwareDisabled = @(GetSubResources -ResourceType 'Microsoft.Security/DefenderForStorageSettings' | Where-Object { $_.properties.malwareScanning.onUpload.isEnabled -eq $False }) $Assert.Count($malwareDisabled, '.', 0).Reason($LocalizedData.ResStorageMalwareScanning, $PSRule.TargetName) } # Synopsis: Enable sensitive data threat detection in Microsoft Defender for Storage. Rule 'Azure.Storage.Defender.DataScan' -Alias 'Azure.Storage.DefenderCloud.SensitiveData' -Ref 'AZR-000391' -Type 'Microsoft.Storage/storageAccounts' -If { IsPublicNetworkAccessEnabled } -Tag @{ release = 'preview'; ruleSet = '2023_06'; 'Azure.WAF/pillar' = 'Security'; } -Labels @{ 'Azure.MCSB.v1/control' = @('DP-2', 'LT-1') } { $sensitiveDisabled = @(GetSubResources -ResourceType 'Microsoft.Security/DefenderForStorageSettings' | Where-Object { $_.properties.sensitiveDataDiscovery.isEnabled -eq $False }) $Assert.Count($sensitiveDisabled, '.', 0).Reason($LocalizedData.ResStorageSensitiveDataThreatDetection, $PSRule.TargetName) } # Synopsis: Enable Microsoft Defender for Storage for storage accounts. Rule 'Azure.Storage.DefenderCloud' -Ref 'AZR-000386' -Type 'Microsoft.Storage/storageAccounts' -If { $Configuration.AZURE_STORAGE_DEFENDER_PER_ACCOUNT -eq $True } -Tag @{ release = 'GA'; ruleSet = '2023_06'; 'Azure.WAF/pillar' = 'Security'; } -Labels @{ 'Azure.MCSB.v1/control' = @('DP-2', 'LT-1') } { $defender = @(GetSubResources -ResourceType 'Microsoft.Security/DefenderForStorageSettings' | Where-Object { $_.properties.isEnabled -eq $True }) $Assert.GreaterOrEqual($defender, '.', 1).Reason($LocalizedData.SubResourceNotFound, 'Microsoft.Security/DefenderForStorageSettings') } # Synopsis: Use standard storage accounts names. Rule 'Azure.Storage.Naming' -Ref 'AZR-000470' -Type 'Microsoft.Storage/storageAccounts' -If { !(Azure_IsManagedStorage) -and $Configuration['AZURE_STORAGE_ACCOUNT_NAME_FORMAT'] -ne '' } -Tag @{ release = 'GA'; ruleSet = '2025_06'; 'Azure.WAF/pillar' = 'Operational Excellence' } -Labels @{ 'Azure.CAF' = 'naming' } { $Assert.Match($PSRule, 'TargetName', $Configuration.AZURE_STORAGE_ACCOUNT_NAME_FORMAT, $True); } #region Helper functions function global:ShouldStorageReplicate { [CmdletBinding()] [OutputType([System.Boolean])] param () process { return (IsStandardStorage) -and !(IsCloudShell) -and !(IsFunctionStorage) -and !(IsMonitorStorage) -and !(IsLargeFileSharesEnabled) } } function global:IsStandardStorage { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if ($PSRule.TargetType -ne 'Microsoft.Storage/storageAccounts') { return $False; } return $TargetObject.sku.name -like 'Standard_*'; } } function global:IsCloudShell { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if ($PSRule.TargetType -ne 'Microsoft.Storage/storageAccounts') { return $False; } return $TargetObject.Tags.'ms-resource-usage' -eq 'azure-cloud-shell'; } } function global:IsFunctionStorage { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if ($PSRule.TargetType -ne 'Microsoft.Storage/storageAccounts') { return $False; } return $TargetObject.Tags.'resource-usage' -eq 'azure-functions'; } } function global:IsMonitorStorage { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if ($PSRule.TargetType -ne 'Microsoft.Storage/storageAccounts') { return $False; } return $TargetObject.Tags.'resource-usage' -eq 'azure-monitor'; } } function global:IsFileStorage { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if ($PSRule.TargetType -ne 'Microsoft.Storage/storageAccounts') { return $False; } return $Assert.HasFieldValue($TargetObject, 'Kind', 'FileStorage').Result; } } # Some features are not supported with hierarchical namespace function global:IsHnsStorage { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if ($PSRule.TargetType -ne 'Microsoft.Storage/storageAccounts') { return $False; } return $Assert.HasFieldValue($TargetObject, 'Properties.isHnsEnabled', $True).Result; } } function global:IsLargeFileSharesEnabled { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if ($PSRule.TargetType -ne 'Microsoft.Storage/storageAccounts') { return $False; } return $Assert.HasFieldValue($TargetObject, 'Properties.largeFileSharesState', 'Enabled').Result; } } function global:IsPublicNetworkAccessEnabled { [CmdletBinding()] param () process { $Assert.HasDefaultValue($TargetObject, 'properties.publicNetworkAccess', 'Enabled').Result } } #endregion Helper functions # SIG # Begin signature block # MIIoHQYJKoZIhvcNAQcCoIIoDjCCKAoCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAVz5VAkbcCX/1h # G05OobGMQJztaLPEovHNPYOlecDhqKCCDYUwggYDMIID66ADAgECAhMzAAAEA73V # lV0POxitAAAAAAQDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTEzWhcNMjUwOTExMjAxMTEzWjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQCfdGddwIOnbRYUyg03O3iz19XXZPmuhEmW/5uyEN+8mgxl+HJGeLGBR8YButGV # LVK38RxcVcPYyFGQXcKcxgih4w4y4zJi3GvawLYHlsNExQwz+v0jgY/aejBS2EJY # oUhLVE+UzRihV8ooxoftsmKLb2xb7BoFS6UAo3Zz4afnOdqI7FGoi7g4vx/0MIdi # kwTn5N56TdIv3mwfkZCFmrsKpN0zR8HD8WYsvH3xKkG7u/xdqmhPPqMmnI2jOFw/ # /n2aL8W7i1Pasja8PnRXH/QaVH0M1nanL+LI9TsMb/enWfXOW65Gne5cqMN9Uofv # ENtdwwEmJ3bZrcI9u4LZAkujAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU6m4qAkpz4641iK2irF8eWsSBcBkw # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMjkyNjAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AFFo/6E4LX51IqFuoKvUsi80QytGI5ASQ9zsPpBa0z78hutiJd6w154JkcIx/f7r # EBK4NhD4DIFNfRiVdI7EacEs7OAS6QHF7Nt+eFRNOTtgHb9PExRy4EI/jnMwzQJV # NokTxu2WgHr/fBsWs6G9AcIgvHjWNN3qRSrhsgEdqHc0bRDUf8UILAdEZOMBvKLC # rmf+kJPEvPldgK7hFO/L9kmcVe67BnKejDKO73Sa56AJOhM7CkeATrJFxO9GLXos # oKvrwBvynxAg18W+pagTAkJefzneuWSmniTurPCUE2JnvW7DalvONDOtG01sIVAB # +ahO2wcUPa2Zm9AiDVBWTMz9XUoKMcvngi2oqbsDLhbK+pYrRUgRpNt0y1sxZsXO # raGRF8lM2cWvtEkV5UL+TQM1ppv5unDHkW8JS+QnfPbB8dZVRyRmMQ4aY/tx5x5+ # sX6semJ//FbiclSMxSI+zINu1jYerdUwuCi+P6p7SmQmClhDM+6Q+btE2FtpsU0W # +r6RdYFf/P+nK6j2otl9Nvr3tWLu+WXmz8MGM+18ynJ+lYbSmFWcAj7SYziAfT0s # IwlQRFkyC71tsIZUhBHtxPliGUu362lIO0Lpe0DOrg8lspnEWOkHnCT5JEnWCbzu # iVt8RX1IV07uIveNZuOBWLVCzWJjEGa+HhaEtavjy6i7MIIHejCCBWKgAwIBAgIK # YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm # aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw # OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD # VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la # UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc # 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D # dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+ # lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk # kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6 # A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd # X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL # 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd # sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3 # T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS # 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI # bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD # uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h # cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA # YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn # 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7 # v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b # pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/ # KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy # CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp # mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi # hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb # BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS # oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL # gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX # cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGe4wghnqAgEBMIGVMH4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAQDvdWVXQ87GK0AAAAA # BAMwDQYJYIZIAWUDBAIBBQCggZAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # LwYJKoZIhvcNAQkEMSIEIDx7kgCtDEphXfh+Wq1ixDPQAk7fJR6NKtbr8GofS7v4 # MEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRw # Oi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEAAzgv6k+fXvc8 # QnhnoKPGzY0HDT+L7jz+4c6zWR+ZUd2pDl+9UuARs8nLOlr3cJEZnzydZvFiU4yX # cXWqv9/XftdeNCCx9/QpVwRQjZXDy0Qep0C4PWiCqsjDc3idu3uWpW1zueoX1vWb # 1AY+5+Wb99U60k6LzEdDgPWJYVwn1RxngLVXy9tK7tM/dbiLSTsplR+oXqcbqPE+ # Pv9/XfgsUpNLmLAG7YUfVHh+TqRpb+nvowfMhI14j8XRBgUcXhT8yZ/8aDqsS8+x # 5L9Uv14uA1Yt8xKmL/oNtyNH1xiRBIqfW5366rsjvaGjeDpVTyD+sLsiIEH4Z6YX # KaqSiM7+ZKGCF5YwgheSBgorBgEEAYI3AwMBMYIXgjCCF34GCSqGSIb3DQEHAqCC # F28wghdrAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAE # ggE8MIIBOAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCC3zI+kaK8A # +jKxtZF0eH0gwf+u3cis2Vqq31PXp+cgBwIGaBKxkp3TGBIyMDI1MDUwNzA3NDg1 # OS44NFowBIACAfSggdGkgc4wgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMx # JzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3RjAwLTA1RTAtRDk0NzElMCMGA1UE # AxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEe0wggcgMIIFCKADAgEC # AhMzAAACBte8UTiYI+wsAAEAAAIGMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBU # aW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI1MDEzMDE5NDI1MFoXDTI2MDQyMjE5NDI1 # MFowgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNV # BAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGll # bGQgVFNTIEVTTjo3RjAwLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRp # bWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AOlEhZsgzdGWvf3tyMdpjHzmXsj5lVYYwIEIz3XUGlTr4gZYKqSyqCp59kUSMrM1 # UNgL1hyAhMDPbvo0aC8QKbhl82/8U/BxpIPPvFsNuw6jFvBCgdQ1Guj7Hm5tmFPp # Yl5T3sXTr68OMDD9i3W9Y6BFOqY/902v2iohsTmgIth0ffAj+ehiawlVzv3rqf4H # tQAYBZTax7cvP7F3Gc2w1fgJHrMgxUlNJ7M//ZJM1zElO72TayXv+/M6HEmEJDfy # t1oSiqEYeteuZWQSFK/5LTQMwlzU4hfGp9vA+MyoRWnsreSZzMKRu6bUE4gnbC4M # Bsq4l6Wm141mP9Lnw1JDDqSF+4kCW6ocreKCRL867Hj2pM/6tT49B424P4a2sKik # W5xGZqdC/EhIY2jGcGrdR4NOqmGbpojsYwe0UPoM6MmWWUfWBVZc9PKK9/7i03xO # Y7rIiAHi4/TRsf2Of93LLFKPE9Daca9m2C2qe+reHdNGNGeRz57VcHW5q0NrXNRx # LuveKh1OnIBN7aGCRVfebgOFHMjoDhInp9skz2KwsfwAYpzKaKwrNi6kB4VJMnXQ # kQVroyMdBhiiGgIXvtHQILAw2O8Thd8se76oo9jwZB+xl2KBD1yVQCLJ0WZW3rWH # K2jFk/suZdvOMPRV5zLNmgvgSq7VezMGy6UCvkt3YrBzAgMBAAGjggFJMIIBRTAd # BgNVHQ4EFgQU7TCwsp0MalP3tzHcjKbKj9IGbhIwHwYDVR0jBBgwFoAUn6cVXQBe # Yl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNy # b3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBD # QSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0 # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBU # aW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNV # HSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQEL # BQADggIBAHbcZk5971OFNS8Pb2Li3qUOnEmGlVEyZ75RvJmEEUJmGgZO2MN2mEAC # tTZDrVZiDdhVyXZF0mbk9RtnZsDvvOT6q0vEL7d03FWxNx23E8NJJaDAEfFOPqkK # agM1eiUBixam8dAUIcOoR8CIHFfV2ZpduJM/V3Rd9++BHp2yFRypof+YV+MNkDEt # TWzodxWAK8FAmUnvEQbmMUp22pqkpZxtQfBNWpdAZsiUdUKU0nfKpbpndQkf8IVx # iItX97ry6tOYa2JnEZJhvhIFI8CtOtNh4c6VAiP/uWhVaZ9ZfbLgAZX8P4zPJkzK # 8XDhXIvRWCr3oTNArK16JV4FpUSPFAqjcBw9QtEXhTPP3w/a0IzldsVndCiP08uD # euAVevSgkSF+Ha2pSuFMl3Xf6Lj996T3NaJyiyGXBeAW7TTZlYFXMBIQW6oQPjyr # K6Vn/aMYkFy1r4V2TaWg/YrehKPg9BB7UzPNVk7nYBc7jYweWGbdIejf9GFD4jUD # Q3L724B6GRAfouvGStU29kbh/Q8AoxupRxcbvHOconTHQdivlrJYZscplFw5tT7/ # fhmkv02tc551UNeZJ3bKUpKX+++LVDA0mpcmX/6AmRAR62qYcBQVCQW16aLwxRdA # bbD9EMddfBYCMT6ogNktD+TjPZnbXq1ZpHpEMocaTB4KgO1C3OQdMIIHcTCCBVmg # AwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9z # b2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgy # MjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx # MDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ck # eb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+ # uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4 # bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhi # JdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD # 4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKN # iOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXf # tnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8 # P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMY # ctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9 # stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUe # h17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQID # AQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4E # FgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9 # AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w # cy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsG # AQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTAD # AQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0w # S6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3Rz # L01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYI # KwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWlj # Um9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38 # Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTlt # uw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99q # b74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQ # JL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1 # ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP # 9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkk # vnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFH # qfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g7 # 5LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr # 4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghi # f9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCA1AwggI4AgEBMIH5oYHRpIHO # MIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQL # ExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxk # IFRTUyBFU046N0YwMC0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1l # LVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAARrR/XXxccz9U12ooGzhBfE # 2c33oIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwDQYJKoZI # hvcNAQELBQACBQDrxRiRMCIYDzIwMjUwNTA2MjMyNDAxWhgPMjAyNTA1MDcyMzI0 # MDFaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAOvFGJECAQAwCgIBAAICQGgCAf8w # BwIBAAICEmkwCgIFAOvGahECAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGE # WQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG9w0BAQsFAAOCAQEA # GqcJfG5oWncGUPY2xeXzeJ+QIXl0PHjTIbq8/XVRalKnPKj2hIywEZ8xB3/n51h+ # 5XthjfLmbRgyRQ0pPySHfG2gN61po9TE9t9XP4pbyYC9DqJ5cFKATw02iQANJwJ+ # dMDkzOzbhkTXUCkHQK0sDOnTA8/aTM7NYsLE2q2DFv1wPdQg8NAPEWbD9kRCLjpZ # /LWUhXB/lqfmaUf00uizctqqdcrosOq9uFF8EXNNTEt9QGzVA6D1+Wh/wEe+bpCD # 2hwU7g7nHF7DQ5U1Ci88zQpSxEisxXoRYKuhgmD7vTIfjDVr+tOsT/e2LcRnv5h3 # fsQoccQA9zOadkbEWBaDbjGCBA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFBDQSAyMDEwAhMzAAACBte8UTiYI+wsAAEAAAIGMA0GCWCGSAFlAwQCAQUA # oIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIE # IB70VvwZc+BfkSd0k+nTwH3uEGA2KbzgSdFmjeOqvS2kMIH6BgsqhkiG9w0BCRAC # LzGB6jCB5zCB5DCBvQQg4Oj1lIiRnp1W0pP4T+5nHZYDLsqJczlHUkg6E0l/S9Iw # gZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYw # JAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAgbXvFE4 # mCPsLAABAAACBjAiBCAQYDEqkfmRq5HvjJhwRHdwlPk/ssp8A+ANIXXX/Ae9dTAN # BgkqhkiG9w0BAQsFAASCAgAbrL9LtlfBzAdJ4XojS9wLtYTGf+YvsRBao8Vne5OD # +7Dy2hQI1TAELcducIXbToM8F/iFe969LuK0EW3EBx8ezGz0Gu9+A/1YSSzPv5/r # lU7ODJZrAgMYJrubWiOt7PoXyoz6VDoa10gcx1vRHKm2SwH5GYG/J9CzEL4RN2L7 # CZfzQq+oTAXtYNJETtHsJZizYzHBDJaHunEm53Dr4NATmxBjGqIfry0VYanPwA2Y # qsSx2vzI3+3brQGD44ISR9l+KwuUEHiFxk14EWlcfcoGlGqlhjQTPjv0OjnsfLLz # mi2bnLfRD4H4O2LwsXB7E+0kz0wA+de5CMJUB+AySVodS9suf5JEzEFJd49AnZX+ # J/mRJljqEzt9BmnHKjl1Tj+igxBRKcB2EF8A2IQ0W2JrrPJn39kkFVmoKdD6UzjF # xHUnSm5RkOVAJUPIm2Cg9lTivCGLdHHdFljSviAun7Cj9zzCb4/+cvyfvkf3SEnS # QjN1eoN0rv0vSCBd9F1Cf6vZ83Y7yG1WPXQsGbD4D8ghtPABvHA9VKKVR8KQKnPB # kQkwxGENKeY/Kojm/YaJ9978se2FEJkOKxMSvTfCDa+NosJmuDP37oaeLotwJJUj # hB0t8Ee8ZLW3n6yAu19scy8U8ULVyLnBvrDYDbw9ieXLHeVitfZ6oauURuds7FrO # Sw== # SIG # End signature block |