Skip to content

Commit

Permalink
feat(new): Added Azure.ACR.AnonymousAccess (#2433)
Browse files Browse the repository at this point in the history
* feat(new): Added Azure.ACR.AnonymousAccess

* Added security baseline

* Bump selector

---------

Co-authored-by: Bernie White <[email protected]>
  • Loading branch information
BenjaminEngeset and BernieWhite authored Sep 23, 2023
1 parent 3f37845 commit 5977082
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 0 deletions.
5 changes: 5 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

- New rules:
- Azure Container Registry:
- Check that Container Registries disables anonymous pull access by @BenjaminEngeset.
[#2422](https://github.com/Azure/PSRule.Rules.Azure/issues/2422)

## v1.30.0-B0080 (pre-release)

What's changed since pre-release v1.30.0-B0047:
Expand Down
92 changes: 92 additions & 0 deletions docs/en/rules/Azure.ACR.AnonymousAccess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
severity: Important
pillar: Security
category: Identity and access management
resource: Container Registry
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ACR.AnonymousAccess/
---

# Anonymous pull access

## SYNOPSIS

Disable anonymous pull access.

## DESCRIPTION

Azure Container Registry (ACR) allows you to pull or push content from an Azure container registry by being authenticated.
However, it is possible to pull content from an Azure container registry by being unauthenticated (anonymous pull access).

By default, access to pull or push content from an Azure container registry is only available to authenticated users.

Generally speaking it is not a good practice to allow data-plane operations to unauthenticated users.
However, anonymous pull access can be used in scenarios that do not require user authentication such as distributing public container images.

## RECOMMENDATION

Consider disabling anonymous pull access in scenarios that require user authentication.

## EXAMPLES

### Configure with Azure template

To deploy Azure Container Registries that pass this rule:

- Set the `properties.anonymousPullEnabled` property to `false`.

For example:

```json
{
"type": "Microsoft.ContainerRegistry/registries",
"apiVersion": "2023-01-01-preview",
"name": "[parameters('registryName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"properties": {
"anonymousPullEnabled": false
}
}
```

### Configure with Bicep

To deploy Azure Container Registries that pass this rule:

- Set the `properties.anonymousPullEnabled` property to `false`.

For example:

```bicep
resource acr 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = {
name: registryName
location: location
sku: {
name: 'Standard'
}
properties: {
anonymousPullEnabled: false
}
}
```

### Configure with Azure CLI

```bash
az acr update --name myregistry --anonymous-pull-enabled false
```

## NOTES

The anonymous pull access feature is currently in preview.
Anonymous pull access is only available in the `Standard` and `Premium` service tiers.

## LINKS

- [Authentication with Azure AD](https://learn.microsoft.com/azure/well-architected/security/design-identity-authentication)
- [Make your container registry content publicly available](https://learn.microsoft.com/azure/container-registry/anonymous-pull-access)
- [Azure security baseline for Container Registry](https://learn.microsoft.com/security/benchmark/azure/baselines/container-registry-security-baseline)
- [IM-1: Use centralized identity and authentication system](https://learn.microsoft.com/security/benchmark/azure/baselines/container-registry-security-baseline#im-1-use-centralized-identity-and-authentication-system)
- [Azure deployment reference](https://learn.microsoft.com/en-us/azure/templates/microsoft.containerregistry/registries#registryproperties)
38 changes: 38 additions & 0 deletions src/PSRule.Rules.Azure/rules/Azure.ACR.Rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,27 @@ spec:
field: properties.policies.retentionPolicy.status
equals: enabled

---
# Synopsis: Disable anonymous pull access.
apiVersion: github.com/microsoft/PSRule/v1
kind: Rule
metadata:
name: Azure.ACR.AnonymousAccess
ref: AZR-000401
tags:
release: preview
ruleSet: 2023_09
Azure.WAF/pillar: Security
labels:
Azure.MCSB.v1/control: 'IM-1'
spec:
with:
- Azure.ACR.IsPremiumSKU
- Azure.ACR.IsStandardSKU
condition:
field: properties.anonymousPullEnabled
hasDefault: false

#endregion Rules

#region Selectors
Expand All @@ -152,4 +173,21 @@ spec:
- field: sku.tier
equals: Premium

---
# Synopsis: Azure Container Registries using a Standard SKU.
apiVersion: github.com/microsoft/PSRule/v1
kind: Selector
metadata:
name: Azure.ACR.IsStandardSKU
spec:
if:
allOf:
- type: '.'
equals: Microsoft.ContainerRegistry/registries
- anyOf:
- field: sku.name
equals: Standard
- field: sku.tier
equals: Standard

#endregion Selectors
20 changes: 20 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Azure.ACR.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,26 @@ Describe 'Azure.ACR' -Tag 'ACR' {
$ruleResult.Length | Should -Be 3;
$ruleResult.TargetName | Should -BeIn 'registry-G', 'registry-I', 'registry-J';
}

It 'Azure.ACR.AnonymousAccess' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.ACR.AnonymousAccess' };

# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -BeIn 'registry-B';
$ruleResult.Detail.Reason.Path | Should -BeIn 'properties.anonymousPullEnabled';

# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult.Length | Should -Be 8;
$ruleResult.TargetName | Should -BeIn 'registry-C', 'registry-D', 'registry-E', 'registry-F', 'registry-G', 'registry-H', 'registry-I', 'registry-J';

# None
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'None' });
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -BeIn 'registry-A';
}
}

Context 'Resource name' {
Expand Down
2 changes: 2 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Resources.ACR.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"Name": "registry-B",
"Properties": {
"loginServer": "registry-B.azurecr.io",
"anonymousPullEnabled": true,
"adminUserEnabled": false,
"policies": {
"quarantinePolicy": {
Expand Down Expand Up @@ -187,6 +188,7 @@
"ResourceName": "registry-C",
"Name": "registry-C",
"Properties": {
"anonymousPullEnabled": false,
"loginServer": "registry-C.azurecr.io",
"policies": {
"quarantinePolicy": {
Expand Down

0 comments on commit 5977082

Please sign in to comment.