Managing findings using the Security Command Center API

This guide walks you through creating and updating findings using the Security Command Center API.

Before you begin

Before you create and update findings, you need to complete the following:

To complete this guide, you must have the Identity and Access Management (IAM) Security Center Findings Editor (securitycenter.findingsEditor) role at the organization level. For more information on Security Command Center roles, see Access control.

If you want to create findings with security marks, you must also have an IAM role that includes permissions for the kind of mark that you want to use:

  • Asset Security Marks Writer (securitycenter.assetSecurityMarksWriter)
  • Finding Security Marks Writer (securitycenter.findingSecurityMarksWriter)

For more information about marks, see Using Security Command Center security marks.

Creating a finding

Create an active finding for a source.

gcloud

gcloudsccfindingscreateFINDING_NAME\
--organization=PARENT_ID\
--location=LOCATION\
--source=SOURCE_ID\
--state=STATE\
--category=CATEGORY\
--event-time=EVENT_TIME\
--resource-name=RESOURCE_NAME

Replace the following:

  • FINDING_NAME: the name of the finding.
  • PARENT_ID: the numeric ID of the parent organization.
  • LOCATION: the Security Command Center location in which to create a finding; if data residency is enabled, use eu, sa, or us; otherwise, use the value global.
  • SOURCE_ID: the numeric ID of the source for the finding.
  • STATE: the state of the finding; use ACTIVE if the finding needs attention or INACTIVE if the finding has been addressed.
  • CATEGORY: the taxonomy group that the finding belongs to; for example, AUDIT_LOGGING_DISABLED.
  • EVENT_TIME: the time when the event occurred, formatted as an RFC 822 timestamp or another timestamp format that the gcloud CLI supports.
  • RESOURCE_NAME: the full resource name of the resource that the finding applies to.

Go

import(
"context"
"fmt"
"io"
"time"
securitycenter"cloud.google.com/go/securitycenter/apiv2"
"cloud.google.com/go/securitycenter/apiv2/securitycenterpb"
"github.com/golang/protobuf/ptypes"
)
// createFinding demonstrates how to create a new security finding in CSCC.
// sourceName is the full resource name of the source the finding should
// be associated with.
funccreateFinding(wio.Writer,sourceNamestring)error{
// sourceName := "organizations/111122222444/sources/1234/locations/global"
// 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.
// Use now as the eventTime for the security finding.
eventTime,err:=ptypes.TimestampProto(time.Now())
iferr!=nil{
returnfmt.Errorf("TimestampProto: %w",err)
}
req:=&securitycenterpb.CreateFindingRequest{
Parent:sourceName,
FindingId:"samplefindingid",
Finding:&securitycenterpb.Finding{
State:securitycenterpb.Finding_ACTIVE ,
// Resource the finding is associated with. This is an
// example any resource identifier can be used.
ResourceName:"//cloudresourcemanager.googleapis.com/organizations/11232/sources/-/locations/global",
// A free-form category.
Category:"MEDIUM_RISK_ONE",
// The time associated with discovering the issue.
EventTime:eventTime,
},
}
finding,err:=client.CreateFinding(ctx,req)
iferr!=nil{
returnfmt.Errorf("CreateFinding: %w",err)
}
fmt.Fprintf(w,"New finding created: %s\n",finding.Name )
fmt.Fprintf(w,"Event time (Epoch Seconds): %d\n",eventTime.Seconds)
returnnil
}

Java


