This commit is contained in:
Bernie White 2020-02-16 19:18:36 +10:00 коммит произвёл GitHub
Родитель a498afb287
Коммит 60c532e365
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 348 добавлений и 0 удалений

Просмотреть файл

@ -5,6 +5,10 @@
- Added new rules for Traffic Manager:
- Check web-based endpoints are monitored with HTTPS. [#240](https://github.com/Microsoft/PSRule.Rules.Azure/issues/240)
- Check at least two endpoints are enabled. [#241](https://github.com/Microsoft/PSRule.Rules.Azure/issues/241)
- Added new rules for Key Vault:
- Check soft delete is enabled. [#277](https://github.com/Microsoft/PSRule.Rules.Azure/issues/277)
- Check purge protection is enabled. [#280](https://github.com/Microsoft/PSRule.Rules.Azure/issues/280)
- Check least privileges permissions assigned in access policy. [#281](https://github.com/Microsoft/PSRule.Rules.Azure/issues/281)
## v0.9.0-B2002019 (pre-release)

Просмотреть файл

@ -0,0 +1,29 @@
---
severity: Important
category: Security operations
resource: Key Vault
online version: https://github.com/Microsoft/PSRule.Rules.Azure/blob/master/docs/rules/en/Azure.KeyVault.AccessPolicy.md
---
# Limit access to Key Vault data
## SYNOPSIS
Use the principal of least privilege when assigning access to Key Vault.
## DESCRIPTION
Key Vault is a service designed to securely store sensitive items such as secrets, keys and certificates.
Access Policies determine the permissions user accounts, groups or applications have to Key Vaults items.
The ability for applications and administrators to get, set and list within a Key Vault is commonly required.
However should only be assigned to security principals that require access.
The purge permission should be rarely assigned.
## RECOMMENDATION
Consider assigning access to Key Vault data based on the principle of least privilege.
## LINKS
- [Security recommendations for Azure Key Vault](https://docs.microsoft.com/en-us/azure/key-vault/security-recommendations)

Просмотреть файл

@ -0,0 +1,32 @@
---
severity: Important
category: Data recovery
resource: Key Vault
online version: https://github.com/Microsoft/PSRule.Rules.Azure/blob/master/docs/rules/en/Azure.KeyVault.PurgeProtect.md
---
# Use Key Vault Purge Protection
## SYNOPSIS
Enable Purge Protection on Key Vaults to prevent early purge of vaults and vault items.
## DESCRIPTION
Purge Protection is a feature of Key Vault that prevents purging of vaults and vault items.
When soft delete is configured without purge protection, deleted vaults and vault items can be purged.
Purging deletes the vault and/ or vault items immediately, and is irreversible.
When purge protection is enabled, vaults and vault items can no longer be purged.
Deleted vaults and vault items will be recoverable until the configured retention period.
By default, the retention period is 90 days.
Purge protection is not enabled by default.
## RECOMMENDATION
Consider enabling purge protection on Key Vaults to enforce retention of vaults and vault items for up to 90 days.
## LINKS
- [Azure Key Vault soft-delete overview](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-ovw-soft-delete)

Просмотреть файл

@ -0,0 +1,31 @@
---
severity: Important
category: Data recovery
resource: Key Vault
online version: https://github.com/Microsoft/PSRule.Rules.Azure/blob/master/docs/rules/en/Azure.KeyVault.SoftDelete.md
---
# Use Key Vault Soft Delete
## SYNOPSIS
Enable Soft Delete on Key Vaults to protect vaults and vault items from accidental deletion.
## DESCRIPTION
Soft Delete is a feature of Key Vault that retains Key Vaults and Key Vault items after initial deletion.
A soft deleted vault or vault item can be restored within the configured retention period.
By default, new Key Vaults created through the portal will have soft delete for 90 days configured.
Once enabled, soft delete can not be disabled.
When soft delete is enabled, it is possible to purge soft deleted vaults and vault items.
## RECOMMENDATION
Consider enabling soft delete on Key Vaults to enable recovery of vaults and vault items.
## LINKS
- [Azure Key Vault soft-delete overview](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-ovw-soft-delete)
- [Security recommendations for Azure Key Vault](https://docs.microsoft.com/en-us/azure/key-vault/security-recommendations)

Просмотреть файл

@ -15,4 +15,5 @@
BackendUrlNotHttps = "The backend URL for '{0}' is not a HTTPS endpoint."
ResourceNotAssociated = "The resource is not associated."
EnabledEndpoints = "The number of enabled endpoints is {0}."
AccessPolicyLeastPrivilege = "One or more access policies grant all or purge permission."
}

Просмотреть файл

@ -0,0 +1,34 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
# Validation rules for Key Vault
#
# Synopsis: Enable Key Vault Soft Delete
Rule 'Azure.KeyVault.SoftDelete' -Type 'Microsoft.KeyVault/vaults' -Tag @{ release = 'GA' } {
$Assert.HasFieldValue($TargetObject, 'Properties.enableSoftDelete', $True)
}
# Synopsis: Enable Key Vault Purge Protection
Rule 'Azure.KeyVault.PurgeProtect' -Type 'Microsoft.KeyVault/vaults' -Tag @{ release = 'GA' } {
$Assert.HasFieldValue($TargetObject, 'Properties.enablePurgeProtection', $True)
}
# Synopsis: Limit access to Key Vault data
Rule 'Azure.KeyVault.AccessPolicy' -Type 'Microsoft.KeyVault/vaults', 'Microsoft.KeyVault/vaults/accessPolicies' -Tag @{ release = 'GA' } {
Reason $LocalizedData.AccessPolicyLeastPrivilege;
$accessPolicies = @($TargetObject);
if ($PSRule.TargetType -eq 'Microsoft.KeyVault/vaults') {
$accessPolicies = @($TargetObject.Properties.accessPolicies);
}
if ($accessPolicies.Length -eq 0) {
return $True;
}
foreach ($policy in $accessPolicies) {
$policy.permissions.keys -notin 'All', 'Purge'
$policy.permissions.secrets -notin 'All', 'Purge'
$policy.permissions.certificates -notin 'All', 'Purge'
$policy.permissions.storage -notin 'All', 'Purge'
}
}

Просмотреть файл

@ -0,0 +1,86 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
# Unit tests for Key Vault rules
#
[CmdletBinding()]
param (
)
# Setup error handling
$ErrorActionPreference = 'Stop';
Set-StrictMode -Version latest;
if ($Env:SYSTEM_DEBUG -eq 'true') {
$VerbosePreference = 'Continue';
}
# Setup tests paths
$rootPath = $PWD;
Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Azure) -Force;
$here = (Resolve-Path $PSScriptRoot).Path;
Describe 'Azure.KeyVault' -Tag 'KeyVault' {
$dataPath = Join-Path -Path $here -ChildPath 'Resources.KeyVault.json';
Context 'Conditions' {
$invokeParams = @{
Baseline = 'Azure.All'
Module = 'PSRule.Rules.Azure'
WarningAction = 'Ignore'
ErrorAction = 'Stop'
}
$result = Invoke-PSRule @invokeParams -InputPath $dataPath -Outcome All;
It 'Azure.KeyVault.SoftDelete' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.KeyVault.SoftDelete' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'keyvault-B';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'keyvault-A', 'keyvault-C';
}
It 'Azure.KeyVault.PurgeProtect' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.KeyVault.PurgeProtect' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'keyvault-B', 'keyvault-C';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -BeIn 'keyvault-A';
}
It 'Azure.KeyVault.AccessPolicy' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.KeyVault.AccessPolicy' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
# $ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'keyvault-B';
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'keyvault-A', 'keyvault-C';
}
}
}

Просмотреть файл

@ -0,0 +1,131 @@
[
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.KeyVault/vaults/keyvault-A",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.KeyVault/vaults/keyvault-A",
"Identity": null,
"Kind": null,
"Location": "region",
"ManagedBy": null,
"ResourceName": "keyvault-A",
"Name": "keyvault-A",
"Properties": {
"sku": {
"family": "A",
"name": "Premium"
},
"tenantId": "00000000-0000-0000-0000-000000000000",
"accessPolicies": [
{
"tenantId": "00000000-0000-0000-0000-000000000000",
"objectId": "00000000-0000-0000-0000-000000000000",
"permissions": {
"certificates": [
"Get",
"List"
],
"keys": [
"Get",
"List"
],
"secrets": [
"Get",
"List",
"Set"
]
}
}
],
"enabledForDeployment": true,
"enabledForDiskEncryption": true,
"enabledForTemplateDeployment": true,
"enableSoftDelete": true,
"enablePurgeProtection": true,
"vaultUri": "https://keyvault-A.vault.azure.net/",
"provisioningState": "Succeeded"
},
"ResourceGroupName": "rg-test",
"Type": "Microsoft.KeyVault/vaults",
"ResourceType": "Microsoft.KeyVault/vaults",
"Sku": null,
"SubscriptionId": "00000000-0000-0000-0000-000000000000"
},
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.KeyVault/vaults/keyvault-B",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.KeyVault/vaults/keyvault-B",
"Identity": null,
"Kind": null,
"Location": "region",
"ManagedBy": null,
"ResourceName": "keyvault-B",
"Name": "keyvault-B",
"Properties": {
"sku": {
"family": "A",
"name": "Premium"
},
"tenantId": "00000000-0000-0000-0000-000000000000",
"accessPolicies": [
{
"tenantId": "00000000-0000-0000-0000-000000000000",
"objectId": "00000000-0000-0000-0000-000000000000",
"permissions": {
"certificates": [
"All"
],
"keys": [
"All"
],
"secrets": [
"Get",
"Set",
"List",
"Purge"
]
}
}
],
"enabledForDeployment": true,
"enabledForDiskEncryption": true,
"enabledForTemplateDeployment": true,
"enableSoftDelete": false,
"vaultUri": "https://keyvault-B.vault.azure.net/",
"provisioningState": "Succeeded"
},
"ResourceGroupName": "rg-test",
"Type": "Microsoft.KeyVault/vaults",
"ResourceType": "Microsoft.KeyVault/vaults",
"Sku": null,
"SubscriptionId": "00000000-0000-0000-0000-000000000000"
},
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.KeyVault/vaults/keyvault-C",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.KeyVault/vaults/keyvault-C",
"Identity": null,
"Kind": null,
"Location": "region",
"ManagedBy": null,
"ResourceName": "keyvault-C",
"Name": "keyvault-C",
"Properties": {
"sku": {
"family": "A",
"name": "Premium"
},
"tenantId": "00000000-0000-0000-0000-000000000000",
"accessPolicies": [
],
"enabledForDeployment": true,
"enabledForDiskEncryption": true,
"enabledForTemplateDeployment": true,
"enableSoftDelete": true,
"enablePurgeProtection": false,
"vaultUri": "https://keyvault-C.vault.azure.net/",
"provisioningState": "Succeeded"
},
"ResourceGroupName": "rg-test",
"Type": "Microsoft.KeyVault/vaults",
"ResourceType": "Microsoft.KeyVault/vaults",
"Sku": null,
"SubscriptionId": "00000000-0000-0000-0000-000000000000"
}
]