Skip to content

Commit 2e1df8f

Browse files
fest(CG-1294): add GCP CIS 1.30 1.17 rule'
1 parent 286ea82 commit 2e1df8f

4 files changed

Lines changed: 159 additions & 0 deletions

File tree

src/gcp/cis-1.3.0/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Policy Pack based on the GCP Foundations 1.3.0 benchmark provided by the [Center
7171
| GCP CIS 1.14 | Ensure API keys are restricted to only APIs that application needs access |
7272
| GCP CIS 1.15 | Ensure API keys are rotated every 90 days |
7373
| GCP CIS 1.16 | Ensure Essential Contacts is Configured for Organization |
74+
| GCP CIS 1.17 | Ensure that Dataproc Cluster is encrypted using CustomerManaged Encryption Key |
7475
| GCP CIS 2.1 | Ensure that Cloud Audit Logging is configured properly across all services and all users from a project |
7576
| GCP CIS 2.2 | Ensure that sinks are configured for all log entries |
7677
| GCP CIS 2.3 | Ensure that retention policies on log buckets are configured using Bucket Lock |
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2+
/* eslint-disable @typescript-eslint/no-explicit-any */
3+
4+
export default {
5+
id: 'gcp-cis-1.3.0-1.17',
6+
title: 'GCP CIS 1.16 Ensure Essential Contacts is Configured for Organization',
7+
description:
8+
'When you use Dataproc, cluster and job data is stored on Persistent Disks (PDs) associated with the Compute Engine VMs in your cluster and in a Cloud Storage staging bucket. This PD and bucket data is encrypted using a Google-generated data encryption key (DEK) and key encryption key (KEK). The CMEK feature allows you to create, use, and revoke the key encryption key (KEK). Google still controls the data encryption key (DEK).',
9+
audit: `**From Console:**
10+
11+
1. Login to the GCP Console and navigate to the Dataproc Cluster page by visiting:
12+
13+
https://console.cloud.google.com/dataproc/clusters.
14+
15+
2. Select the project from the project dropdown list.
16+
3. On the Dataproc Clusters page, select the cluster and click on the Name attribute value that you want to examine.
17+
4. On the details page, select the Configurations tab.
18+
5. On the Configurations tab, check the Encryption type configuration attribute value. If the value is set to Google-managed key, then Dataproc Cluster is not encrypted with Customer managed encryption keys.
19+
20+
Repeat step no. 3 - 5 for other Dataproc Clusters available in the selected project.
21+
22+
6. Change the project from the project dropdown list and repeat the audit procedure for other projects.
23+
24+
**From Command Line:**
25+
26+
1. Run clusters list command to list all the Dataproc Clusters available in the region:
27+
28+
gcloud dataproc clusters list --region='us-central1'
29+
30+
2. Run clusters describe command to get the key details of the selected cluster:
31+
32+
gcloud dataproc clusters describe <cluster_name> --region=us-central1 --flatten=config.encryptionConfig.gcePdKmsKeyName
33+
34+
3. If the above command output return "null", then the selected cluster is not encrypted with Customer managed encryption keys.
35+
4. Repeat step no. 2 and 3 for other Dataproc Clusters available in the selected region. Change the region by updating --region and repeat step no. 2 for other clusters available in the project. Change the project by running the below command and repeat the audit procedure for other Dataproc clusters available in other projects:
36+
37+
gcloud config set project <project_ID>"
38+
`,
39+
rationale:
40+
'Many Google Cloud services, such as Cloud Billing, send out notifications to share important information with Google Cloud users. By default, these notifications are sent to members with certain Identity and Access Management (IAM) roles. With Essential Contacts, you can customize who receives notifications by providing your own list of contacts.',
41+
remediation: `**From Console:**
42+
1. Login to the GCP Console and navigate to the Dataproc Cluster page by visiting
43+
44+
https://console.cloud.google.com/dataproc/clusters.
45+
46+
2. Select the project from the projects dropdown list.
47+
3. On the *Dataproc Cluster* page, click on the *Create Cluster* to create a new cluster with Customer managed encryption keys.
48+
4. On *Create a cluster* page, perform below steps:
49+
• Inside *Set up cluster* section perform below steps:
50+
-In the *Name* textbox, provide a name for your cluster.
51+
o From *Location* select the location in which you want to deploy a cluster.
52+
o Configure other configurations as per your requirements.
53+
• Inside *Configure Nodes* and *Customize cluster* section configure the settings as per your requirements.
54+
• Inside *Manage security* section, perform below steps:
55+
o From *Encryption*, select *Customer-managed key*.
56+
o Select a customer-managed key from dropdown list.
57+
o Ensure that the selected KMS Key have Cloud KMS CryptoKey Encrypter/Decrypter role assign to Dataproc Cluster service account ("serviceAccount:service-<project_number>@computesystem.iam.gserviceaccount.com").
58+
o Click on *Create* to create a cluster.
59+
• Once the cluster is created migrate all your workloads from the older cluster to the new cluster and delete the old cluster by performing the below steps:
60+
o On the *Clusters* page, select the old cluster and click on *Delete cluster*.
61+
o On the *Confirm deletion* window, click on *Confirm* to delete the cluster.
62+
o Repeat step above for other Dataproc clusters available in the selected project.
63+
• Change the project from the project dropdown list and repeat the remediation procedure for other Dataproc clusters available in other projects.
64+
65+
66+
**From Command Line:**
67+
68+
Before creating cluster ensure that the selected KMS Key have Cloud KMS CryptoKey Encrypter/Decrypter role assign to Dataproc Cluster service account ("serviceAccount:service-<project_number>@compute-system.iam.gserviceaccount.com").
69+
Run clusters create command to create new cluster with customer-managed key:
70+
71+
gcloud dataproc clusters create <cluster_name> --region=us-central1 --gce-pdkms-key=<key_resource_name>
72+
73+
The above command will create a new cluster in the selected region.
74+
Once the cluster is created migrate all your workloads from the older cluster to the new cluster and Run clusters delete command to delete cluster:
75+
76+
gcloud dataproc clusters delete <cluster_name> --region=us-central1
77+
78+
Repeat step no. 1 to create a new Dataproc cluster.
79+
Change the project by running the below command and repeat the remediation procedure for other projects:
80+
81+
gcloud config set project <project_ID>"
82+
`,
83+
references: [
84+
'https://cloud.google.com/docs/security/encryption/default-encryption',
85+
],
86+
gql: `{
87+
querygcpDataprocCluster {
88+
id
89+
__typename
90+
config{
91+
encryptionConfigGcePdKmsKeyName
92+
}
93+
}
94+
}`,
95+
resource: 'querygcpDataprocCluster[*]',
96+
severity: 'unknown',
97+
conditions: {
98+
path: '@.config.encryptionConfigGcePdKmsKeyName',
99+
isEmpty: false,
100+
}
101+
}

src/gcp/cis-1.3.0/rules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Gcp_CIS_130_113 from './gcp-cis-1.3.0-1.13'
1414
import Gcp_CIS_130_114 from './gcp-cis-1.3.0-1.14'
1515
import Gcp_CIS_130_115 from './gcp-cis-1.3.0-1.15'
1616
import Gcp_CIS_130_116 from './gcp-cis-1.3.0-1.16'
17+
import Gcp_CIS_130_117 from './gcp-cis-1.3.0-1.17'
1718
import Gcp_CIS_130_21 from './gcp-cis-1.3.0-2.1'
1819
import Gcp_CIS_130_22 from './gcp-cis-1.3.0-2.2'
1920
import Gcp_CIS_130_23 from './gcp-cis-1.3.0-2.3'
@@ -91,6 +92,7 @@ export default [
9192
Gcp_CIS_130_114,
9293
Gcp_CIS_130_115,
9394
Gcp_CIS_130_116,
95+
Gcp_CIS_130_117,
9496
Gcp_CIS_130_21,
9597
Gcp_CIS_130_22,
9698
Gcp_CIS_130_23,

src/gcp/cis-1.3.0/tests/gcp-cis-1.3.0-1.x.test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Gcp_CIS_130_112 from '../rules/gcp-cis-1.3.0-1.12'
1616
import Gcp_CIS_130_113 from '../rules/gcp-cis-1.3.0-1.13'
1717
import Gcp_CIS_130_115 from '../rules/gcp-cis-1.3.0-1.15'
1818
import Gcp_CIS_130_116 from '../rules/gcp-cis-1.3.0-1.16'
19+
import Gcp_CIS_130_117 from '../rules/gcp-cis-1.3.0-1.17'
1920
import { initRuleEngine } from '../../../utils/test'
2021

2122
export interface MetricDescriptor {
@@ -110,6 +111,13 @@ export interface QuerygcpEssentialContact {
110111
notificationCategorySubscriptions: string[]
111112
email: string
112113
}
114+
export interface DataprocClusterConfig {
115+
encryptionConfigGcePdKmsKeyName?: string
116+
}
117+
export interface QuerygcpDataprocCluster {
118+
id: string
119+
config: DataprocClusterConfig
120+
}
113121
export interface CIS1xQueryResponse {
114122
querygcpOrganization?: QuerygcpOrganization[]
115123
querygcpProject?: QuerygcpProject[]
@@ -118,6 +126,7 @@ export interface CIS1xQueryResponse {
118126
querygcpKmsKeyRing?: QuerygcpKmsKeyRing[]
119127
querygcpIamPolicy?: QuerygcpIamPolicy[]
120128
querygcpEssentialContact?: QuerygcpEssentialContact[]
129+
querygcpDataprocCluster?: QuerygcpDataprocCluster[]
121130
}
122131

123132
describe('CIS Google Cloud Platform Foundations: 1.3.0', () => {
@@ -957,4 +966,50 @@ describe('CIS Google Cloud Platform Foundations: 1.3.0', () => {
957966
await testRule(data, Result.PASS)
958967
})
959968
})
969+
970+
describe('GCP CIS 1.17 Ensure that Dataproc Cluster is encrypted using Customer Managed Encryption Key', () => {
971+
const getRuleFixture = (): CIS1xQueryResponse => {
972+
return {
973+
querygcpDataprocCluster: [
974+
{
975+
id: cuid(),
976+
config: {},
977+
},
978+
],
979+
}
980+
}
981+
982+
const testRule = async (
983+
data: CIS1xQueryResponse,
984+
expectedResult: Result
985+
): Promise<void> => {
986+
// Act
987+
const [processedRule] = await rulesEngine.processRule(
988+
Gcp_CIS_130_117 as Rule,
989+
{ ...data }
990+
)
991+
992+
// Asserts
993+
expect(processedRule.result).toBe(expectedResult)
994+
}
995+
996+
test('Security Issue when Customer Managed Encryption Key config is missing ', async () => {
997+
const data: CIS1xQueryResponse = getRuleFixture()
998+
await testRule(data, Result.FAIL)
999+
})
1000+
1001+
test('Security Issue when Customer Managed Encryption Key config is empty ', async () => {
1002+
const data: CIS1xQueryResponse = getRuleFixture()
1003+
const dataprocCluster = data.querygcpDataprocCluster as QuerygcpDataprocCluster[]
1004+
dataprocCluster[0].config.encryptionConfigGcePdKmsKeyName = ''
1005+
await testRule(data, Result.FAIL)
1006+
})
1007+
1008+
test('No Security Issue when Customer Managed Encryption Key is configured', async () => {
1009+
const data: CIS1xQueryResponse = getRuleFixture()
1010+
const dataprocCluster = data.querygcpDataprocCluster as QuerygcpDataprocCluster[]
1011+
dataprocCluster[0].config.encryptionConfigGcePdKmsKeyName = 'MyKey'
1012+
await testRule(data, Result.PASS)
1013+
})
1014+
})
9601015
})

0 commit comments

Comments
 (0)