importcom.google.cloud.securitycenter.v2.CreateFindingRequest ;
importcom.google.cloud.securitycenter.v2.Finding ;
importcom.google.cloud.securitycenter.v2.Finding.FindingClass ;
importcom.google.cloud.securitycenter.v2.Finding.Mute ;
importcom.google.cloud.securitycenter.v2.Finding.Severity ;
importcom.google.cloud.securitycenter.v2.Finding.State;
importcom.google.cloud.securitycenter.v2.SecurityCenterClient ;
importcom.google.cloud.securitycenter.v2.SourceName ;
importcom.google.protobuf.Timestamp ;
importjava.io.IOException;
importjava.time.Instant;
importjava.util.Optional;
importjava.util.UUID;
publicclass CreateFindings{
publicstaticvoidmain(String[]args)throwsIOException{
// TODO: Replace the sample resource name
// organizationId: Google Cloud Organization id.
StringorganizationId="{google-cloud-organization-id}";
// Specify the location to list the findings.
Stringlocation="global";
// The source id corresponding to the finding.
StringsourceId="{source-id}";
// The finding id.
StringfindingId="testfindingv2"+UUID.randomUUID().toString().split("-")[0];
// Specify the category.
Optional<String>category=Optional.of("MEDIUM_RISK_ONE");
createFinding(organizationId,location,findingId,sourceId,category);
}
/**
 * Creates a security finding within a specific source in the Security Command Center.
 */
publicstaticFinding createFinding(StringorganizationId,Stringlocation,StringfindingId,
StringsourceId,Optional<String>category)throwsIOException{
try(SecurityCenterClient client=SecurityCenterClient .create()){
// Optionally SourceName or String can be used.
// String sourceName = String.format("organizations/%s/sources/%s", organizationId, sourceId);
SourceName sourceName=SourceName .of(organizationId,sourceId);
InstanteventTime=Instant.now();
// The resource this finding applies 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.
StringresourceName=String.format("//cloudresourcemanager.googleapis.com/organizations/%s",
organizationId);
// Set up a request to create a finding in a source.
Stringparent=String.format("%s/locations/%s",sourceName.toString (),location);
Finding finding=Finding .newBuilder()
.setParent(parent)
.setState(State.ACTIVE)
.setSeverity (Severity .LOW)
.setMute(Mute .UNMUTED)
.setFindingClass (FindingClass .OBSERVATION)
.setResourceName (resourceName)
.setEventTime(Timestamp .newBuilder()
.setSeconds(eventTime.getEpochSecond())
.setNanos(eventTime.getNano()))
.setCategory (category.orElse("LOW_RISK_ONE"))
.build();
CreateFindingRequest createFindingRequest=CreateFindingRequest .newBuilder()
.setParent(parent)
.setFindingId (findingId)
.setFinding(finding).build();
// Call the API.
Finding response=client.createFinding(createFindingRequest);
returnresponse;
}
}
}

Node.js

// Imports the Google Cloud client library.
const{SecurityCenterClient}=require('@google-cloud/security-center').v2;
constuuid=require('uuid');
// Create a Security Center client
constclient=newSecurityCenterClient ();
// TODO(developer): Update the following for your own environment.
constorganizationId='1081635000895';
constlocation='global';
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 applies 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,
},
},
};
// Call the API.
const[finding]=awaitclient.createFinding(createFindingRequest);
console.log('New finding created: %j',finding);

Python

defcreate_finding(
 organization_id, location_id, finding_id, source_name, category
) -> Dict:
"""
 cretaes a new finding
 Args:
 organization_id: organization_id is the numeric ID of the organization. e.g.:organization_id = "111122222444"
 source_name: is the resource path for a source that has been created
 finding_id: unique identifier provided by the client.
 location_id: GCP location id; example: 'global'
 category: the additional category group with in findings.
 Returns:
 Dict: returns the created findings details.
 """
 importdatetime
 fromgoogle.cloudimport securitycenter_v2
 fromgoogle.cloud.securitycenter_v2import Finding
 # Create a new client.
 client = securitycenter_v2.SecurityCenterClient()
 # Use the current time as the finding "event time".
 event_time = datetime.datetime.now(tz=datetime.timezone.utc)
 # '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_name = f"organizations/{organization_id}/sources/{source_name}"
 # category= "MEDIUM_RISK_ONE"
 # The resource this finding applies to. The CSCC UI can link
 # the findings for a resource to the corresponding Asset of a resource
 # if there are matches.
 resource_name = (
 f"//cloudresourcemanager.googleapis.com/organizations/{organization_id}"
 )
 finding = Finding(
 state=Finding.State.ACTIVE,
 resource_name=resource_name,
 category=category,
 event_time=event_time,
 )
 parent = source_name + "/locations/" + location_id
 # Call The API.
 created_finding = client.create_finding (
 request={"parent": parent, "finding_id": finding_id, "finding": finding}
 )
 print(created_finding)
 return created_finding

For information on how long findings data is stored in Security Command Center, read Findings retention.

Updating a finding's state

Security Command Center also provides an API to only update a finding's state. The following example shows how to change a finding's state to inactive.

gcloud

