Listing security findings using the Security Command Center API

Standard, Premium, and Enterpriseservice tiers

Security Command Center findings model the potential security risks of assets in aproject or an organization. A finding always relates to a specific assetin Security Command Center.

This guide shows you how to use Security Command Center client libraries toaccess findings. Each finding belongs to a source. Mostdetectors or finding providers produce findings within the same source.

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 aboutSecurity Command Center roles, seeAccess control.

Before you begin

Before you set up a source, you need to complete the following:

Page size

All Security Command Center list APIs are paginated. Each response returns a pageof results and a token to return the next page. The page size is configurable.The default page size is 10. You can set it to a minimum of 1, and a maximum of1000.

Findings retention

Depending on your Security Command Center tier, findings remainavailable for you to list or query for specific periods of time. For moreinformation about Security Command Center data retention, seeData retention.

List all findings

gcloud

To list all findings in a project, folder, or organization, run the followingcommand:

gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION

Replace the following:

  • PARENT_TYPE: the level of the resource hierarchy forwhich to list findings; useorganizations,folders, orprojects.
  • PARENT_ID: the numeric ID of the organization,folder, or project, or the alphanumeric project ID.
  • LOCATION:theSecurity Command Center location in which to list findings; if data residency is enabled, useeu,sa, orus; otherwise, use the valueglobal.

For more examples, run:

gcloudsccfindingslist--help

For examples in the documentation, seegcloud scc findings list.

Go

import("context""fmt""io"securitycenter"cloud.google.com/go/securitycenter/apiv2""cloud.google.com/go/securitycenter/apiv2/securitycenterpb""google.golang.org/api/iterator")// listFindings prints all findings in orgID to w. orgID is the numeric// identifier of the organization.funclistFindings(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.ListFindingsRequest{// List findings across all sources.// Parent must be in one of the following formats://"organizations/{orgId}/sources/-/locations/global"//"projects/{projectId}/sources/-/locations/global"//"folders/{folderId}/sources/-/locations/global"Parent:fmt.Sprintf("organizations/%s/sources/-/locations/global",orgID),}it:=client.ListFindings(ctx,req)for{result,err:=it.Next()iferr==iterator.Done{break}iferr!=nil{returnfmt.Errorf("it.Next: %w",err)}finding:=result.Findingfmt.Fprintf(w,"Finding Name: %s, ",finding.Name)fmt.Fprintf(w,"Resource Name %s, ",finding.ResourceName)fmt.Fprintf(w,"Category: %s\n",finding.Category)}returnnil}

Java

