Managing security sources using the Security Command Center API

This guide walks you through using the Security Command Center API to create a source to generate findings. When you add a source, Security Command Center creates appropriate sources and assigns them the relevant permissions.

The IAM roles for Security Command Center can be granted at the organization, folder, or project level. Your ability to view, edit, create, or update findings, assets, and security sources depends on the level for which you are granted access. To learn more about Security Command Center roles, see Access control.

Before you begin

Before you set up a source, you need to authenticate with the Security Command Center API.

Creating a source

This example shows how to create a source with a specific display name and description that is used in Security Command Center.

The server automatically assigns an ID to the source.

REST

In the API, make a request to the organizations.sources.create method. The request body contains an instance of Source.

 POST https://securitycenter.googleapis.com/v2/organizations/ORGANIZATION_ID/sources
 {
 "name": "SOURCE_NAME",
 "description": "SOURCE_DESCRIPTION",
 "displayName": "DISPLAY_NAME"
 }

Replace the following:

  • ORGANIZATION_ID: your organization ID.
  • SOURCE_NAME: the name of the source.
  • SOURCE_DESCRIPTION: a description of the source (max: 1,024 characters).
  • DISPLAY_NAME: the display name of the source (between one and 64 characters).

Go

import(
"context"
"fmt"
"io"
securitycenter"cloud.google.com/go/securitycenter/apiv2"
"cloud.google.com/go/securitycenter/apiv2/securitycenterpb"
)
// createSource creates a new source for organization orgID. orgID is
// the numeric identifier of the organization
funccreateSource(wio.Writer,orgIDstring)error{
// orgID := "12321311"
// Instantiate a context and a security service client to make API calls.
ctx:=context.Background()
client,err:=securitycenter.NewClient (ctx)
iferr!=nil{
returnfmt.Errorf("securitycenter.NewClient: %w",err)
}
deferclient.Close ()// Closing the client safely cleans up background resources.
req:=&securitycenterpb.CreateSourceRequest{
Source:&securitycenterpb.Source{
DisplayName:"Customized Display Name",
Description:"A new custom source that does X",
},
Parent:fmt.Sprintf("organizations/%s",orgID),
}
source,err:=client.CreateSource(ctx,req)
iferr!=nil{
returnfmt.Errorf("CreateSource: %w",err)
}
fmt.Fprintf(w,"New source created: %s\n",source.Name )
fmt.Fprintf(w,"Display Name: %s\n",source.DisplayName)
returnnil
}

Java


importcom.google.cloud.securitycenter.v2.CreateSourceRequest ;
importcom.google.cloud.securitycenter.v2.OrganizationName ;
importcom.google.cloud.securitycenter.v2.SecurityCenterClient ;
importcom.google.cloud.securitycenter.v2.Source ;
importjava.io.IOException;
publicclass CreateSource{
publicstaticvoidmain(String[]args)throwsIOException{
// TODO: Replace the sample resource name
// organizationId: Google Cloud Organization id.
StringorganizationId="{google-cloud-organization-id}";
createSource(organizationId);
}
/**
 * Creates a new "source" in the Security Command Center.
 */
publicstaticSource createSource(StringorganizationId)throwsIOException{
try(SecurityCenterClient client=SecurityCenterClient .create()){
// Start setting up a request to create a source in an organization.
OrganizationName organizationName=OrganizationName .of(organizationId);
Source source=
Source .newBuilder()
.setDisplayName("Custom display name")
.setDescription("A source that does X")
.build();
CreateSourceRequest createSourceRequest=
CreateSourceRequest .newBuilder()
.setParent(organizationName.toString ())
.setSource(source)
.build();
// The source is not visible in the Security Command Center dashboard
// until it generates findings.
Source response=client.createSource(createSourceRequest);
returnresponse;
}
}
}

Node.js