gcloudsccfindingsupdate\
PARENT/PARENT_ID/sources/SOURCE_ID/locations/LOCATION/findings/FINDING_NAME\
--state=STATE

Replace the following:

  • PARENT: the level of the resource hierarchy where the finding is located; use organizations, folders, or projects.
  • PARENT_ID: the numeric ID of the parent organization, folder, or project, or the alphanumeric ID of the parent project.
  • SOURCE_ID: the numeric ID of the source for the finding.
  • LOCATION: the Security Command Center location in which to update a finding; if data residency is enabled, use eu, sa, or us; otherwise, use the value global.
  • FINDING_NAME: the finding to update.
  • STATE: the state of the finding; use ACTIVE if the finding needs attention or INACTIVE if the finding has been addressed.

Go

import(
"context"
"fmt"
"io"
securitycenter"cloud.google.com/go/securitycenter/apiv2"
"cloud.google.com/go/securitycenter/apiv2/securitycenterpb"
)
// updateFindingState demonstrates how to update a security finding's state
// in CSCC. findingName is the full resource name of the finding to update.
funcsetFindingState(wio.Writer,findingNamestring)error{
// findingName := "organizations/111122222444/sources/1234/locations/global"
// 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.SetFindingStateRequest{
Name:findingName,
State:securitycenterpb.Finding_INACTIVE ,
// New state is effective immediately.
}
finding,err:=client.SetFindingState(ctx,req)
iferr!=nil{
returnfmt.Errorf("SetFindingState: %w",err)
}
fmt.Fprintf(w,"Finding updated: %s\n",finding.Name )
fmt.Fprintf(w,"Finding state: %v\n",finding.State)
fmt.Fprintf(w,"Event time (Epoch Seconds): %d\n",finding.EventTime.Seconds)
returnnil
}

Java


importcom.google.cloud.securitycenter.v2.Finding ;
importcom.google.cloud.securitycenter.v2.Finding.State;
importcom.google.cloud.securitycenter.v2.FindingName ;
importcom.google.cloud.securitycenter.v2.SecurityCenterClient ;
importcom.google.cloud.securitycenter.v2.SetFindingStateRequest ;
importjava.io.IOException;
publicclass SetFindingsByState{
publicstaticvoidmain(String[]args)throwsIOException{
// organizationId: Google Cloud Organization id.
StringorganizationId="{google-cloud-organization-id}";
// Specify the location to list the findings.
Stringlocation="global";
// The source id corresponding to the finding.
StringsourceId="{source-id}";
// The finding id.
StringfindingId="{finding-id}";
setFindingState(organizationId,location,sourceId,findingId);
}
// Demonstrates how to update a finding's state
publicstaticFinding setFindingState(StringorganizationId,Stringlocation,StringsourceId,
StringfindingId)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()){
// Optionally FindingName or String can be used.
// String findingName = String.format("organizations/%s/sources/%s/locations/%s/findings/%s",
// organizationId,sourceId,location,findingId);
FindingName findingName=FindingName
.ofOrganizationSourceLocationFindingName (organizationId,sourceId,location,findingId);
SetFindingStateRequest request=SetFindingStateRequest .newBuilder()
.setName(findingName.toString ())
.setState(State.INACTIVE)
.build();
// Call the API.
Finding finding=client.setFindingState(request);
System.out.println("Updated Finding: "+finding);
returnfinding;
}
}
}

Node.js

// Imports the Google Cloud client library.
const{SecurityCenterClient}=require('@google-cloud/security-center').v2;
// Creates a new 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);
return{sourceId,findingId};
}
const{sourceId,findingId}=awaitcreateSampleFinding();
// The name is the full resource name of the source the finding should be associated with.
constname=`organizations/${organizationId}/sources/${sourceId}/locations/${location}/findings/${findingId}`;
// Build the request.
consteventTime=newDate();
constfindingRequest={
name,
state:'INACTIVE',
// use now as the time when the new state takes effect.
startTime:{
seconds:Math.floor(eventTime.getTime()/1000),
nanos:(eventTime.getTime()%1000)*1e6,
},
};
asyncfunctionsetFindingState(){
// Call the API.
const[response]=awaitclient.setFindingState(findingRequest);
console.log('Set finding state: %j',response);
}
awaitsetFindingState();

What's next

Learn more about accessing Security Command Center using client libraries.

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月24日 UTC.