diff --git a/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js new file mode 100644 index 0000000000..a7168a2c84 --- /dev/null +++ b/security-center/snippets/management_api/createSecurityHealthAnalyticsCustomModule.js @@ -0,0 +1,99 @@ +// Copyright 2025 Google LLC +// +// 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. +'use strict'; + +/** + * Create security health analytics custom module + */ +function main(organizationId, customModuleDisplayName, locationId = 'global') { + // [START securitycenter_create_security_health_analytics_custom_module] + // npm install '@google-cloud/securitycentermanagement' + const { + SecurityCenterManagementClient, + protos, + } = require('@google-cloud/securitycentermanagement'); + + const client = new SecurityCenterManagementClient(); + + const EnablementState = + protos.google.cloud.securitycentermanagement.v1 + .SecurityHealthAnalyticsCustomModule.EnablementState; + + const Severity = + protos.google.cloud.securitycentermanagement.v1.CustomConfig.Severity; + + /* + * Required. The name of the parent resource of security health analytics module + * Its format is + * `organizations/[organization_id]/locations/[location_id]` + * `folders/[folder_id]/locations/[location_id]` + * `projects/[project_id]/locations/[location_id]` + */ + const parent = `organizations/${organizationId}/locations/${locationId}`; + + /* + * Required. Resource name of security health analytics module. + * Its format is + * `organizations/[organization_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `folders/[folder_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `projects/[project_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + */ + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/custom_module`; + + // define the CEL expression here and this will scans for keys that have not been rotated in + // the last 30 days, change it according to your requirements + const expr = { + expression: `has(resource.rotationPeriod) && (resource.rotationPeriod > duration('2592000s'))`, + }; + + // define the resource selector + const resourceSelector = { + resourceTypes: ['cloudkms.googleapis.com/CryptoKey'], + }; + + // define the custom module configuration, update the severity, description, + // recommendation below + const customConfig = { + predicate: expr, + resourceSelector: resourceSelector, + severity: Severity.MEDIUM, + description: 'add your description here', + recommendation: 'add your recommendation here', + }; + + // define the security health analytics custom module configuration, update the + // EnablementState below + const securityHealthAnalyticsCustomModule = { + name: name, + displayName: customModuleDisplayName, + enablementState: EnablementState.ENABLED, + customConfig: customConfig, + }; + + async function createSecurityHealthAnalyticsCustomModule() { + const [response] = await client.createSecurityHealthAnalyticsCustomModule({ + parent: parent, + securityHealthAnalyticsCustomModule: securityHealthAnalyticsCustomModule, + }); + console.log( + 'Security Health Analytics Custom Module creation succeeded: ', + response + ); + } + + createSecurityHealthAnalyticsCustomModule(); + // [END securitycenter_create_security_health_analytics_custom_module] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js new file mode 100644 index 0000000000..19302ac1e3 --- /dev/null +++ b/security-center/snippets/management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js @@ -0,0 +1,52 @@ +// Copyright 2025 Google LLC +// +// 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. +'use strict'; + +/** + * Retrieve an existing effective security health analytics custom module + */ +function main(organizationId, customModuleId, locationId = 'global') { + // [START securitycenter_get_effective_security_health_analytics_custom_module] + // npm install '@google-cloud/securitycentermanagement' + const { + SecurityCenterManagementClient, + } = require('@google-cloud/securitycentermanagement'); + + const client = new SecurityCenterManagementClient(); + + /* + * Required. Resource name of security health analytics module. + * Its format is + * `organizations/[organization_id]/locations/[location_id]/effectiveSecurityHealthAnalyticsCustomModules/[custom_module]` + * `folders/[folder_id]/locations/[location_id]/effectiveSecurityHealthAnalyticsCustomModules/[custom_module]` + * `projects/[project_id]/locations/[location_id]/effectiveSecurityHealthAnalyticsCustomModules/[custom_module]` + */ + const name = `organizations/${organizationId}/locations/${locationId}/effectiveSecurityHealthAnalyticsCustomModules/${customModuleId}`; + + async function getEffectiveSecurityHealthAnalyticsCustomModule() { + const [response] = + await client.getEffectiveSecurityHealthAnalyticsCustomModule({ + name: name, + }); + console.log( + 'Security Health Analytics Custom Module get effective succeeded: ', + response + ); + } + + getEffectiveSecurityHealthAnalyticsCustomModule(); + // [END securitycenter_get_effective_security_health_analytics_custom_module] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/management_api/getSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/getSecurityHealthAnalyticsCustomModule.js new file mode 100644 index 0000000000..086f95103b --- /dev/null +++ b/security-center/snippets/management_api/getSecurityHealthAnalyticsCustomModule.js @@ -0,0 +1,51 @@ +// Copyright 2025 Google LLC +// +// 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. +'use strict'; + +/** + * Retrieve an existing security health analytics custom module + */ +function main(organizationId, customModuleId, locationId = 'global') { + // [START securitycenter_get_security_health_analytics_custom_module] + // npm install '@google-cloud/securitycentermanagement' + const { + SecurityCenterManagementClient, + } = require('@google-cloud/securitycentermanagement'); + + const client = new SecurityCenterManagementClient(); + + /* + * Required. Resource name of security health analytics module. + * Its format is + * `organizations/[organization_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `folders/[folder_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `projects/[project_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + */ + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${customModuleId}`; + + async function getSecurityHealthAnalyticsCustomModule() { + const [response] = await client.getSecurityHealthAnalyticsCustomModule({ + name: name, + }); + console.log( + 'Security Health Analytics Custom Module get succeeded: ', + response + ); + } + + getSecurityHealthAnalyticsCustomModule(); + // [END securitycenter_get_security_health_analytics_custom_module] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/management_api/updateSecurityHealthAnalyticsCustomModule.js b/security-center/snippets/management_api/updateSecurityHealthAnalyticsCustomModule.js new file mode 100644 index 0000000000..495c740109 --- /dev/null +++ b/security-center/snippets/management_api/updateSecurityHealthAnalyticsCustomModule.js @@ -0,0 +1,69 @@ +// Copyright 2025 Google LLC +// +// 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. +'use strict'; + +/** + * Update an existing security health analytics custom module + */ +function main(organizationId, customModuleId, locationId = 'global') { + // [START securitycenter_update_security_health_analytics_custom_module] + // npm install '@google-cloud/securitycentermanagement' + const { + SecurityCenterManagementClient, + protos, + } = require('@google-cloud/securitycentermanagement'); + + const client = new SecurityCenterManagementClient(); + + const EnablementState = + protos.google.cloud.securitycentermanagement.v1 + .SecurityHealthAnalyticsCustomModule.EnablementState; + + /* + * Required. Resource name of security health analytics module. + * Its format is + * `organizations/[organization_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `folders/[folder_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + * `projects/[project_id]/locations/[location_id]/securityHealthAnalyticsCustomModules/[custom_module]` + */ + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${customModuleId}`; + + // define the security health analytics custom module configuration, update the + // EnablementState below + const securityHealthAnalyticsCustomModule = { + name: name, + enablementState: EnablementState.DISABLED, + }; + + // Set the field mask to specify which properties should be updated. + const fieldMask = { + paths: ['enablement_state'], + }; + + async function updateSecurityHealthAnalyticsCustomModule() { + const [response] = await client.updateSecurityHealthAnalyticsCustomModule({ + updateMask: fieldMask, + securityHealthAnalyticsCustomModule: securityHealthAnalyticsCustomModule, + }); + console.log( + 'Security Health Analytics Custom Module update succeeded: ', + response + ); + } + + updateSecurityHealthAnalyticsCustomModule(); + // [END securitycenter_update_security_health_analytics_custom_module] +} + +main(...process.argv.slice(2)); diff --git a/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js new file mode 100644 index 0000000000..6220214729 --- /dev/null +++ b/security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js @@ -0,0 +1,173 @@ +// Copyright 2025 Google LLC +// +// 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 +// +// https://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. + +'use strict'; + +const { + SecurityCenterManagementClient, + protos, +} = require('@google-cloud/securitycentermanagement'); +const uuidv1 = require('uuid').v1; +const {assert} = require('chai'); +const {describe, it, before, after} = require('mocha'); +const {execSync} = require('child_process'); +const exec = cmd => execSync(cmd, {encoding: 'utf8'}); + +// TODO(developer): update for your own environment +const organizationId = '1081635000895'; +const locationId = 'global'; +const customModuleDisplayName = + 'node_security_health_analytics_test' + uuidv1().replace(/-/g, '_'); + +describe('security health analytics custom module', async () => { + let data; + const sharedModuleIds = []; + + before(async () => { + const client = new SecurityCenterManagementClient(); + const EnablementState = + protos.google.cloud.securitycentermanagement.v1 + .SecurityHealthAnalyticsCustomModule.EnablementState; + const Severity = + protos.google.cloud.securitycentermanagement.v1.CustomConfig.Severity; + const parent = `organizations/${organizationId}/locations/${locationId}`; + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/custom_module`; + const expr = { + expression: `has(resource.rotationPeriod) && (resource.rotationPeriod > duration('2592000s'))`, + }; + const resourceSelector = { + resourceTypes: ['cloudkms.googleapis.com/CryptoKey'], + }; + const customConfig = { + predicate: expr, + resourceSelector: resourceSelector, + severity: Severity.MEDIUM, + description: 'add your description here', + recommendation: 'add your recommendation here', + }; + const securityHealthAnalyticsCustomModule = { + name: name, + displayName: customModuleDisplayName, + enablementState: EnablementState.ENABLED, + customConfig: customConfig, + }; + + try { + await new Promise(resolve => setTimeout(resolve, 1000)); + const [createResponse] = + await client.createSecurityHealthAnalyticsCustomModule({ + parent: parent, + securityHealthAnalyticsCustomModule: + securityHealthAnalyticsCustomModule, + }); + // extracts the custom module ID from the full name + const customModuleId = createResponse.name.split('/').pop(); + data = { + orgId: organizationId, + customModuleId: customModuleId, + customModuleName: createResponse.displayName, + }; + sharedModuleIds.push(customModuleId); + console.log( + 'SecurityHealthAnalyticsCustomModule created : %j', + createResponse + ); + } catch (error) { + console.error( + 'Error creating SecurityHealthAnalyticsCustomModule:', + error + ); + } + }); + + after(async () => { + const client = new SecurityCenterManagementClient(); + + if (sharedModuleIds.length > 0) { + for (const moduleId of sharedModuleIds) { + const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${moduleId}`; + + try { + await client.deleteSecurityHealthAnalyticsCustomModule({ + name: name, + }); + console.log( + `SecurityHealthAnalyticsCustomModule ${moduleId} deleted successfully.` + ); + } catch (error) { + console.error( + 'Error deleting SecurityHealthAnalyticsCustomModule:', + error + ); + } + } + } + }); + + it('create security health analytics custom module', done => { + const output = exec( + `node management_api/createSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleName} ${locationId}` + ); + + const name = output.match(/name:\s*['"]([^'"]+)['"]/)[1]; + sharedModuleIds.push(name.split('/').pop()); + + assert.include(output, data.customModuleName); + assert.match( + output, + /Security Health Analytics Custom Module creation succeeded/ + ); + assert.notMatch(output, /undefined/); + done(); + }); + + it('update security health analytics custom module', done => { + const output = exec( + `node management_api/updateSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleId} ${locationId}` + ); + assert.include(output, 'DISABLED'); + assert.match( + output, + /Security Health Analytics Custom Module update succeeded/ + ); + assert.notMatch(output, /undefined/); + done(); + }); + + it('get security health analytics custom module', done => { + const output = exec( + `node management_api/getSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleId} ${locationId}` + ); + assert.include(output, data.customModuleName); + assert.match( + output, + /Security Health Analytics Custom Module get succeeded/ + ); + assert.notMatch(output, /undefined/); + done(); + }); + + it('get effective security health analytics custom module', done => { + const output = exec( + `node management_api/getEffectiveSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleId} ${locationId}` + ); + assert.include(output, data.customModuleName); + assert.match( + output, + /Security Health Analytics Custom Module get effective succeeded/ + ); + assert.notMatch(output, /undefined/); + done(); + }); +});