// Import the Google Cloud client library.
const{SecurityCenterClient}=require('@google-cloud/security-center').v2;
// Create a new Security Center client
constclient=newSecurityCenterClient ();
// TODO(developer): Update for your own environment.
constorganizationId='1081635000895';
// Resource name of the new source's parent. Format is:
// "organizations/[organization_id]".
constparent=client.organizationPath(organizationId);
// The source object.
constsource={
displayName:'Customized Display Name V2',
description:'A new custom source that does X',
};
// Build the create source request.
constcreateSourceRequest={
parent,
source,
};
// The source is not visible in the Security Command Center dashboard
// until it generates findings.
// Call the API
asyncfunctioncreateSource(){
const[source]=awaitclient.createSource(createSourceRequest);
console.log('New Source created: %j',source);
}
awaitcreateSource();

Python

defcreate_source(organization_id) -> Dict:
"""
 Create a new findings source
 Args:
 organization_id: organization_id is the numeric ID of the organization. e.g.:organization_id = "111122222444"
 Returns:
 Dict: returns the created findings source details.
 """
 fromgoogle.cloudimport securitycenter_v2
 client = securitycenter_v2.SecurityCenterClient()
 org_name = f"organizations/{organization_id}"
 response = client.create_source (
 request={
 "parent": org_name,
 "source": {
 "display_name": "Customized Display Name",
 "description": "A new custom source that does X",
 },
 }
 )
 print(f"Created Source: {response.name}")
 return response

The source is not visible in the Security Command Center console until it generates findings. You can verify it was created by following the instructions in Get a specific source.

Updating a source

You can update a source's display name and description after it's created. You can also use a field mask to update only one field. The following example uses a field mask to only update the display name, leaving the description unchanged.

REST

In the API, make a request to the organizations.sources.patch method. The request body contains an instance of Source.

 PATCH https://securitycenter.googleapis.com/v2/organizations/ORGANIZATION_ID/sources/SOURCE_ID?updateMask=displayName -d
 {
 "description": "SOURCE_DESCRIPTION",
 "displayName": "DISPLAY_NAME",
 }

Replace the following:

  • ORGANIZATION_ID: your organization ID.
  • SOURCE_ID: the source ID; to learn how to find a source ID, see Getting the source ID.
  • SOURCE_DESCRIPTION: a description of the source (max: 1024 characters).
  • DISPLAY_NAME: the display name of the source (between one and 64 characters).

Go

import(
"context"
"fmt"
"io"
securitycenter"cloud.google.com/go/securitycenter/apiv2"
"cloud.google.com/go/securitycenter/apiv2/securitycenterpb"
"google.golang.org/genproto/protobuf/field_mask"
)
// updateSource changes a sources display name to "New Display Name" for a
// specific source. sourceName is the full resource name of the source to be
// updated.
funcupdateSource(wio.Writer,sourceNamestring)error{
// sourceName := "organizations/111122222444/sources/1234"
// Instantiate a context and a security service client to make API calls.
ctx:=context.Background()
client,err:=securitycenter.NewClient (ctx)
iferr!=nil{
returnfmt.Errorf("securitycenter.NewClient: %w",err)
}
deferclient.Close ()// Closing the client safely cleans up background resources.
req:=&securitycenterpb.UpdateSourceRequest{
Source:&securitycenterpb.Source{
Name:sourceName,
DisplayName:"New Display Name",
},
// Only update the display name field (if not set all mutable
// fields of the source will be updated.
UpdateMask:&field_mask.FieldMask{
Paths:[]string{"display_name"},
},
}
source,err:=client.UpdateSource(ctx,req)
iferr!=nil{
returnfmt.Errorf("UpdateSource: %w",err)
}
fmt.Fprintf(w,"Source Name: %s, ",source.Name )
fmt.Fprintf(w,"Display name: %s, ",source.DisplayName)
fmt.Fprintf(w,"Description: %s\n",source.Description)
returnnil
}

Java


