From 30738d78105dfd5734f0eedd202e3874d55c5325 Mon Sep 17 00:00:00 2001 From: Pepe Fagoaga Date: Tue, 15 Nov 2022 17:41:58 +0100 Subject: [PATCH] feat(Glacier): Service and check (#1480) --- providers/aws/services/glacier/__init__.py | 0 .../aws/services/glacier/check_extra7147 | 56 ---- .../aws/services/glacier/glacier_client.py | 4 + .../aws/services/glacier/glacier_service.py | 78 +++++ .../services/glacier/glacier_service_test.py | 116 +++++++ .../__init__.py | 0 ..._vaults_policy_public_access.metadata.json | 35 +++ .../glacier_vaults_policy_public_access.py | 50 ++++ ...lacier_vaults_policy_public_access_test.py | 282 ++++++++++++++++++ 9 files changed, 565 insertions(+), 56 deletions(-) create mode 100644 providers/aws/services/glacier/__init__.py delete mode 100644 providers/aws/services/glacier/check_extra7147 create mode 100644 providers/aws/services/glacier/glacier_client.py create mode 100644 providers/aws/services/glacier/glacier_service.py create mode 100644 providers/aws/services/glacier/glacier_service_test.py create mode 100644 providers/aws/services/glacier/glacier_vaults_policy_public_access/__init__.py create mode 100644 providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json create mode 100644 providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.py create mode 100644 providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_test.py diff --git a/providers/aws/services/glacier/__init__.py b/providers/aws/services/glacier/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/providers/aws/services/glacier/check_extra7147 b/providers/aws/services/glacier/check_extra7147 deleted file mode 100644 index 3374b91d..00000000 --- a/providers/aws/services/glacier/check_extra7147 +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -# Prowler - the handy cloud security tool (copyright 2018) by Toni de la Fuente -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy -# of the License at http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software distributed -# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, either express or implied. See the License for the -# specific language governing permissions and limitations under the License. -CHECK_ID_extra7147="7.147" -CHECK_TITLE_extra7147="[extra7147] Check if S3 Glacier vaults have policies which allow access to everyone" -CHECK_SCORED_extra7147="NOT_SCORED" -CHECK_CIS_LEVEL_extra7147="EXTRA" -CHECK_SEVERITY_extra7147="Critical" -CHECK_ASFF_RESOURCE_TYPE_extra7147="AwsGlacierVault" -CHECK_ALTERNATE_check7147="extra7147" -CHECK_SERVICENAME_extra7147="glacier" -CHECK_RISK_extra7147='Vaults accessible to everyone could expose sensitive data to bad actors' -CHECK_REMEDIATION_extra7147='Ensure vault policy does not have principle as *' -CHECK_DOC_extra7147='https://docs.aws.amazon.com/amazonglacier/latest/dev/access-control-overview.html' -CHECK_CAF_EPIC_extra7147='Data Protection' - -extra7147(){ - for regx in $REGIONS; do - LIST_OF_VAULTS=$($AWSCLI glacier list-vaults ${PROFILE_OPT} --region "${regx}" --account-id "${ACCOUNT_NUM}" --query VaultList[*].VaultName --output text 2>&1|xargs -n1) - if grep -q -E 'AccessDenied|UnauthorizedOperation|AuthorizationError' <<< "$LIST_OF_VAULTS"; then - textInfo "$regx: Access Denied trying to list vaults" "${regx}" - continue - fi - # Check for unsupported regions - if grep -q -E 'error' <<< "${LIST_OF_VAULTS}"; then - textInfo "$regx: An error occurred when calling the ListVaults operation - check if this region is supported" "${regx}" - continue - fi - if [[ $LIST_OF_VAULTS ]]; then - for vault in $LIST_OF_VAULTS;do - VAULT_POLICY_STATEMENTS=$($AWSCLI glacier ${PROFILE_OPT} get-vault-access-policy --region "${regx}" --account-id "${ACCOUNT_NUM}" --vault-name "${vault}" --output json --query policy.Policy 2>&1) - if [[ $VAULT_POLICY_STATEMENTS == *GetVaultAccessPolicy* ]]; then - textInfo "${regx}: Vault $vault doesn't have any policy" "${regx}" "$vault" - else - VAULT_POLICY_BAD_STATEMENTS=$(jq '. | fromjson' <<< "${VAULT_POLICY_STATEMENTS}" | jq '.Statement[] | select(.Effect=="Allow") | select(.Principal=="*" or .Principal.AWS=="*" or .Principal.CanonicalUser=="*")') - if [[ $VAULT_POLICY_BAD_STATEMENTS != "" ]]; then - textFail "${regx}: Vault $vault has policy which allows access to everyone" "${regx}" "$vault" - else - textPass "${regx}: Vault $vault has policy which does not allow access to everyone" "${regx}" "$vault" - fi - fi - done - else - textInfo "${regx}: No Glacier vaults found" "${regx}" - fi - done -} diff --git a/providers/aws/services/glacier/glacier_client.py b/providers/aws/services/glacier/glacier_client.py new file mode 100644 index 00000000..29006933 --- /dev/null +++ b/providers/aws/services/glacier/glacier_client.py @@ -0,0 +1,4 @@ +from providers.aws.lib.audit_info.audit_info import current_audit_info +from providers.aws.services.glacier.glacier_service import Glacier + +glacier_client = Glacier(current_audit_info) diff --git a/providers/aws/services/glacier/glacier_service.py b/providers/aws/services/glacier/glacier_service.py new file mode 100644 index 00000000..e2726150 --- /dev/null +++ b/providers/aws/services/glacier/glacier_service.py @@ -0,0 +1,78 @@ +import json +import threading + +from pydantic import BaseModel + +from lib.logger import logger +from providers.aws.aws_provider import generate_regional_clients + + +################## Glacier +class Glacier: + def __init__(self, audit_info): + self.service = "glacier" + self.session = audit_info.audit_session + self.audited_account = audit_info.audited_account + self.regional_clients = generate_regional_clients(self.service, audit_info) + self.vaults = {} + self.__threading_call__(self.__list_vaults__) + self.__threading_call__(self.__get_vault_access_policy__) + + def __get_session__(self): + return self.session + + def __threading_call__(self, call): + threads = [] + for regional_client in self.regional_clients.values(): + threads.append(threading.Thread(target=call, args=(regional_client,))) + for t in threads: + t.start() + for t in threads: + t.join() + + def __list_vaults__(self, regional_client): + logger.info("Glacier - Listing Vaults...") + try: + list_vaults_paginator = regional_client.get_paginator("list_vaults") + for page in list_vaults_paginator.paginate(): + for vault in page["VaultList"]: + vault_name = vault["VaultName"] + vault_arn = vault["VaultARN"] + self.vaults[vault_name] = Vault( + name=vault_name, + arn=vault_arn, + region=regional_client.region, + ) + + except Exception as error: + logger.error( + f"{regional_client.region} --" + f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:" + f" {error}" + ) + + def __get_vault_access_policy__(self, regional_client): + logger.info("Glacier - Getting Vault Access Policy...") + try: + for vault in self.vaults.values(): + if vault.region == regional_client.region: + vault_access_policy = regional_client.get_vault_access_policy( + vaultName=vault.name + ) + self.vaults[vault.name].access_policy = json.loads( + vault_access_policy["policy"]["Policy"] + ) + + except Exception as error: + logger.error( + f"{regional_client.region} --" + f" {error.__class__.__name__}[{error.__traceback__.tb_lineno}]:" + f" {error}" + ) + + +class Vault(BaseModel): + name: str + arn: str + region: str + access_policy: dict = {} diff --git a/providers/aws/services/glacier/glacier_service_test.py b/providers/aws/services/glacier/glacier_service_test.py new file mode 100644 index 00000000..cca64111 --- /dev/null +++ b/providers/aws/services/glacier/glacier_service_test.py @@ -0,0 +1,116 @@ +import json +from unittest.mock import patch + +import botocore +from moto.core import DEFAULT_ACCOUNT_ID + +from providers.aws.lib.audit_info.audit_info import current_audit_info +from providers.aws.services.glacier.glacier_service import Glacier + +# Mock Test Region +AWS_REGION = "eu-west-1" + + +# Mocking Access Analyzer Calls +make_api_call = botocore.client.BaseClient._make_api_call + +vault_json_policy = { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "cross-account-upload", + "Principal": {"AWS": [f"arn:aws:iam::{DEFAULT_ACCOUNT_ID}:root"]}, + "Effect": "Allow", + "Action": [ + "glacier:UploadArchive", + "glacier:InitiateMultipartUpload", + "glacier:AbortMultipartUpload", + "glacier:CompleteMultipartUpload", + ], + "Resource": [ + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ], + } + ], +} + + +def mock_make_api_call(self, operation_name, kwarg): + """We have to mock every AWS API call using Boto3""" + if operation_name == "ListVaults": + return { + "VaultList": [ + { + "VaultARN": f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault", + "VaultName": "examplevault", + "CreationDate": "2012-03-16T22:22:47.214Z", + "LastInventoryDate": "2012-03-21T22:06:51.218Z", + "NumberOfArchives": 2, + "SizeInBytes": 12334, + }, + ], + } + + if operation_name == "GetVaultAccessPolicy": + return {"policy": {"Policy": json.dumps(vault_json_policy)}} + + return make_api_call(self, operation_name, kwarg) + + +# Mock generate_regional_clients() +def mock_generate_regional_clients(service, audit_info): + regional_client = audit_info.audit_session.client(service, region_name=AWS_REGION) + regional_client.region = AWS_REGION + return {AWS_REGION: regional_client} + + +# Patch every AWS call using Boto3 and generate_regional_clients to have 1 client +@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) +@patch( + "providers.aws.services.glacier.glacier_service.generate_regional_clients", + new=mock_generate_regional_clients, +) +class Test_Glacier_Service: + # Test Glacier Client + def test__get_client__(self): + glacier = Glacier(current_audit_info) + assert glacier.regional_clients[AWS_REGION].__class__.__name__ == "Glacier" + + # Test Glacier Session + def test__get_session__(self): + glacier = Glacier(current_audit_info) + assert glacier.session.__class__.__name__ == "Session" + + # Test Glacier Service + def test__get_service__(self): + glacier = Glacier(current_audit_info) + assert glacier.service == "glacier" + + def test__list_vaults__(self): + # Set partition for the service + current_audit_info.audited_partition = "aws" + glacier = Glacier(current_audit_info) + vault_name = "examplevault" + assert len(glacier.vaults) == 1 + assert glacier.vaults[vault_name] + assert glacier.vaults[vault_name].name == vault_name + assert ( + glacier.vaults[vault_name].arn + == f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ) + assert glacier.vaults[vault_name].region == AWS_REGION + + def test__get_vault_access_policy__(self): + # Set partition for the service + current_audit_info.audited_partition = "aws" + glacier = Glacier(current_audit_info) + vault_name = "examplevault" + assert len(glacier.vaults) == 1 + assert glacier.vaults[vault_name] + assert glacier.vaults[vault_name].name == vault_name + assert ( + glacier.vaults[vault_name].arn + == f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ) + assert glacier.vaults[vault_name].region == AWS_REGION + assert glacier.vaults[vault_name].access_policy == vault_json_policy diff --git a/providers/aws/services/glacier/glacier_vaults_policy_public_access/__init__.py b/providers/aws/services/glacier/glacier_vaults_policy_public_access/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json b/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json new file mode 100644 index 00000000..ac8888ce --- /dev/null +++ b/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.metadata.json @@ -0,0 +1,35 @@ +{ + "Provider": "aws", + "CheckID": "glacier_vaults_policy_public_access", + "CheckTitle": "Check if S3 Glacier vaults have policies which allow access to everyone.", + "CheckType": [], + "ServiceName": "glacier", + "SubServiceName": "", + "ResourceIdTemplate": "arn:aws:glacier:region:account-id:vaults/vault-name", + "Severity": "critical", + "ResourceType": "AwsGlacierVault", + "Description": "Ensure CodeArtifact internal packages do not allow external public source publishing.", + "Risk": "Vaults accessible to everyone could expose sensitive data to bad actors.", + "RelatedUrl": "https://docs.aws.amazon.com/amazonglacier/latest/dev/access-control-overview.html", + "Remediation": { + "Code": { + "CLI": "", + "NativeIaC": "", + "Other": "", + "Terraform": "https://docs.bridgecrew.io/docs/ensure-glacier-vault-access-policy-is-not-public-by-only-allowing-specific-services-or-principals-to-access-it#terraform" + }, + "Recommendation": { + "Text": "Ensure vault policy does not have principle as *.", + "Url": "https://docs.aws.amazon.com/amazonglacier/latest/dev/access-control-overview.html" + } + }, + "Categories": [], + "Tags": { + "Tag1Key": "value", + "Tag2Key": "value" + }, + "DependsOn": [], + "RelatedTo": [], + "Notes": "", + "Compliance": [] +} diff --git a/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.py b/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.py new file mode 100644 index 00000000..cd7987c2 --- /dev/null +++ b/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access.py @@ -0,0 +1,50 @@ +from lib.check.models import Check, Check_Report +from providers.aws.services.glacier.glacier_client import ( + glacier_client, +) + + +class glacier_vaults_policy_public_access(Check): + def execute(self): + findings = [] + for vault in glacier_client.vaults.values(): + report = Check_Report(self.metadata) + report.region = vault.region + report.resource_id = vault.name + report.resource_arn = vault.arn + + report.status = "PASS" + report.status_extended = ( + f"Vault {vault.name} has policy which does not allow access to everyone" + ) + + public_access = False + if vault.access_policy: + for statement in vault.access_policy["Statement"]: + + # Only check allow statements + if statement["Effect"] == "Allow": + + if ( + "*" in statement["Principal"] + or ( + "AWS" in statement["Principal"] + and "*" in statement["Principal"]["AWS"] + ) + or ( + "CanonicalUser" in statement["Principal"] + and "*" in statement["Principal"]["CanonicalUser"] + ) + ): + public_access = True + break + + if public_access: + report.status = "FAIL" + report.status_extended = ( + f"Vault {vault.name} has policy which allows access to everyone" + ) + + findings.append(report) + + return findings diff --git a/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_test.py b/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_test.py new file mode 100644 index 00000000..afe730d7 --- /dev/null +++ b/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_test.py @@ -0,0 +1,282 @@ +from unittest import mock + +from moto.core import DEFAULT_ACCOUNT_ID + +from providers.aws.services.glacier.glacier_service import Vault + +AWS_REGION = "eu-west-1" + + +class Test_glacier_vaults_policy_public_access: + def test_no_vaults(self): + glacier_client = mock.MagicMock + glacier_client.vaults = {} + with mock.patch( + "providers.aws.services.glacier.glacier_service.Glacier", + new=glacier_client, + ): + # Test Check + from providers.aws.services.glacier.glacier_vaults_policy_public_access.glacier_vaults_policy_public_access import ( + glacier_vaults_policy_public_access, + ) + + check = glacier_vaults_policy_public_access() + result = check.execute() + + assert len(result) == 0 + + def test_vault_no_policy(self): + glacier_client = mock.MagicMock + vault_name = "test-vault" + vault_arn = ( + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ) + glacier_client.vaults = { + vault_name: Vault( + name=vault_name, + arn=vault_arn, + access_policy={}, + region=AWS_REGION, + ) + } + with mock.patch( + "providers.aws.services.glacier.glacier_service.Glacier", + new=glacier_client, + ): + # Test Check + from providers.aws.services.glacier.glacier_vaults_policy_public_access.glacier_vaults_policy_public_access import ( + glacier_vaults_policy_public_access, + ) + + check = glacier_vaults_policy_public_access() + result = check.execute() + + assert len(result) == 1 + assert result[0].region == AWS_REGION + assert result[0].resource_id == vault_name + assert result[0].resource_arn == vault_arn + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Vault {vault_name} has policy which does not allow access to everyone" + ) + + def test_vault_policy_pricipal_aws_list_asterisk(self): + glacier_client = mock.MagicMock + vault_name = "test-vault" + vault_arn = ( + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ) + glacier_client.vaults = { + vault_name: Vault( + name=vault_name, + arn=vault_arn, + access_policy={ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "cross-account-upload", + "Principal": {"AWS": ["*", DEFAULT_ACCOUNT_ID]}, + "Effect": "Allow", + "Action": [ + "glacier:UploadArchive", + "glacier:InitiateMultipartUpload", + "glacier:AbortMultipartUpload", + "glacier:CompleteMultipartUpload", + ], + "Resource": [ + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ], + } + ], + }, + region=AWS_REGION, + ) + } + with mock.patch( + "providers.aws.services.glacier.glacier_service.Glacier", + new=glacier_client, + ): + # Test Check + from providers.aws.services.glacier.glacier_vaults_policy_public_access.glacier_vaults_policy_public_access import ( + glacier_vaults_policy_public_access, + ) + + check = glacier_vaults_policy_public_access() + result = check.execute() + + assert len(result) == 1 + assert result[0].region == AWS_REGION + assert result[0].resource_id == vault_name + assert result[0].resource_arn == vault_arn + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Vault {vault_name} has policy which allows access to everyone" + ) + + def test_vault_policy_pricipal_asterisk(self): + glacier_client = mock.MagicMock + vault_name = "test-vault" + vault_arn = ( + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ) + glacier_client.vaults = { + vault_name: Vault( + name=vault_name, + arn=vault_arn, + access_policy={ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "cross-account-upload", + "Principal": {"AWS": ["*"]}, + "Effect": "Allow", + "Action": [ + "glacier:UploadArchive", + "glacier:InitiateMultipartUpload", + "glacier:AbortMultipartUpload", + "glacier:CompleteMultipartUpload", + ], + "Resource": [ + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ], + } + ], + }, + region=AWS_REGION, + ) + } + with mock.patch( + "providers.aws.services.glacier.glacier_service.Glacier", + new=glacier_client, + ): + # Test Check + from providers.aws.services.glacier.glacier_vaults_policy_public_access.glacier_vaults_policy_public_access import ( + glacier_vaults_policy_public_access, + ) + + check = glacier_vaults_policy_public_access() + result = check.execute() + + assert len(result) == 1 + assert result[0].region == AWS_REGION + assert result[0].resource_id == vault_name + assert result[0].resource_arn == vault_arn + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Vault {vault_name} has policy which allows access to everyone" + ) + + def test_vault_policy_pricipal_canonical_user_asterisk(self): + glacier_client = mock.MagicMock + vault_name = "test-vault" + vault_arn = ( + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ) + glacier_client.vaults = { + vault_name: Vault( + name=vault_name, + arn=vault_arn, + access_policy={ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "cross-account-upload", + "Principal": {"CanonicalUser": ["*"]}, + "Effect": "Allow", + "Action": [ + "glacier:UploadArchive", + "glacier:InitiateMultipartUpload", + "glacier:AbortMultipartUpload", + "glacier:CompleteMultipartUpload", + ], + "Resource": [ + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ], + } + ], + }, + region=AWS_REGION, + ) + } + with mock.patch( + "providers.aws.services.glacier.glacier_service.Glacier", + new=glacier_client, + ): + # Test Check + from providers.aws.services.glacier.glacier_vaults_policy_public_access.glacier_vaults_policy_public_access import ( + glacier_vaults_policy_public_access, + ) + + check = glacier_vaults_policy_public_access() + result = check.execute() + + assert len(result) == 1 + assert result[0].region == AWS_REGION + assert result[0].resource_id == vault_name + assert result[0].resource_arn == vault_arn + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"Vault {vault_name} has policy which allows access to everyone" + ) + + def test_vault_policy_private(self): + glacier_client = mock.MagicMock + vault_name = "test-vault" + vault_arn = ( + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ) + glacier_client.vaults = { + vault_name: Vault( + name=vault_name, + arn=vault_arn, + access_policy={ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "cross-account-upload", + "Principal": { + "CanonicalUser": [ + f"arn:aws:iam::{DEFAULT_ACCOUNT_ID}:root", + ] + }, + "Effect": "Allow", + "Action": [ + "glacier:UploadArchive", + "glacier:InitiateMultipartUpload", + "glacier:AbortMultipartUpload", + "glacier:CompleteMultipartUpload", + ], + "Resource": [ + f"arn:aws:glacier:{AWS_REGION}:{DEFAULT_ACCOUNT_ID}:vaults/examplevault" + ], + } + ], + }, + region=AWS_REGION, + ) + } + with mock.patch( + "providers.aws.services.glacier.glacier_service.Glacier", + new=glacier_client, + ): + # Test Check + from providers.aws.services.glacier.glacier_vaults_policy_public_access.glacier_vaults_policy_public_access import ( + glacier_vaults_policy_public_access, + ) + + check = glacier_vaults_policy_public_access() + result = check.execute() + + assert len(result) == 1 + assert result[0].region == AWS_REGION + assert result[0].resource_id == vault_name + assert result[0].resource_arn == vault_arn + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Vault {vault_name} has policy which does not allow access to everyone" + )