importcom.google.cloud.securitycenter.v2.ListFindingsRequest;importcom.google.cloud.securitycenter.v2.ListFindingsResponse.ListFindingsResult;importcom.google.cloud.securitycenter.v2.SecurityCenterClient;importjava.io.IOException;publicclassListAllFindings{publicstaticvoidmain(String[]args)throwsIOException{// organizationId: The source to list all findings for.// You can also use project/ folder as the parent resource.StringorganizationId="google-cloud-organization-id";// Specify the location to list the findings.Stringlocation="global";// The source id to scope the findings.StringsourceId="source-id";listAllFindings(organizationId,sourceId,location);}// List all findings under a given parent resource.publicstaticvoidlistAllFindings(StringorganizationId,StringsourceId,Stringlocation)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(SecurityCenterClientclient=SecurityCenterClient.create()){ListFindingsRequestrequest=ListFindingsRequest.newBuilder()// To list findings across all sources, use "-"..setParent(String.format("organizations/%s/sources/%s/locations/%s",organizationId,sourceId,location)).build();for(ListFindingsResultresult:client.listFindings(request).iterateAll()){System.out.printf("Finding: %s",result.getFinding().getName());}System.out.println("\nListing complete.");}}}

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';// Required. Name of the source the findings belong to. If no location is// specified, the default is global. The following list shows some examples:// - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]`// - `folders/[folder_id]/sources/[source_id]`// - `folders/[folder_id]/sources/[source_id]/locations/[location_id]`// - `projects/[project_id]/sources/[source_id]`// - `projects/[project_id]/sources/[source_id]/locations/[location_id]`// To groupBy across all sources provide a source_id of `-`.constparent=`organizations/${organizationId}/sources/-/locations/${location}`;// Build the list findings request.constlistFindingsRequest={parent,};asyncfunctionlistAllFindings(){// Call the API.constiterable=client.listFindingsAsync(listFindingsRequest);letcount=0;forawait(constresponseofiterable){// Just print a few for demonstration.if(count >5)break;console.log(`${++count}${response.finding.name}${response.finding.resourceName}`);}}awaitlistAllFindings();

Python

deflist_all_findings(organization_id,source_name,location_id)->int:"""    lists all findings for a source    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       location_id: GCP location id; example: 'global'    Returns:        int: returns the count of all findings for a source    """fromgoogle.cloudimportsecuritycenter_v2# Create a client.client=securitycenter_v2.SecurityCenterClient()parent=f"organizations/{organization_id}"all_sources=f"{parent}/sources/{source_name}/locations/{location_id}"# Create the request dictionaryrequest={"parent":all_sources}# Print the request for debuggingprint("Request: ",request)finding_result_iterator=client.list_findings(request={"parent":all_sources})forcount,finding_resultinenumerate(finding_result_iterator):print("{}: name:{} resource:{}".format(count,finding_result.finding.name,finding_result.finding.resource_name))returnfinding_result_iterator

The output for each finding resembles the following:

{"finding":{"name":"organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID","parent":"organizations/ORGANIZATION_ID/sources/SOURCE_ID","resourceName":"//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER","state":"ACTIVE","category":"Malware: Cryptomining Bad Domain","sourceProperties":{"sourceId":{"projectNumber":"PROJECT_NUMBER","customerOrganizationNumber":"ORGANIZATION_ID"},"detectionCategory":{"technique":"cryptomining","indicator":"domain","ruleName":"bad_domain","subRuleName":"cryptomining"},"detectionPriority":"LOW","affectedResources":[{"gcpResourceName":"//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER"}],"evidence":[{"sourceLogId":{"projectId":"PROJECT_ID","resourceContainer":"projects/PROJECT_ID","timestamp":{"seconds":"1636566099","nanos":5.41483849E8},"insertId":"INSERT_ID"}}],"properties":{"domains":["DOMAIN"],"instanceDetails":"/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_ID","network":{"project":"PROJECT_ID","location":"ZONE"},"dnsContexts":[{"authAnswer":true,"sourceIp":"SOURCE_IP_ADDRESS","queryName":"DOMAIN","queryType":"A","responseCode":"NXDOMAIN"}],"vpc":{"vpcName":"default"}},"findingId":"FINDING_ID","contextUris":{"mitreUri":{"displayName":"MITRE Link","url":"https://attack.mitre.org/techniques/T1496/"},"virustotalIndicatorQueryUri":[{"displayName":"VirusTotal Domain Link","url":"https://www.virustotal.com/gui/domain/DOMAIN/detection"}],"cloudLoggingQueryUri":[{"displayName":"Cloud Logging Query Link","url":"https://console.cloud.google.com/logs/query;query\u003dtimestamp%3D%222021-11-10T17:41:39.541483849Z%22%0AinsertId%3D%22INSERT_ID%22%0Aresource.labels.project_id%3D%22PROJECT_ID%22?project\u003dPROJECT_ID"}],"relatedFindingUri":{}}},"securityMarks":{"name":"organizations/ORGANIZATION_ID/sources/SOURCE_ID/findings/FINDING_ID/securityMarks"},"eventTime":"2021-11-10T17:41:41.594Z","createTime":"2021-11-10T17:41:42.014Z","severity":"LOW","workflowState":"NEW","canonicalName":"projects/PROJECT_NUMBER/sources/SOURCE_ID/findings/FINDING_ID","mute":"UNDEFINED","findingClass":"THREAT","indicator":{"domains":["DOMAIN"]}},"resource":{"name":"//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER","projectName":"//cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER","projectDisplayName":"PROJECT_ID","parentName":"//cloudresourcemanager.googleapis.com/organizations/ORGANIZATION_ID","parentDisplayName":"PARENT_NAME","type":"google.cloud.resourcemanager.Project","displayName":"PROJECT_ID"}}

Filter findings

A project, folder, or organization might have many findings. The precedingexample doesn't use a filter, so all finding records are returned.

To help you get information about only the fields you want, you can usefinding filters. These filters are like "where" clauses in SQL statements, butinstead of columns, they apply to the objects returned by the API.

The following example lists only the findings that have a category"MEDIUM_RISK_ONE". Different finding providers (also known assecuritysources) use different sets ofcategories. To determine the categories you can use in your filter, refer to thedocumentation of the finding provider.

gcloud

Use the following command to filter findings:

gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="FILTER"

Replace the following:

  • PARENT_TYPE: the level of the resource hierarchy forwhich to list findings; useorganizations,folders, orprojects.
  • PARENT_ID: the numeric ID of the organization,folder, or project, or the alphanumeric project ID.
  • LOCATION:theSecurity Command Center location in which to list findings with a filter; if data residency is enabled, useeu,sa, orus; otherwise, use the valueglobal.
  • SOURCE_ID: the ID of the security source thatprovides the finding type.
  • FILTER: the filter you need to use. For example,the following filter returns findings from the category ofMEDIUM_RISK_ONE only:
    --filter="category=\"MEDIUM_RISK_ONE\""

For more examples, run:

gcloudsccfindingslist--help

For examples in the documentation, seegcloud scc findings list.

Go

import("context""fmt""io"securitycenter"cloud.google.com/go/securitycenter/apiv2""cloud.google.com/go/securitycenter/apiv2/securitycenterpb""google.golang.org/api/iterator")// listFilteredFindings prints findings with category 'MEDIUM_RISK_ONE' for a// specific source to w. sourceName is the full resource name of the source// to search for findings under.funclistFilteredFindings(wio.Writer,sourceNamestring)error{// Specific source:// sourceName := "{parent}/sources/{sourceId}"// All sources:// sourceName := "{parent}/sources/-"// where,// Parent must be in one of the following formats://"organizations/{orgId}"//"projects/{projectId}"//"folders/{folderId}"// 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.ListFindingsRequest{Parent:sourceName,Filter:`category="MEDIUM_RISK_ONE"`,}it:=client.ListFindings(ctx,req)for{result,err:=it.Next()iferr==iterator.Done{break}iferr!=nil{returnfmt.Errorf("it.Next: %w",err)}finding:=result.Findingfmt.Fprintf(w,"Finding Name: %s, ",finding.Name)fmt.Fprintf(w,"Resource Name %s, ",finding.ResourceName)fmt.Fprintf(w,"Category: %s\n",finding.Category)}returnnil}

Java

importcom.google.cloud.securitycenter.v2.ListFindingsRequest;importcom.google.cloud.securitycenter.v2.ListFindingsResponse.ListFindingsResult;importcom.google.cloud.securitycenter.v2.SecurityCenterClient;importjava.io.IOException;publicclassListFindingsWithFilter{publicstaticvoidmain(String[]args)throwsIOException{// TODO: Replace the variables within {}// organizationId: Google Cloud Organization id.// You can also use project/ folder as the parent resource.StringorganizationId="google-cloud-organization-id";// Specify the location to list the findings.Stringlocation="global";// The source id to scope the findings.StringsourceId="source-id";listFilteredFindings(organizationId,sourceId,location);}// List filtered findings under a source.publicstaticvoidlistFilteredFindings(StringorganizationId,StringsourceId,Stringlocation)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(SecurityCenterClientclient=SecurityCenterClient.create()){// Use any one of the following formats://  * organizations/{organization_id}/sources/{source_id}/locations/{location}//  * folders/{folder_id}/sources/{source_id}/locations/{location}//  * projects/{project_id}/sources/{source_id}/locations/{location}Stringparent=String.format("organizations/%s/sources/%s/locations/%s",organizationId,sourceId,location);// Listing all findings of category "MEDIUM_RISK_ONE".Stringfilter="category=\"MEDIUM_RISK_ONE\"";ListFindingsRequestrequest=ListFindingsRequest.newBuilder().setParent(parent).setFilter(filter).build();for(ListFindingsResultresult:client.listFindings(request).iterateAll()){System.out.printf("Finding: %s",result.getFinding().getName());}System.out.println("\nListing complete.");}}}

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';// Required. Name of the source to groupBy. If no location is specified,// finding is assumed to be in global.//  The following list shows some examples:// - `organizations/[organization_id]/sources/[source_id]`// - `organizations/[organization_id]/sources/[source_id]/locations/[location_id]`// - `folders/[folder_id]/sources/[source_id]`// - `folders/[folder_id]/sources/[source_id]/locations/[location_id]`// - `projects/[project_id]/sources/[source_id]`// - `projects/[project_id]/sources/[source_id]/locations/[location_id]`// To groupBy across all sources provide a source_id of `-`.constparent=`organizations/${organizationId}/sources/-/locations/${location}`;// Listing all findings of category "MEDIUM_RISK_ONE".constfilter='category="MEDIUM_RISK_ONE"';// Build the list findings with filter request.constlistFilteredFindingsRequest={parent,filter,};asyncfunctionlistFilteredFindings(){// Call the API.constiterable=client.listFindingsAsync(listFilteredFindingsRequest);letcount=0;console.log('Findings:');forawait(constresponseofiterable){// Just print a few for demonstration.if(count >5)break;console.log(`${++count}${response.finding.name}${response.finding.resourceName}`);}}awaitlistFilteredFindings();

Python

deflist_filtered_findings(organization_id,source_name,location_id)->int:"""    lists filtered findings for a source    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        location_id: GCP location id; example: 'global'    Returns:         int: returns the filtered findings for a source    """count=0fromgoogle.cloudimportsecuritycenter_v2# Create a new client.client=securitycenter_v2.SecurityCenterClient()parent=f"organizations/{organization_id}"all_sources=f"{parent}/sources/{source_name}/locations/{location_id}"finding_result_iterator=client.list_findings(request={"parent":all_sources,"filter":'severity="LOW"'})# Iterate an print all finding names and the resource they are# in reference to.forcount,finding_resultinenumerate(finding_result_iterator):print("{}: name:{} resource:{}".format(count,finding_result.finding.name,finding_result.finding.resource_name))returncount

Security Command Center also supports full JSON arrays and objects as potentialproperty types. You can filter on:

  • Array elements
  • Full JSON objects with partial string match within the object
  • JSON object subfields

Supported operators

The query statements for Security Command Center findings support theoperators that most Google Cloud APIs support.

The following list shows the use of various operators:

  • state="ACTIVE"AND NOT mute="MUTED"
  • create_time>"2023-08-15T19:05:32.428Z"
  • resource.parent_name:"prod"
  • severity="CRITICAL"OR severity="HIGH"

The following list shows all of the operators and functions that aresupported in query statements for findings:

  • For strings:

    • = for an exact match

      For example,resource.parent_name="prod" matches the valueprod. Itdoesn't matchproduction orcanaryprod.

    • : for a partial match

      For example,resource.parent_name:"prod" matches the valuesprod,production, andcanaryprod.

  • For numbers (except int64):

    • <,>,<=,>= for inequalities
    • =,!= for equality
  • For numbers (int 64):

    • =,!= for equality
  • For booleans:

    • = for equality
  • For logical relationships:

    • AND
    • OR
    • NOT or-
  • For grouping expressions:

    • (,) (parentheses)
  • For arrays:
    • contains(), a function forquerying findings with an array field that contains at least one elementthat matches the specified filter
    • containsOnly(), afunction for querying findings with an array field that only containselements that match the specified filter
  • For IP addresses:
    • inIpRange(), a functionfor querying IP addresses within a specified CIDR range

Filtering on IP addresses

Certain finding properties include IP addresses. You can filter findingsbased on specific IP addresses or a range of IP addresses.

IP addresses appear as strings in a variety of findings and finding properties,including the following:

  • access.caller_ip
  • connections.destinationIp
  • connections.sourceIp
  • indicator.ip_addresses

To filter on a specific IP address, you can use the equality operator,as shown in the following example:

access.caller_ip="192.0.2.0"

To filter findings based on a range of IP addresses, use theinIpRangefunction. Using theinIpRange function, you filter findings to only thosefindings that contain a IP address within a specified CIDR range. By usingtheNOT operation withinIpRange, you can filter findings to only thosefindings that contain an IP address outside of the specified CIDR range.

The following example shows the syntax of theinIpRange function:

inIpRange(IP_FINDING_FIELD, "CIDR_RANGE")

If the IP address is in an array element in a finding field that containsan array, use the following syntax with bothcontains function andtheinIpRange function:

contains(ATTRIBUTE_WITH_ARRAY, inIpRange(IP_FINDING_FIELD, "CIDR_RANGE"))

In the following example, theinIpRange function evaluates eachdestination_ip element of the array that is contained in theconnectionsfinding field for an IP address that is in the CIDR range defined by192.0.2.0/24:

contains(connections, inIpRange(destination_ip, "192.0.2.0/24"))

The following example shows a gcloud CLI command thatuses theinIpRange function to filter findings that have an IPaddress in theconnections.source_ip field that is within one range,but not in another. Theconnections field is anarray-type field,so thecontains function is used:

gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="contains(connections, inIpRange(source_ip, \"2001:db8::/32\")) \      AND NOT contains(connections, inIpRange(source_ip, \"192.0.2.0/24\"))"

Example JSON object

The examples later on this page assume the following JSON object is a findingattribute:

{"outer_object":{"middle_object":{"deeply_nested_object":{"x":123},"y":"some-string-value"},"list_middle_object":[{"v":321,"w":[{"a":3,"b":4}]}],"z":"some-other-string-value","u":["list-element-1","list-element-2","list-element-3"]}}

Filtering findings example

Suppose theprevious JSON example is a finding attributenamedmy_property. The following example includes queries for findingsthat have the object as a property. You can also use these filters with otherfilters usingAND andOR in your query. For example, the first query usestheACTIVE filter to display active findings.

gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="state=\"ACTIVE\""--filter="my_property.outer_object.middle_object.deeply_nested_object.x = 123"gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="my_property.outer_object.middle_object.y = \"some-string-value\""gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="my_property.outer_object.middle_object.y : \"string-value\""gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="my_property.outer_object.z = \"some-other-string-value\""gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="my_property.outer_object.z : \"other-string-value\""gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="my_property.outer_object.u : \"list-element-1\""gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="my_property.outer_object.u : \"list-element-2\""gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="my_property.outer_object.u : \"list-element-3\""

Note: If you want to use these filters in the Google Cloud console,don't include the escape characters. For example, instead of\"string-value\", use"string-value".

Subfilters for array-type fields

When callingListFindings,you can use a substring match:, which does a single check for a partialstring match across the entire contents of the array. Alternatively, you can runa subfilter directly against elements of the array and its subfields using oneof the following functions:

  • Thecontains() function to return findings when any elements of thearray contains the specified value.

  • ThecontainsOnly() function to return findings only if all elements of thearray match the subfilter.

Both of these functions support subfilter query capabilities such as thefollowing:

  • Exact element matching: Match array elements that contain the exact string,"example".
  • Specific number operations: Match array elements that are greater than or equalto100.
  • Complex filtering against array structures: Match array elements that containpropertyx with a corresponding valuey.

Format of thecontains() function

Thecontains() function has the following format:

contains(ARRAY_ATTRIBUTE_NAME,SUBFILTER)

Replace the following:

  • ARRAY_ATTRIBUTE_NAME: a field or subfield that is oftype array (a list).
  • SUBFILTER: an expression that defines the values tolook for in the array. The subfilter's format differs depending on whetherARRAY_ATTRIBUTE_NAME is anarray of objects or anarray of primitive-typeelements. If theARRAY_ATTRIBUTE_NAME is an array of objects that havenested arrays, you can use ascoped subfilter to specifythat you want all conditions to be satisfied within the sameARRAY_ATTRIBUTE_NAME element.

The Security Command Center API returns findings where theARRAY_ATTRIBUTE_NAME contains at least one element thatsatisfies theSUBFILTER.

Note: If you want to use these filters in the Google Cloud console,don't include the escape characters. For example, instead of\"string-value\", use"string-value".

Format of thecontainsOnly() function

ThecontainsOnly() function has the following format:

containsOnly(ARRAY_ATTRIBUTE_NAME,SUBFILTER)

Replace the following:

The Security Command Center API returns findings where all of theARRAY_ATTRIBUTE_NAME elements match theSUBFILTER.

Note: If you want to use these filters in the Google Cloud console,don't include the escape characters. For example, instead of\"string-value\", use"string-value".

Subfilter for an array of objects

The following is an excerpt of theprevious JSON example. Here, thelist_middle_object field is an array of objects:

"list_middle_object":[{"v":321,"w":[{"a":3,"b":4}]}]

The following example queries for findings where at least one of theelements in thelist_middle_object field has av subfieldwith a value greater than or equal to 321:

gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="contains(my_property.outer_object.list_middle_object, v  >= 321)"

For practical examples that use thecontains() andcontainsOnly() functions,seeFindings that contain specific arrayvalues.

Subfilter for an array that contains primitive-type elements

Primitive types are strings, numbers, and booleans. To use thecontains() functionagainst an array that contains primitive types, you use the special keyword,elem.

The following is an excerpt of theprevious JSON example. Here, theu fieldis an array of primitive-type elements:

"u":["list-element-1","list-element-2","list-element-3"]

The following example queries for findings where at least one of theelements in theu field is "list-element-1":

gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="contains(my_property.outer_object.u, elem = \"list-element-1\")"

For practical examples that use thecontains() function, seeFindings that contain specific array values.

Scoped subfilter

The following is an excerpt of theprevious JSON example. Here, thelist_middle_object field is an array of objects, and objects in this arraycontain a nested array.

"list_middle_object":[{"v":321,"w":[{"a":3,"b":4}]}]

The following example queries for findings where both of the following conditionsare satisfied within the samelist_middle_object element:

  • Thev subfield has a value greater than or equal to 321.
  • Thew subfield doesn't contain an element with ana property equal to 3.
gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--filter="contains(my_property.outer_object.list_middle_object, v  >= 321 AND -contains(w, a = 3))"

For practical examples that use thecontains() function, seeFindings that contain specific array values.

Sorting findings example

You can sort findings by strict subfields that are primitive types—strings,numbers, and booleans. Suppose theprevious JSON example is afinding attribute namedmy_property. The following example includesqueries to sort the finding fields. The keywordDESC specifies that the fieldit follows must be sorted in descending order. The default order is ascending.

gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--order-by="my_property.outer_object.middle_object.deeply_nested_object.x DESC"gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--order-by="my_property.outer_object.middle_object.deeply_nested_object.x"gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--order-by="my_property.outer_object.middle_object.y DESC"gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--order-by="my_property.outer_object.middle_object.y"gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--order-by="my_property.outer_object.z DESC"gcloudsccfindingslistPARENT_TYPE/PARENT_ID\--location=LOCATION\--source=SOURCE_ID\--order-by="my_property.outer_object.z"

Filter examples

The following sections show practical examples of finding filters.

Note: If you want to use these filters in the Google Cloud console,don't include the escape characters. For example, instead of\"string-value\", use"string-value".

Filter for findings that occurred after a point in time

These example filters match findings that most recently occurred afterWednesday, June 5, 2019 10:12:05 PM GMT. With theevent_time filter, you canexpress time using the following formats and types:

Filter on array-type fields

The following example shows the use of a partial string match on an array-typefield within a filter:

"indicator.domains : \"website.com\""

The Security Command Center API returns any finding with awebsite.com partial string within thearray. For example, it matches a finding withindicator.domains = [\"onewebsite.com\"] because "website.com" is a substringin an element in the array.

In the following sections, the example filters show some options for use of richarray-type filtering using thecontains() function.

Filter on thevulnerability.cve.references field

The following example returns findings where at least one element in thevulnerability.cve.references array has both asource property equal toSOURCE_OF_REFERENCE and auri property that hasFILTERED_URI.

"contains(vulnerability.cve.references, source = \"SOURCE_OF_REFERENCE\" AND uri : \"FILTERED_URI\")"

Replace the following:

Filter on theindicator.domains field

The following example returns findings where at least one indicator domainhas bothmycompanyprefix and.ca.

"contains(indicator.domains, elem : \"mycompanyprefix\" AND elem : \".ca\")"

Filter on theindicator.ip_addresses field

The following example returns findings where at least one element in theindicator.ip_addresses array is equal toIP_ADDRESS.

"contains(indicator.ip_addresses, elem = \"IP_ADDRESS\")"

ReplaceIP_ADDRESS with an IP address associated withthe findings you're searching for.

Filter on external system assignees

The following example returns findings where at least one element in theexternal_systems.EXTERNAL_SYSTEM_NAME.assignees array isequal toASSIGNEE.

"contains(external_systems.EXTERNAL_SYSTEM_NAME.assignees, elem = \"ASSIGNEE\")"

Replace the following:

  • EXTERNAL_SYSTEM_NAME: the name of a third-partySIEM/SOAR system—for example,demisto.
  • ASSIGNEE: an assignee in the external system.

Filter on theresource.folders.resource_folder field

The following example returns findings where at least one element in theresource.folders.resource_folder array is not equal toFOLDER_NAME.

"contains(resource.folders.resource_folder, -(elem = \"FOLDER_NAME\"))"

Filter on theresource.folders.resource_folder_display_name field

The following example returns findings where at least one element in theresource.folders.resource_folder_display_name array is equal toDISPLAY_NAME.

"contains(resource.folders.resource_folder_display_name, elem = \"DISPLAY_NAME\")"

ReplaceDISPLAY_NAME with the user-defined name of thefolder associated with the findings you're searching for.

Filter includes only specific service accounts

The following example returns findings only when everyiam_bindings entry'smember value is equal to one of the provided service accounts.

containsOnly(iam_bindings, (member =SERVICE_ACCOUNT1 OR member =SERVICE_ACCOUNT2 OR member = "SERVICE_ACCOUNT3 "))

ReplaceSERVICE_ACCOUNT1,SERVICE_ACCOUNT2, andSERVICE_ACCOUNT3 with the email addresses for theservice accounts.

To learn how to use thecontains() andcontainsOnly() functions in a findingfilter, seeSubfilters for array-type fields.

What's next

Learn more aboutsetting up finding notifications.

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

Last updated 2025-12-17 UTC.