importcom.google.cloud.securitycenter.v2.SecurityCenterClient ;
importcom.google.cloud.securitycenter.v2.Source ;
importcom.google.cloud.securitycenter.v2.SourceName ;
importcom.google.cloud.securitycenter.v2.UpdateSourceRequest ;
importcom.google.protobuf.FieldMask ;
importjava.io.IOException;
publicclass UpdateSource{
publicstaticvoidmain(String[]args)throwsIOException{
// TODO: Replace the below variables.
// organizationId: Google Cloud Organization id.
StringorganizationId="{google-cloud-organization-id}";
// Specify the source-id.
StringsourceId="{source-id}";
updateSource(organizationId,sourceId);
}
// Demonstrates how to update a source.
publicstaticSource updateSource(StringorganizationId,StringsourceId)throwsIOException{
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try(SecurityCenterClient client=SecurityCenterClient .create()){
// Start setting up a request to get a source.
SourceName sourceName=SourceName .ofOrganizationSourceName (organizationId,sourceId);
Source source=Source .newBuilder()
.setDisplayName("Updated Display Name")
.setName(sourceName.toString ())
.build();
// Set the update mask to specify which properties should be updated.
// If empty, all mutable fields will be updated.
// For more info on constructing field mask path, see the proto or:
// https://cloud.google.com/java/docs/reference/protobuf/latest/com.google.protobuf.FieldMask
FieldMask updateMask=FieldMask .newBuilder()
.addPaths ("display_name")
.build();
UpdateSourceRequest request=UpdateSourceRequest .newBuilder()
.setSource(source)
.setUpdateMask(updateMask)
.build();
// Call the API.
Source response=client.updateSource(request);
System.out.println("Updated Source: "+response);
returnresponse;
}
}
}

Node.js

// npm install '@google-cloud/security-center'
const{SecurityCenterClient}=require('@google-cloud/security-center').v2;
constclient=newSecurityCenterClient ();
// TODO(developer): Update the following for your own environment.
constorganizationId='1081635000895';
constlocation='global';
asyncfunctioncreateSampleFinding(){
constuuid=require('uuid');
const[source]=awaitclient.createSource({
source:{
displayName:'Customized Display Name V2',
description:'A new custom source that does X',
},
parent:client.organizationPath(organizationId),
});
constsourceId=source.name.split('/')[3];
// Resource name of the new finding's parent. Examples:
// - `organizations/[organization_id]/sources/[source_id]`
// - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]`
constparent=`organizations/${organizationId}/sources/${sourceId}/locations/${location}`;
// The resource this finding applied to. The Cloud Security Command Center UI can link the
// findings for a resource to the corresponding asset of a resource if there are matches.
constresourceName=`//cloudresourcemanager.googleapis.com/organizations/${organizationId}`;
// Unique identifier provided by the client within the parent scope.
// It must be alphanumeric and less than or equal to 32 characters and
// greater than 0 characters in length.
constfindingId=uuid.v4().replace(/-/g,'');
// Get the current timestamp.
consteventDate=newDate();
// Finding category.
constcategory='MEDIUM_RISK_ONE';
// Build the finding request object.
constcreateFindingRequest={
parent:parent,
findingId:findingId,
finding:{
resourceName,
category,
state:'ACTIVE',
// The time associated with discovering the issue.
eventTime:{
seconds:Math.floor(eventDate.getTime()/1000),
nanos:(eventDate.getTime()%1000)*1e6,
},
},
};
awaitclient.createFinding(createFindingRequest);
returnsourceId;
}
constsourceId=awaitcreateSampleFinding();
/**
 * Required. The source resource to update.
 */
constsourceName=client.organizationSourcePath(organizationId,sourceId);
// Set the update mask to specify which properties should be updated.
// If empty, all mutable fields will be updated.
// For more info on constructing field mask path, see the proto or:
// https://cloud.google.com/java/docs/reference/protobuf/latest/com.google.protobuf.FieldMask
constupdateMask={
paths:['display_name'],
};
// Build the request.
constsource={
name:sourceName,
displayName:'New Display Name',
};
asyncfunctionupdateSource(){
const[response]=awaitclient.updateSource({updateMask,source});
console.log('Updated Source: %j',response);
}
awaitupdateSource();

