Security Command Center findings model the potential security risks of assets in a project or an organization. A finding always relates to a specific asset in Security Command Center.
This guide shows you how to use Security Command Center client libraries to access findings. Each finding belongs to a source. Most detectors 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 about Security Command Center roles, see Access 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 page of 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 of 1000.
Findings retention
A finding remains available for you to list or query for at least 13 months.
Security Command Center stores snapshots of each finding. A snapshot of a finding is retained for at least 13 months. If all snapshots for a finding are deleted, the finding can no longer be listed or recovered.
For more information about Security Command Center data retention, see Data retention.
List all findings
gcloud
To list all findings in a project, folder, or organization, run the following command:
gcloud scc findings list PARENT_ID
Replace PARENT_ID
with one of the following values:
- An organization ID in the following format:
ORGANIZATION_ID
(the numerical ID only) - A folder ID in the following format:
folders/FOLDER_ID
- A project ID in the following format:
projects/PROJECT_ID
For more examples, run:
gcloud scc findings list --help
For examples in the documentation, see gcloud scc findings list.
Python
Java
Go
Node.js
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 preceding example doesn't use a filter, so all finding records are returned. Security Command Center enables you to use finding filters to get information about only the findings you want.
Finding filters are like "where" clauses in SQL statements, but instead 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 as security
sources) use different sets of
categories. To determine the categories you can use in your filter, refer to the
documentation of the finding provider.
gcloud
Use the following command to filter findings:
gcloud scc findings list PARENT_ID --source=SOURCE_ID --filter="FILTER"
Replace the following:
FILTER
with 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\""
PARENT_ID
with one of the following values:- An organization ID in the following format:
ORGANIZATION_ID
(the numerical ID only) - A project ID in the following format:
projects/PROJECT_ID
- A folder ID in the following format:
folders/FOLDER_ID
- An organization ID in the following format:
SOURCE_ID
with the ID of the security source that provides the finding type.
For more examples, run:
gcloud scc findings list --help
For examples in the documentation, see gcloud scc findings list.
Python
Java
Go
Node.js
Security Command Center also supports full JSON arrays and objects as potential property types. You can filter on:
- Array elements
- Full JSON objects with partial string match within the object
- JSON object subfields
Supported operators
Finding filters support common operators, including the following:
- Strings:
- Full equality
=
- Partial string matching
:
- Full equality
- Numbers:
- Inequalities
<
,>
,<=
,>=
- Equality
=
- Inequalities
- Booleans:
- Equality
=
- Equality
- Logical operators:
AND
OR
- Negation
-
Example JSON object
The examples later on this page assume the following JSON object is a finding attribute:
{
"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 the previous JSON example is a finding attribute
named my_property
. The following example includes queries for findings
that have the object as a property. You can also use these filters with other
filters using AND
and OR
in your query.
# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="my_property.outer_object.middle_object.deeply_nested_object.x = 123"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="my_property.outer_object.middle_object.y = \"some-string-value\""
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="my_property.outer_object.middle_object.y : \"string-value\""
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="my_property.outer_object.z = \"some-other-string-value\""
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="my_property.outer_object.z : \"other-string-value\""
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="my_property.outer_object.u : \"list-element-1\""
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="my_property.outer_object.u : \"list-element-2\""
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="my_property.outer_object.u : \"list-element-3\""
Filtering on array-type fields
When calling ListFindings
,
you can use a substring match :
, which does a single check for a partial
string match across the entire contents of the array. Alternatively, you can run
a subfilter directly against elements of the array and its subfields using the
contains()
function. The contains()
function offers an enhanced querying
experience, which includes the following:
- Exact element matching: Match array elements that contain the exact string,
"example"
. - Specific number operations: Match array elements that are greater than or equal
to
100
. - Complex filtering against array structures: Match array elements that contain
property
x
with a corresponding valuey
.
Format of the contains()
function
The contains()
function has the following format:
contains(ARRAY_FIELD, SUBFILTER)
Replace the following:
- ARRAY_FIELD: a field or subfield that is of type array (a list).
- SUBFILTER: an expression that defines the values to look for in the array. The subfilter's format differs depending on whether ARRAY_FIELD is an array of objects or an array of primitive-type elements. If the ARRAY_FIELD is an array of objects that have nested arrays, you can use a scoped subfilter to specify that you want all conditions to be satisfied within the same ARRAY_FIELD element.
The Security Command Center API returns findings where the ARRAY_FIELD contains at least one element that satisfies the SUBFILTER.
Subfilter for an array of objects
The following is an excerpt of the previous JSON example. Here, the
list_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 the
elements in the list_middle_object
field has a v
subfield
with a value greater than or equal to 321:
# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="contains(my_property.outer_object.list_middle_object, v >= 321)"
For practical examples that use the contains()
function, see
Findings that contain specific array values.
Subfilter for an array that contains primitive-type elements
Primitive types are strings, numbers, and booleans. To use the contains()
function
against an array that contains primitive types, you use the special keyword,
elem
.
The following is an excerpt of the previous JSON example. Here, the u
field
is 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 the
elements in the u
field is "list-element-1":
# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="contains(my_property.outer_object.u, elem = \"list-element-1\")"
For practical examples that use the contains()
function, see
Findings that contain specific array values.
Scoped subfilter
The following is an excerpt of the previous JSON example. Here, the
list_middle_object
field is an array of objects, and objects in this array
contain a nested array.
"list_middle_object": [
{
"v": 321,
"w": [
{
"a": 3,
"b": 4
}
]
}
]
The following example queries for findings where both of the following conditions
are satisfied within the same list_middle_object
element:
- The
v
subfield has a value greater than or equal to 321. - The
w
subfield doesn't contain an element with ana
property equal to 3.
# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--filter="contains(my_property.outer_object.list_middle_object, v >= 321 AND -contains(w, a = 3))"
For practical examples that use the contains()
function, see
Findings that contain specific array values.
Sorting findings example
You can sort findings by strict subfields that are primitive types—strings,
numbers, and booleans. Suppose the previous JSON example is a
finding attribute named my_property
. The following example includes
queries to sort the finding fields. The keyword DESC
specifies that the field
it follows must be sorted in descending order. The default order is ascending.
# ORGANIZATION_ID=organization-id
# SOURCE_ID="source-id"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--order-by="my_property.outer_object.middle_object.deeply_nested_object.x DESC"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--order-by="my_property.outer_object.middle_object.deeply_nested_object.x"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--order-by="my_property.outer_object.middle_object.y DESC"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--order-by="my_property.outer_object.middle_object.y"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--order-by="my_property.outer_object.z DESC"
gcloud scc findings list $ORGANIZATION_ID --source=$SOURCE_ID \
--order-by="my_property.outer_object.z"
Filter examples
The following sections show practical examples of finding filters.
Filter for findings that occurred after a point in time
These example filters match findings that most recently occurred after
Wednesday, June 5, 2019 10:12:05 PM GMT. With the event_time
filter, you can
express time using the following formats and types:
Unix epoch time (in milliseconds) as an integer literal
"event_time > 1559772725000"
RFC 3339 as a string literal
"event_time > \"2019-06-05T22:34:40+00:00\""
Filter on array-type fields
The following example shows the use of a partial string match on an array-type field within a filter:
"indicator.domains : \"website.com\""
The Security Command Center API returns any finding with a website.com
partial string within the
array. For example, it matches a finding with
indicator.domains = [\"onewebsite.com\"]
because "website.com" is a substring
in an element in the array.
In the following sections, the example filters show some options for use of rich
array-type filtering using the contains()
function.
Filter on the vulnerability.cve.references
field
The following example returns findings where at least one element in the
vulnerability.cve.references
array has both a source
property equal to
SOURCE_OF_REFERENCE and a uri
property that has FILTERED_URI.
"contains(vulnerability.cve.references, source = \"SOURCE_OF_REFERENCE\" AND uri : \"FILTERED_URI\")"
Replace the following:
- SOURCE_OF_REFERENCE: name of the source of a
Common Vulnerabilities and Exposures (CVE)
reference—for example,
NVD
. - FILTERED_URI: URI of the SOURCE_OF_REFERENCE.
Filter on the indicator.domains
field
The following example returns findings where at least one indicator domain
has both mycompanyprefix
and .ca
.
"contains(indicator.domains, elem : \"mycompanyprefix\" AND elem : \".ca\")"
Filter on the indicator.ip_addresses
field
The following example returns findings where at least one element in the
indicator.ip_addresses
array is equal to IP_ADDRESS.
"contains(indicator.ip_addresses, elem = \"IP_ADDRESS\")"
Replace IP_ADDRESS with an IP address associated with the findings you're searching for.
Filter on external system assignees
The following example returns findings where at least one element in the
external_systems.EXTERNAL_SYSTEM_NAME.assignees
array is
equal to ASSIGNEE.
"contains(external_systems.EXTERNAL_SYSTEM_NAME.assignees, elem = \"ASSIGNEE\")"
Replace the following:
- EXTERNAL_SYSTEM_NAME: the name of a third-party SIEM/SOAR
system—for example,
demisto
. - ASSIGNEE: an assignee in the external system.
Filter on the resource.folders.resource_folder
field
The following example returns findings where at least one element in the
resource.folders.resource_folder
array is not equal to FOLDER_NAME.
"contains(resource.folders.resource_folder, -(elem = \"FOLDER_NAME\"))"
Filter on the resource.folders.resource_folder_display_name
field
The following example returns findings where at least one element in the
resource.folders.resource_folder_display_name
array is equal to
DISPLAY_NAME.
"contains(resource.folders.resource_folder_display_name, elem = \"DISPLAY_NAME\")"
Replace DISPLAY_NAME with the user-defined name of the folder associated with the findings you're searching for.
To learn how to use a contains()
function in a finding filter, see
Filtering on array-type fields.
What's next
Learn more Setting up finding notifications.