mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
feat(gcp): split kms_key_rotation_enabled into enabled and max-90-days checks (#11516)
This commit is contained in:
@@ -17,6 +17,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
- External multi-provider compliance frameworks can be registered via the `prowler.compliance.universal` entry point group [(#11490)](https://github.com/prowler-cloud/prowler/pull/11490)
|
||||
- AWS AI Security Framework support in the CLI dashboard [(#11475)](https://github.com/prowler-cloud/prowler/pull/11475)
|
||||
- `entra_service_principal_privileged_role_no_owners` check for M365 provider, failing when a service principal with a permanent Tier 0 directory role has owners on the service principal or its parent app registration [(#11070)](https://github.com/prowler-cloud/prowler/issues/11070)
|
||||
- `kms_key_rotation_max_90_days` check for GCP provider, verifying KMS customer-managed keys are rotated every 90 days or less in line with the CIS Benchmark [(#11516)](https://github.com/prowler-cloud/prowler/pull/11516)
|
||||
- `exchange_mailbox_primary_smtp_uses_custom_domain` check for M365 provider [(#11215)](https://github.com/prowler-cloud/prowler/pull/11215)
|
||||
|
||||
### 🐞 Fixed
|
||||
@@ -24,6 +25,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
- `load_and_validate_config_file` now unwraps namespaced config for every built-in and external provider, and no longer leaks the full file as the provider's config when the file is namespaced [(#10700)](https://github.com/prowler-cloud/prowler/pull/10700)
|
||||
- `entra_users_mfa_capable` no longer flags pre-provisioned users with future `employeeHireDate`; future-hire date comparisons now tolerate naive datetimes [(#11511)](https://github.com/prowler-cloud/prowler/pull/11511)
|
||||
- M365 Admin Center group enumeration now follows Microsoft Graph pagination so group-scoped checks include groups beyond the first page [(#11510)](https://github.com/prowler-cloud/prowler/pull/11510)
|
||||
- GCP `kms_key_rotation_enabled` check now only verifies that automatic key rotation is enabled (any interval) instead of enforcing a 90-day period, resolving the mismatch between the check and its documentation; the CIS, Prowler ThreatScore, and CCC requirements that mandate a 90-day maximum were remapped to the new `kms_key_rotation_max_90_days` check [(#11516)](https://github.com/prowler-cloud/prowler/pull/11516)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -889,7 +889,7 @@
|
||||
}
|
||||
],
|
||||
"Checks": [
|
||||
"kms_key_rotation_enabled"
|
||||
"kms_key_rotation_max_90_days"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
"Id": "1.10",
|
||||
"Description": "Google Cloud Key Management Service stores cryptographic keys in a hierarchical structure designed for useful and elegant access control management. The format for the rotation schedule depends on the client library that is used. For the gcloud command-line tool, the next rotation time must be in `ISO` or `RFC3339` format, and the rotation period must be in the form `INTEGERUNIT`, where units can be one of seconds (s), minutes (m), hours (h) or days (d).",
|
||||
"Checks": [
|
||||
"kms_key_rotation_enabled"
|
||||
"kms_key_rotation_max_90_days"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
"Id": "1.10",
|
||||
"Description": "Ensure KMS Encryption Keys Are Rotated Within a Period of 90 Days",
|
||||
"Checks": [
|
||||
"kms_key_rotation_enabled"
|
||||
"kms_key_rotation_max_90_days"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
"Id": "1.10",
|
||||
"Description": "Ensure KMS Encryption Keys Are Rotated Within a Period of 90 Days",
|
||||
"Checks": [
|
||||
"kms_key_rotation_enabled"
|
||||
"kms_key_rotation_max_90_days"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
"Id": "1.2.4",
|
||||
"Description": "Ensure KMS Encryption Keys Are Rotated Within a Period of 90 Days",
|
||||
"Checks": [
|
||||
"kms_key_rotation_enabled"
|
||||
"kms_key_rotation_max_90_days"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
|
||||
+9
-7
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"Provider": "gcp",
|
||||
"CheckID": "kms_key_rotation_enabled",
|
||||
"CheckTitle": "KMS key is rotated at least annually",
|
||||
"CheckTitle": "KMS key has automatic rotation enabled",
|
||||
"CheckType": [],
|
||||
"ServiceName": "kms",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "low",
|
||||
"ResourceType": "cloudkms.googleapis.com/CryptoKey",
|
||||
"Description": "Google Cloud KMS customer-managed keys have **automatic rotation** enabled or a rotation interval `365` days.\n\nThe evaluation reviews each key's rotation settings to confirm periodic creation of new key versions.",
|
||||
"Description": "Google Cloud KMS customer-managed keys have **automatic rotation** enabled, regardless of the rotation interval.\n\nThe evaluation reviews each key's rotation settings to confirm that a rotation period is configured so new key versions are created periodically.",
|
||||
"Risk": "Without timely rotation, a stolen key can decrypt an expanding volume of data, eroding **confidentiality**. Prolonged key lifetimes widen windows for misuse, impact **integrity** of protected workloads, and make emergency rollover harder, risking **availability** disruptions.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
@@ -17,13 +17,13 @@
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "gcloud kms keys update <KEY_NAME> --keyring=<KEY_RING> --location=<LOCATION> --rotation-period=365d --next-rotation-time=<RFC3339_TIME>",
|
||||
"CLI": "gcloud kms keys update <KEY_NAME> --keyring=<KEY_RING> --location=<LOCATION> --rotation-period=<PERIOD> --next-rotation-time=<RFC3339_TIME>",
|
||||
"NativeIaC": "",
|
||||
"Other": "1. In Google Cloud Console, go to Security > Key Management > Key rings\n2. Open the key ring and select the key\n3. Click Edit rotation schedule (or Set rotation schedule)\n4. Set Rotation period to 365 days or less\n5. Set Next rotation date/time\n6. Click Save",
|
||||
"Terraform": "```hcl\nresource \"google_kms_crypto_key\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n key_ring = \"<example_resource_id>\"\n purpose = \"ENCRYPT_DECRYPT\"\n\n rotation_period = \"31536000s\" # Critical: sets automatic rotation to 365 days (<= 365 ensures PASS)\n}\n```"
|
||||
"Other": "1. In Google Cloud Console, go to Security > Key Management > Key rings\n2. Open the key ring and select the key\n3. Click Edit rotation schedule (or Set rotation schedule)\n4. Set a Rotation period\n5. Set Next rotation date/time\n6. Click Save",
|
||||
"Terraform": "```hcl\nresource \"google_kms_crypto_key\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n key_ring = \"<example_resource_id>\"\n purpose = \"ENCRYPT_DECRYPT\"\n\n rotation_period = \"7776000s\" # Critical: enables automatic rotation (any period ensures PASS)\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable **auto-rotation** for customer-managed keys with an interval `365` days.\n\nAdopt a **key lifecycle** policy: enforce **least privilege** on key usage, apply **separation of duties** between key admins and users, monitor key access, and rehearse emergency rotation to minimize blast radius.",
|
||||
"Text": "Enable **auto-rotation** for customer-managed keys by configuring a rotation period.\n\nAdopt a **key lifecycle** policy: enforce **least privilege** on key usage, apply **separation of duties** between key admins and users, monitor key access, and rehearse emergency rotation to minimize blast radius.",
|
||||
"Url": "https://hub.prowler.com/check/kms_key_rotation_enabled"
|
||||
}
|
||||
},
|
||||
@@ -31,6 +31,8 @@
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"RelatedTo": [
|
||||
"kms_key_rotation_max_90_days"
|
||||
],
|
||||
"Notes": ""
|
||||
}
|
||||
|
||||
+6
-28
@@ -1,5 +1,3 @@
|
||||
import datetime
|
||||
|
||||
from prowler.lib.check.models import Check, Check_Report_GCP
|
||||
from prowler.providers.gcp.services.kms.kms_client import kms_client
|
||||
|
||||
@@ -9,36 +7,16 @@ class kms_key_rotation_enabled(Check):
|
||||
findings = []
|
||||
for key in kms_client.crypto_keys:
|
||||
report = Check_Report_GCP(metadata=self.metadata(), resource=key)
|
||||
now = datetime.datetime.now()
|
||||
condition_next_rotation_time = False
|
||||
if key.next_rotation_time:
|
||||
try:
|
||||
next_rotation_time = datetime.datetime.strptime(
|
||||
key.next_rotation_time, "%Y-%m-%dT%H:%M:%S.%fZ"
|
||||
)
|
||||
except ValueError:
|
||||
next_rotation_time = datetime.datetime.strptime(
|
||||
key.next_rotation_time, "%Y-%m-%dT%H:%M:%SZ"
|
||||
)
|
||||
condition_next_rotation_time = (
|
||||
abs((next_rotation_time - now).days) <= 90
|
||||
)
|
||||
condition_rotation_period = False
|
||||
if key.rotation_period:
|
||||
condition_rotation_period = (
|
||||
int(key.rotation_period[:-1]) // (24 * 3600) <= 90
|
||||
)
|
||||
if condition_rotation_period and condition_next_rotation_time:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Key {key.name} is rotated every 90 days or less and the next rotation time is in less than 90 days."
|
||||
report.status_extended = (
|
||||
f"Key {key.name} has automatic rotation enabled."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
if condition_rotation_period:
|
||||
report.status_extended = f"Key {key.name} is rotated every 90 days or less but the next rotation time is in more than 90 days."
|
||||
elif condition_next_rotation_time:
|
||||
report.status_extended = f"Key {key.name} is not rotated every 90 days or less but the next rotation time is in less than 90 days."
|
||||
else:
|
||||
report.status_extended = f"Key {key.name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
report.status_extended = (
|
||||
f"Key {key.name} does not have automatic rotation enabled."
|
||||
)
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"Provider": "gcp",
|
||||
"CheckID": "kms_key_rotation_max_90_days",
|
||||
"CheckTitle": "KMS key is rotated every 90 days or less",
|
||||
"CheckType": [],
|
||||
"ServiceName": "kms",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "low",
|
||||
"ResourceType": "cloudkms.googleapis.com/CryptoKey",
|
||||
"Description": "Google Cloud KMS customer-managed keys are rotated with an interval of `90` days or less, in line with the CIS Benchmark.\n\nThe evaluation reviews each key's rotation settings to confirm that both the rotation period and the next rotation time stay within 90 days.",
|
||||
"Risk": "Without timely rotation, a stolen key can decrypt an expanding volume of data, eroding **confidentiality**. Prolonged key lifetimes widen windows for misuse, impact **integrity** of protected workloads, and make emergency rollover harder, risking **availability** disruptions.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://www.trendmicro.com/trendaivisiononecloudriskmanagement/knowledge-base/gcp/CloudKMS/rotate-kms-encryption-keys.html",
|
||||
"https://cloud.google.com/iam/docs/manage-access-service-accounts"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "gcloud kms keys update <KEY_NAME> --keyring=<KEY_RING> --location=<LOCATION> --rotation-period=90d --next-rotation-time=<RFC3339_TIME>",
|
||||
"NativeIaC": "",
|
||||
"Other": "1. In Google Cloud Console, go to Security > Key Management > Key rings\n2. Open the key ring and select the key\n3. Click Edit rotation schedule (or Set rotation schedule)\n4. Set Rotation period to 90 days or less\n5. Set Next rotation date/time\n6. Click Save",
|
||||
"Terraform": "```hcl\nresource \"google_kms_crypto_key\" \"<example_resource_name>\" {\n name = \"<example_resource_name>\"\n key_ring = \"<example_resource_id>\"\n purpose = \"ENCRYPT_DECRYPT\"\n\n rotation_period = \"7776000s\" # Critical: sets automatic rotation to 90 days (<= 90 ensures PASS)\n}\n```"
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable **auto-rotation** for customer-managed keys with an interval of `90` days or less.\n\nAdopt a **key lifecycle** policy: enforce **least privilege** on key usage, apply **separation of duties** between key admins and users, monitor key access, and rehearse emergency rotation to minimize blast radius.",
|
||||
"Url": "https://hub.prowler.com/check/kms_key_rotation_max_90_days"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"encryption"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [
|
||||
"kms_key_rotation_enabled"
|
||||
],
|
||||
"Notes": ""
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
import datetime
|
||||
|
||||
from prowler.lib.check.models import Check, Check_Report_GCP
|
||||
from prowler.providers.gcp.services.kms.kms_client import kms_client
|
||||
|
||||
|
||||
class kms_key_rotation_max_90_days(Check):
|
||||
def execute(self) -> Check_Report_GCP:
|
||||
findings = []
|
||||
for key in kms_client.crypto_keys:
|
||||
report = Check_Report_GCP(metadata=self.metadata(), resource=key)
|
||||
now = datetime.datetime.now()
|
||||
condition_next_rotation_time = False
|
||||
if key.next_rotation_time:
|
||||
try:
|
||||
next_rotation_time = datetime.datetime.strptime(
|
||||
key.next_rotation_time, "%Y-%m-%dT%H:%M:%S.%fZ"
|
||||
)
|
||||
except ValueError:
|
||||
next_rotation_time = datetime.datetime.strptime(
|
||||
key.next_rotation_time, "%Y-%m-%dT%H:%M:%SZ"
|
||||
)
|
||||
condition_next_rotation_time = (
|
||||
abs((next_rotation_time - now).days) <= 90
|
||||
)
|
||||
condition_rotation_period = False
|
||||
if key.rotation_period:
|
||||
condition_rotation_period = (
|
||||
int(key.rotation_period[:-1]) // (24 * 3600) <= 90
|
||||
)
|
||||
if condition_rotation_period and condition_next_rotation_time:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Key {key.name} is rotated every 90 days or less and the next rotation time is in less than 90 days."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
if condition_rotation_period:
|
||||
report.status_extended = f"Key {key.name} is rotated every 90 days or less but the next rotation time is in more than 90 days."
|
||||
elif condition_next_rotation_time:
|
||||
report.status_extended = f"Key {key.name} is not rotated every 90 days or less but the next rotation time is in less than 90 days."
|
||||
else:
|
||||
report.status_extended = f"Key {key.name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
+9
-459
@@ -1,4 +1,3 @@
|
||||
import datetime
|
||||
from unittest import mock
|
||||
|
||||
from tests.providers.gcp.gcp_fixtures import (
|
||||
@@ -34,7 +33,7 @@ class Test_kms_key_rotation_enabled:
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_kms_key_no_next_rotation_time_and_no_rotation_period(self):
|
||||
def test_kms_key_without_rotation_period(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
@@ -86,14 +85,14 @@ class Test_kms_key_rotation_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
== f"Key {kms_client.crypto_keys[0].name} does not have automatic rotation enabled."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_no_next_rotation_time_and_big_rotation_period(self):
|
||||
def test_kms_key_with_long_rotation_period(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
@@ -135,471 +134,26 @@ class Test_kms_key_rotation_enabled:
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
# Rotation period greater than 90 days still counts as enabled
|
||||
rotation_period="8776000s",
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_no_next_rotation_time_and_appropriate_rotation_period(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled import (
|
||||
kms_key_rotation_enabled,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
rotation_period="7776000s",
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less but the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_no_rotation_period_and_big_next_rotation_time(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled import (
|
||||
kms_key_rotation_enabled,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
# Next rotation time of now + 100 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_no_rotation_period_and_appropriate_next_rotation_time(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled import (
|
||||
kms_key_rotation_enabled,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
# Next rotation time of now + 30 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+30)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less but the next rotation time is in less than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_period_greater_90_days_and_big_next_rotation_time(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled import (
|
||||
kms_key_rotation_enabled,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="8776000s",
|
||||
# Next rotation time of now + 100 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_period_greater_90_days_and_appropriate_next_rotation_time(
|
||||
self,
|
||||
):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled import (
|
||||
kms_key_rotation_enabled,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="8776000s",
|
||||
# Next rotation time of now + 30 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+30)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less but the next rotation time is in less than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_period_less_90_days_and_big_next_rotation_time(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled import (
|
||||
kms_key_rotation_enabled,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="7776000s",
|
||||
# Next rotation time of now + 100 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less but the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_period_less_90_days_and_appropriate_next_rotation_time(
|
||||
self,
|
||||
):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_enabled.kms_key_rotation_enabled import (
|
||||
kms_key_rotation_enabled,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="7776000s",
|
||||
# Next rotation time of now + 30 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+30)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less and the next rotation time is in less than 90 days."
|
||||
== f"Key {kms_client.crypto_keys[0].name} has automatic rotation enabled."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_with_fractional_seconds(self):
|
||||
def test_kms_key_with_short_rotation_period(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
@@ -639,13 +193,9 @@ class Test_kms_key_rotation_enabled:
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="7776000s",
|
||||
# Next rotation time of now + 100 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
rotation_period="7776000s",
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
@@ -653,10 +203,10 @@ class Test_kms_key_rotation_enabled:
|
||||
check = kms_key_rotation_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less but the next rotation time is in more than 90 days."
|
||||
== f"Key {kms_client.crypto_keys[0].name} has automatic rotation enabled."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
|
||||
+728
@@ -0,0 +1,728 @@
|
||||
import datetime
|
||||
from unittest import mock
|
||||
|
||||
from tests.providers.gcp.gcp_fixtures import (
|
||||
GCP_PROJECT_ID,
|
||||
GCP_US_CENTER1_LOCATION,
|
||||
set_mocked_gcp_provider,
|
||||
)
|
||||
|
||||
|
||||
class Test_kms_key_rotation_max_90_days:
|
||||
def test_kms_no_key(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
kms_client.crypto_keys = []
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_kms_key_no_next_rotation_time_and_no_rotation_period(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_no_next_rotation_time_and_big_rotation_period(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
rotation_period="8776000s",
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_no_next_rotation_time_and_appropriate_rotation_period(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
rotation_period="7776000s",
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less but the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_no_rotation_period_and_big_next_rotation_time(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
# Next rotation time of now + 100 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_no_rotation_period_and_appropriate_next_rotation_time(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
# Next rotation time of now + 30 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+30)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less but the next rotation time is in less than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_period_greater_90_days_and_big_next_rotation_time(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="8776000s",
|
||||
# Next rotation time of now + 100 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less and the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_period_greater_90_days_and_appropriate_next_rotation_time(
|
||||
self,
|
||||
):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="8776000s",
|
||||
# Next rotation time of now + 30 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+30)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is not rotated every 90 days or less but the next rotation time is in less than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_period_less_90_days_and_big_next_rotation_time(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="7776000s",
|
||||
# Next rotation time of now + 100 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less but the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_period_less_90_days_and_appropriate_next_rotation_time(
|
||||
self,
|
||||
):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="7776000s",
|
||||
# Next rotation time of now + 30 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+30)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less and the next rotation time is in less than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_rotation_with_fractional_seconds(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="7776000s",
|
||||
# Next rotation time of now + 100 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=+100)
|
||||
).strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less but the next rotation time is in more than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
|
||||
def test_kms_key_next_rotation_time_without_fractional_seconds(self):
|
||||
kms_client = mock.MagicMock()
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_gcp_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days.kms_client",
|
||||
new=kms_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.gcp.services.kms.kms_key_rotation_max_90_days.kms_key_rotation_max_90_days import (
|
||||
kms_key_rotation_max_90_days,
|
||||
)
|
||||
from prowler.providers.gcp.services.kms.kms_service import (
|
||||
CriptoKey,
|
||||
KeyLocation,
|
||||
KeyRing,
|
||||
)
|
||||
|
||||
kms_client.project_ids = [GCP_PROJECT_ID]
|
||||
kms_client.region = GCP_US_CENTER1_LOCATION
|
||||
|
||||
keyring = KeyRing(
|
||||
name="projects/123/locations/us-central1/keyRings/keyring1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
keylocation = KeyLocation(
|
||||
name=GCP_US_CENTER1_LOCATION,
|
||||
project_id=GCP_PROJECT_ID,
|
||||
)
|
||||
|
||||
kms_client.crypto_keys = [
|
||||
CriptoKey(
|
||||
name="key1",
|
||||
id="projects/123/locations/us-central1/keyRings/keyring1/cryptoKeys/key1",
|
||||
project_id=GCP_PROJECT_ID,
|
||||
rotation_period="7776000s",
|
||||
# Next rotation time without fractional seconds, within 90 days
|
||||
next_rotation_time=(
|
||||
datetime.datetime.now() - datetime.timedelta(days=30)
|
||||
).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
key_ring=keyring.name,
|
||||
location=keylocation.name,
|
||||
members=["user:jane@example.com"],
|
||||
)
|
||||
]
|
||||
|
||||
check = kms_key_rotation_max_90_days()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Key {kms_client.crypto_keys[0].name} is rotated every 90 days or less and the next rotation time is in less than 90 days."
|
||||
)
|
||||
assert result[0].resource_id == kms_client.crypto_keys[0].id
|
||||
assert result[0].resource_name == kms_client.crypto_keys[0].name
|
||||
assert result[0].location == kms_client.crypto_keys[0].location
|
||||
assert result[0].project_id == kms_client.crypto_keys[0].project_id
|
||||
Reference in New Issue
Block a user