Python

defupdate_source(source_name) -> Dict:
"""
 Updates a source's display name.
 Args:
 source_name: is the resource path for a source that has been created
 Returns:
 Dict: returns the details of updated source.
 """
 fromgoogle.cloudimport securitycenter_v2
 fromgoogle.protobufimport field_mask_pb2
 client = securitycenter_v2.SecurityCenterClient()
 # Field mask to only update the display name.
 field_mask = field_mask_pb2.FieldMask(paths=["display_name"])
 # 'source_name' is the resource path for a source that has been
 # created previously (you can use list_sources to find a specific one).
 # Its format is:
 # source_name = "organizations/{organization_id}/sources/{source_id}"
 # e.g.:
 # source_name = "organizations/111122222444/sources/1234"
 updated = client.update_source (
 request={
 "source": {"name": source_name, "display_name": "Updated Display Name"},
 "update_mask": field_mask,
 }
 )
 print(f"Updated Source: {updated}")
 return updated

Get a specific source

Verify that a source is created or updated appropriately by querying Security Command Center with the source's absolute resource name:

gcloud

gcloudsccsourcesdescribeORGANIZATION_ID--source=SOURCE_ID

Replace the following:

  • ORGANIZATION_ID: your organization ID.
  • SOURCE_ID: the source ID.

REST

In the API, make a request to the organizations.sources.get method:

GET https://securitycenter.googleapis.com/v2/organizations/ORGANIZATION_ID/sources/SOURCE_ID

Replace the following:

  • ORGANIZATION_ID: your organization ID.
  • SOURCE_ID: the source ID.

Go

import(
"context"
"fmt"
"io"
securitycenter"cloud.google.com/go/securitycenter/apiv2"
"cloud.google.com/go/securitycenter/apiv2/securitycenterpb"
)
// getSource retrieves a source by its resource name and print it to w.
// sourceName is the full resource name of the source to be updated.
funcgetSource(wio.Writer,sourceNamestring)error{
// sourceName := "organizations/111122222444/sources/1234"
// Instantiate a context and a security service client to make API calls.
ctx:=context.Background()
client,err:=securitycenter.NewClient (ctx)
iferr!=nil{
returnfmt.Errorf("securitycenter.NewClient: %w",err)
}
deferclient.Close ()// Closing the client safely cleans up background resources.
req:=&securitycenterpb.GetSourceRequest{
Name:sourceName,
}
source,err:=client.GetSource(ctx,req)
iferr!=nil{
returnfmt.Errorf("GetSource: %w",err)
}
fmt.Fprintf(w,"Source: %v\n",source.Name )
fmt.Fprintf(w,"Display Name: %v\n",source.DisplayName)
fmt.Fprintf(w,"Description: %v\n",source.Description)
returnnil
}

Java


importcom.google.cloud.securitycenter.v2.GetSourceRequest ;
importcom.google.cloud.securitycenter.v2.SecurityCenterClient ;
importcom.google.cloud.securitycenter.v2.Source ;
importcom.google.cloud.securitycenter.v2.SourceName ;
importjava.io.IOException;
publicclass GetSource{
publicstaticvoidmain(String[]args)throwsIOException{
// TODO: Replace the below variables.
// organizationId: Google Cloud Organization id.
StringorganizationId="{google-cloud-organization-id}";
// Specify the source-id.
StringsourceId="{source-id}";
getSource(organizationId,sourceId);
}
// Demonstrates how to retrieve a specific source.
publicstaticSource getSource(StringorganizationId,StringsourceId)throwsIOException{
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try(SecurityCenterClient client=SecurityCenterClient .create()){
// Start setting up a request to get a source.
SourceName sourceName=SourceName .ofOrganizationSourceName (organizationId,sourceId);
GetSourceRequest request=GetSourceRequest .newBuilder()
.setName(sourceName.toString ())
.build();
// Call the API.
Source response=client.getSource(request);
System.out.println("Source: "+response);
returnresponse;
}
}
}

Node.js

// Imports the Google Cloud client library.
const{SecurityCenterClient}=require('@google-cloud/security-center').v2;
// Create a Security Center client
constclient=newSecurityCenterClient ();
// TODO(developer): Update the following for your own environment.
constorganizationId='1081635000895';
constlocation='global';
asyncfunctioncreateSampleFinding(){
constuuid=require('uuid');
const[source]=awaitclient.createSource({
source:{
displayName:'Customized Display Name V2',
description:'A new custom source that does X',
},
parent:client.organizationPath(organizationId),
});
constsourceId=source.name.split('/')[3];
// Resource name of the new finding's parent. Examples:
// - `organizations/[organization_id]/sources/[source_id]`
// - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]`
constparent=`organizations/${organizationId}/sources/${sourceId}/locations/${location}`;
// The resource this finding applied to. The Cloud Security Command Center UI can link the
// findings for a resource to the corresponding asset of a resource if there are matches.
constresourceName=`//cloudresourcemanager.googleapis.com/organizations/${organizationId}`;
// Unique identifier provided by the client within the parent scope.
// It must be alphanumeric and less than or equal to 32 characters and
// greater than 0 characters in length.
constfindingId=uuid.v4().replace(/-/g,'');
// Get the current timestamp.
consteventDate=newDate();
// Finding category.
constcategory='MEDIUM_RISK_ONE';
// Build the finding request object.
constcreateFindingRequest={
parent:parent,
findingId:findingId,
finding:{
resourceName,
category,
state:'ACTIVE',
// The time associated with discovering the issue.
eventTime:{
seconds:Math.floor(eventDate.getTime()/1000),
nanos:(eventDate.getTime()%1000)*1e6,
},
},
};
awaitclient.createFinding(createFindingRequest);
returnsourceId;
}
constsourceId=awaitcreateSampleFinding();
// Relative resource name of the source. Its format is
// "organizations/[organization_id]/source/[source_id]".
constname=`organizations/${organizationId}/sources/${sourceId}`;
// Build the request.
constgetSourceRequest={
name,
};
asyncfunctiongetSource(){
// Call the API.
const[source]=awaitclient.getSource(getSourceRequest);
console.log('Source: %j',source);
}
awaitgetSource();

Python

defget_source(source_name) -> Dict:
"""
 Gets the details of an existing source.
 Args:
 source_name: is the resource path for a source that has been created
 Returns:
 Dict: returns the details of existing source.
 """
 fromgoogle.cloudimport securitycenter_v2
 client = securitycenter_v2.SecurityCenterClient()
 # 'source_name' is the resource path for a source that has been
 # created previously (you can use list_sources to find a specific one).
 # Its format is:
 # source_name = "organizations/{organization_id}/sources/{source_id}"
 # e.g.:
 # source_name = "organizations/111122222444/sources/1234"
 source = client.get_source (request={"name": source_name})
 print(f"Source: {source}")
 return source

Listing sources

Security Command Center lets you list a specific source, or all sources available in an organization:

REST

In the API, make a request to the organizations.sources.list method:

GET https://securitycenter.googleapis.com/v2/organizations/ORGANIZATION_ID/sources

Replace the following:

  • ORGANIZATION_ID: your organization ID.

Go

import(
"context"
"fmt"
"io"
securitycenter"cloud.google.com/go/securitycenter/apiv2"
"cloud.google.com/go/securitycenter/apiv2/securitycenterpb"
"google.golang.org/api/iterator"
)
// listSources prints all sources in orgID to w. orgID is the numeric
// identifier of the organization.
funclistSources(wio.Writer,orgIDstring)error{
// orgID := "12321311"
// Instantiate a context and a security service client to make API calls.
ctx:=context.Background()
client,err:=securitycenter.NewClient (ctx)
iferr!=nil{
returnfmt.Errorf("securitycenter.NewClient: %w",err)
}
deferclient.Close ()// Closing the client safely cleans up background resources.
req:=&securitycenterpb.ListSourcesRequest{
// Parent must be in one of the following formats:
//		"organizations/{orgId}"
//		"projects/{projectId}"
//		"folders/{folderId}"
Parent:fmt.Sprintf("organizations/%s",orgID),
}
it:=client.ListSources(ctx,req)
for{
source,err:=it.Next()
iferr==iterator.Done {
break
}
iferr!=nil{
returnfmt.Errorf("it.Next: %w",err)
}
fmt.Fprintf(w,"Source Name: %s, ",source.Name )
fmt.Fprintf(w,"Display name: %s, ",source.DisplayName)
fmt.Fprintf(w,"Description: %s\n",source.Description)
}
returnnil
}

Java


importcom.google.cloud.securitycenter.v2.OrganizationLocationName ;
importcom.google.cloud.securitycenter.v2.OrganizationName ;
importcom.google.cloud.securitycenter.v2.SecurityCenterClient ;
importcom.google.cloud.securitycenter.v2.SecurityCenterClient.ListSourcesPagedResponse ;
importcom.google.cloud.securitycenter.v2.Source ;
importjava.io.IOException;
importjava.util.ArrayList;
importjava.util.List;
publicclass ListSources{
publicstaticvoidmain(String[]args)throwsIOException{
// TODO: Replace the below variables.
// organizationId: Google Cloud Organization id.
StringorganizationId="{google-cloud-organization-id}";
listSources(organizationId);
}
// Demonstrates how to list all security sources in an organization.
publicstaticList<Source>listSources(StringorganizationId)throwsIOException{
// Initialize client that will be used to send requests. This client only needs to be created
// once, and can be reused for multiple requests.
try(SecurityCenterClient client=SecurityCenterClient .create()){
// Start setting up a request to get a source.
OrganizationName parent=OrganizationName .of(organizationId);
// Call the API.
List<Source>sourcesList=newArrayList<>();
ListSourcesPagedResponse response=client.listSources(parent);
response.iterateAll().forEach(sourcesList::add);
for(Source source:sourcesList){
System.out.println("List sources: "+source);
}
returnsourcesList;
}
}
}

Node.js

// Imports the Google Cloud client library.
const{SecurityCenterClient}=require('@google-cloud/security-center').v2;
constclient=newSecurityCenterClient ();
// TODO(developer): Update the following for your own environment.
constorganizationId='1081635000895';
// Required. Resource name of the parent of sources to list. Its format should
// be "organizations/[organization_id]", "folders/[folder_id]", or
// "projects/[project_id]".
constparent=`organizations/${organizationId}`;
// Build the request.
constlistSourcesRequest={
parent,
};
asyncfunctionlistAllSources(){
// Call the API.
constiterable=client.listSourcesAsync(listSourcesRequest);
letcount=0;
console.log('Sources:');
forawait(constresponseofiterable){
console.log(`${++count}${response.name}${response.description}`);
}
}
awaitlistAllSources();

Python

deflist_source(organization_id) -> int:
"""
 lists the findings source
 Args:
 organization_id: organization_id is the numeric ID of the organization. e.g.:organization_id = "111122222444"
 Returns:
 Dict: returns the count of the findings source
 """
 count = -1
 fromgoogle.cloudimport securitycenter_v2
 # Create a new client.
 client = securitycenter_v2.SecurityCenterClient()
 # 'parent' must be in one of the following formats:
 # "organizations/{organization_id}"
 # "projects/{project_id}"
 # "folders/{folder_id}"
 parent = f"organizations/{organization_id}"
 # Call the API and print out each existing source.
 for count, source in enumerate(client.list_sources (request={"parent": parent})):
 print(count, source)
 return count

What's next

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025年11月11日 UTC.