本指南将介绍如何使用 Security Command Center API 创建和更新发现结果。
准备工作
在创建和更新发现结果之前,您需要完成以下操作:
为完成本指南,必须拥有组织级别的 Identity and Access Management (IAM) Security Center Findings Editor (securitycenter.findingsEditor
) 角色。如需详细了解 Security Command Center 角色,请参阅访问权限控制。
如果要使用安全标志创建发现结果,还必须拥有包含要使用的标记类型的权限的 IAM 角色:
- Asset Security Marks Writer (
securitycenter.assetSecurityMarksWriter
) - Finding Security Marks Writer (
securitycenter.findingSecurityMarksWriter
)
如需详细了解标记,请参阅 使用 Security Command Center 安全标记。
创建发现结果
为来源创建活跃的发现结果。
gcloud
# ORGANIZATION=12344321 # SOURCE=43211234 # FINDING_ID=testfindingid # EVENT_TIME follows the format YYYY-MM-DDThh:mm:ss.ffffffZ EVENT_TIME=2019-02-28T07:00:06.861Z STATE=ACTIVE CATEGORY=MEDIUM_RISK_ONE RESOURCE_NAME=//cloudresourcemanager.googleapis.com/projects/PROJECT_ID gcloud scc findings create $FINDING_ID \ --source $SOURCE \ --organization $ORGANIZATION \ --state $STATE \ --category $CATEGORY \ --event-time $EVENT_TIME --resource-name $RESOURCE_NAME
如需查看更多示例,请运行以下命令:
gcloud scc findings create --help
Python
import datetime
from google.cloud import securitycenter
from google.cloud.securitycenter_v1 import Finding
# Create a new client.
client = securitycenter.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"
# 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 = "//cloudresourcemanager.googleapis.com/organizations/11232"
finding = Finding(
state=Finding.State.ACTIVE,
resource_name=resource_name,
category="MEDIUM_RISK_ONE",
event_time=event_time,
)
# Call The API.
created_finding = client.create_finding(
request={"parent": source_name, "finding_id": finding_id, "finding": finding}
)
print(created_finding)
Java
static Finding createFinding(SourceName sourceName, String findingId) {
try (SecurityCenterClient client = SecurityCenterClient.create()) {
// SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
// "423432321");
// String findingId = "samplefindingid";
// Use the current time as the finding "event time".
Instant eventTime = Instant.now();
// 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.
String resourceName = "//cloudresourcemanager.googleapis.com/organizations/11232";
// Start setting up a request to create a finding in a source.
Finding finding =
Finding.newBuilder()
.setParent(sourceName.toString())
.setState(State.ACTIVE)
.setResourceName(resourceName)
.setEventTime(
Timestamp.newBuilder()
.setSeconds(eventTime.getEpochSecond())
.setNanos(eventTime.getNano()))
.setCategory("MEDIUM_RISK_ONE")
.build();
// Call the API.
Finding response = client.createFinding(sourceName, findingId, finding);
System.out.println("Created Finding: " + response);
return response;
} catch (IOException e) {
throw new RuntimeException("Couldn't create client.", e);
}
}
Go
import (
"context"
"fmt"
"io"
"time"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
"cloud.google.com/go/securitycenter/apiv1/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.
func createFinding(w io.Writer, sourceName string) 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)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %w", err)
}
defer client.Close() // Closing the client safely cleans up background resources.
// Use now as the eventTime for the security finding.
eventTime, err := ptypes.TimestampProto(time.Now())
if err != nil {
return fmt.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",
// A free-form category.
Category: "MEDIUM_RISK_ONE",
// The time associated with discovering the issue.
EventTime: eventTime,
},
}
finding, err := client.CreateFinding(ctx, req)
if err != nil {
return fmt.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)
return nil
}
Node.js
// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');
// Creates a new client.
const client = new SecurityCenterClient();
// sourceName is the full resource name of the source the finding should
// be associated with.
/*
* TODO(developer): Uncomment the following lines
*/
// const sourceName = "organizations/111122222444/sources/1234";
// Use now as the eventTime for the security finding.
const eventTime = new Date();
async function createFinding() {
const [newFinding] = await client.createFinding({
parent: sourceName,
findingId: 'samplefindingid',
finding: {
state: 'ACTIVE',
// Resource the finding is associated with. This is an
// example any resource identifier can be used.
resourceName:
'//cloudresourcemanager.googleapis.com/organizations/11232',
// A free-form category.
category: 'MEDIUM_RISK_ONE',
// The time associated with discovering the issue.
eventTime: {
seconds: Math.floor(eventTime.getTime() / 1000),
nanos: (eventTime.getTime() % 1000) * 1e6,
},
},
});
console.log('New finding created: %j', newFinding);
}
createFinding();
如需了解 Security Command Center 中发现结果数据的存储时长,请参阅发现结果保留。
使用来源属性创建发现结果
Security Command Center 允许来源通过称为“来源属性”的键值元数据为发现结果添加上下文。来源属性可以在创建时进行初始化。以下示例展示了如何创建具有来源属性的发现结果。
使用来源属性创建发现结果。source_properties
映射中键名的长度必须介于 1 到 255 个字符之间,并且必须以字母开头,并且只能包含字母数字字符或下划线。Security Command Center 仅支持布尔值、数字和字符串的值。
gcloud
# ORGANIZATION=12344321 # SOURCE=43211234 # FINDING_ID=testfindingid # EVENT_TIME follows the format YYYY-MM-DDThh:mm:ss.ffffffZ EVENT_TIME=2019-02-28T07:00:06.861Z STATE=ACTIVE CATEGORY=MEDIUM_RISK_ONE SOURCE_PROPERTY_KEY=gcloud_client_test SOURCE_PROPERTY_VALUE=value RESOURCE_NAME=//cloudresourcemanager.googleapis.com/projects/PROJECT_ID gcloud scc findings create $FINDING_ID \ --source $SOURCE \ --organization $ORGANIZATION \ --state $STATE \ --category $CATEGORY \ --event-time $EVENT_TIME \ --source-properties $SOURCE_PROPERTY_KEY=$SOURCE_PROPERTY_VALUE --resource-name $RESOURCE_NAME
- 可以使用以逗号分隔的键值对列表添加更多来源属性。
如需查看更多示例,请运行以下命令:
gcloud scc findings create --help
Python
import datetime
from google.cloud import securitycenter
from google.cloud.securitycenter_v1 import Finding
from google.protobuf.struct_pb2 import Value
# Create a new client.
client = securitycenter.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"
# Controlled by caller.
finding_id = "samplefindingid2"
# 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 = "//cloudresourcemanager.googleapis.com/organizations/11232"
# Define source properties values as protobuf "Value" objects.
str_value = Value()
str_value.string_value = "string_example"
num_value = Value()
num_value.number_value = 1234
# Use the current time as the finding "event time".
event_time = datetime.datetime.now(tz=datetime.timezone.utc)
finding = Finding(
state=Finding.State.ACTIVE,
resource_name=resource_name,
category="MEDIUM_RISK_ONE",
source_properties={"s_value": "string_example", "n_value": 1234},
event_time=event_time,
)
created_finding = client.create_finding(
request={"parent": source_name, "finding_id": finding_id, "finding": finding}
)
print(created_finding)
Java
static Finding createFindingWithSourceProperties(SourceName sourceName) {
try (SecurityCenterClient client = SecurityCenterClient.create()) {
// SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
// "423432321");
// Use the current time as the finding "event time".
Instant eventTime = Instant.now();
// Controlled by caller.
String findingId = "samplefindingid2";
// 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.
String resourceName = "//cloudresourcemanager.googleapis.com/organizations/11232";
// Define source properties values as protobuf "Value" objects.
Value stringValue = Value.newBuilder().setStringValue("stringExample").build();
Value numValue = Value.newBuilder().setNumberValue(1234).build();
ImmutableMap<String, Value> sourceProperties =
ImmutableMap.of("stringKey", stringValue, "numKey", numValue);
// Start setting up a request to create a finding in a source.
Finding finding =
Finding.newBuilder()
.setParent(sourceName.toString())
.setState(State.ACTIVE)
.setResourceName(resourceName)
.setEventTime(
Timestamp.newBuilder()
.setSeconds(eventTime.getEpochSecond())
.setNanos(eventTime.getNano()))
.putAllSourceProperties(sourceProperties)
.build();
// Call the API.
Finding response = client.createFinding(sourceName, findingId, finding);
System.out.println("Created Finding with Source Properties: " + response);
return response;
} catch (IOException e) {
throw new RuntimeException("Couldn't create client.", e);
}
}
Go
import (
"context"
"fmt"
"io"
"time"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
"github.com/golang/protobuf/ptypes"
structpb "github.com/golang/protobuf/ptypes/struct"
)
// createFindingWithProperties demonstrates how to create a new security
// finding in CSCC that includes additional metadata via sourceProperties.
// sourceName is the full resource name of the source the finding should be
// associated with.
func createFindingWithProperties(w io.Writer, sourceName string) 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)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %w", err)
}
defer client.Close() // Closing the client safely cleans up background resources.
// Use now as the eventTime for the security finding.
eventTime, err := ptypes.TimestampProto(time.Now())
if err != nil {
return fmt.Errorf("TimestampProto: %w", err)
}
req := &securitycenterpb.CreateFindingRequest{
Parent: sourceName,
FindingId: "samplefindingprops",
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",
// A free-form category.Error converting now
Category: "MEDIUM_RISK_ONE",
// The time associated with discovering the issue.
EventTime: eventTime,
// Define key-value pair metadata to include with the finding.
SourceProperties: map[string]*structpb.Value{
"s_value": {
Kind: &structpb.Value_StringValue{StringValue: "string_example"},
},
"n_value": {
Kind: &structpb.Value_NumberValue{NumberValue: 1234},
},
},
},
}
finding, err := client.CreateFinding(ctx, req)
if err != nil {
return fmt.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)
fmt.Fprintf(w, "Source Properties:\n")
for k, v := range finding.SourceProperties {
fmt.Fprintf(w, "%s = %v\n", k, v)
}
return nil
}
Node.js
// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');
// Creates a new client.
const client = new SecurityCenterClient();
// sourceName is the full resource name of the source the finding should
// be associated with.
/*
* TODO(developer): Uncomment the following lines
*/
// const sourceName = "organizations/111122222444/sources/1234";
// Use now as the eventTime for the security finding.
const eventTime = new Date();
async function createFinding() {
const [newFinding] = await client.createFinding({
parent: sourceName,
findingId: 'findingwithprops',
finding: {
state: 'ACTIVE',
// Resource the finding is associated with. This is an
// example any resource identifier can be used.
resourceName:
'//cloudresourcemanager.googleapis.com/organizations/11232',
// A free-form category.
category: 'MEDIUM_RISK_ONE',
// The time associated with discovering the issue.
eventTime: {
seconds: Math.floor(eventTime.getTime() / 1000),
nanos: (eventTime.getTime() % 1000) * 1e6,
},
sourceProperties: {
s_value: {stringValue: 'string_example'},
n_value: {numberValue: 1234},
},
},
});
console.log('New finding created: %j', newFinding);
}
createFinding();
更新发现结果的来源属性
以下示例展示了如何更新单个来源属性和事件时间。它使用字段掩码仅更新特定字段。如果不使用字段掩码,则新值将替换找到的所有可变字段。
与创建新发现结果一样,source_properties
映射必须介于 1 到 255 个字符之间,并且必须以字母开头,并且只包含字母数字字符或下划线。Security Command Center 仅支持布尔值、数字和字符串的值。
gcloud
# ORGANIZATION=12344321 # SOURCE=43211234 # FINDING_ID=testfindingid # EVENT_TIME follows the format YYYY-MM-DDThh:mm:ss.ffffffZ EVENT_TIME=2019-02-28T08:00:06.861Z SOURCE_PROPERTY_KEY=gcloud_client_test SOURCE_PROPERTY_VALUE=VALUE UPDATE_MASK=source_properties,event_time gcloud scc findings update $FINDING_ID \ --source $SOURCE \ --organization $ORGANIZATION \ --event-time $EVENT_TIME \ --source-properties $SOURCE_PROPERTY_KEY=$SOURCE_PROPERTY_VALUE \ --update-mask=$UPDATE_MASK
- 使用 --update-mask ''(空)覆盖所有可变字段。
- 可以使用以逗号分隔的键值对列表添加更多来源属性。
如需查看更多示例,请运行以下命令:
gcloud scc findings update --help
Python
import datetime
from google.cloud import securitycenter
from google.cloud.securitycenter_v1 import Finding
from google.protobuf import field_mask_pb2
client = securitycenter.SecurityCenterClient()
# Only update the specific source property and event_time. event_time
# is required for updates.
field_mask = field_mask_pb2.FieldMask(
paths=["source_properties.s_value", "event_time"]
)
# Set the update time to Now. This must be some time greater then the
# event_time on the original finding.
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"
finding_name = f"{source_name}/findings/samplefindingid2"
finding = Finding(
name=finding_name,
source_properties={"s_value": "new_string"},
event_time=event_time,
)
updated_finding = client.update_finding(
request={"finding": finding, "update_mask": field_mask}
)
print(
"New Source properties: {}, Event Time {}".format(
updated_finding.source_properties, updated_finding.event_time
)
)
Java
static Finding updateFinding(FindingName findingName) {
try (SecurityCenterClient client = SecurityCenterClient.create()) {
// FindingName findingName = FindingName.of(/*organization=*/"123234324",
// /*source=*/"423432321", /*findingId=*/"samplefindingid2");
// Use the current time as the finding "event time".
Instant eventTime = Instant.now();
// Define source properties values as protobuf "Value" objects.
Value stringValue = Value.newBuilder().setStringValue("value").build();
FieldMask updateMask =
FieldMask.newBuilder()
.addPaths("event_time")
.addPaths("source_properties.stringKey")
.build();
Finding finding =
Finding.newBuilder()
.setName(findingName.toString())
.setEventTime(
Timestamp.newBuilder()
.setSeconds(eventTime.getEpochSecond())
.setNanos(eventTime.getNano()))
.putSourceProperties("stringKey", stringValue)
.build();
UpdateFindingRequest.Builder request =
UpdateFindingRequest.newBuilder().setFinding(finding).setUpdateMask(updateMask);
// Call the API.
Finding response = client.updateFinding(request.build());
System.out.println("Updated Finding: " + response);
return response;
} catch (IOException e) {
throw new RuntimeException("Couldn't create client.", e);
}
}
Go
import (
"context"
"fmt"
"io"
"time"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
"github.com/golang/protobuf/ptypes"
structpb "github.com/golang/protobuf/ptypes/struct"
"google.golang.org/genproto/protobuf/field_mask"
)
// updateFindingSourceProperties demonstrates how to update a security finding
// in CSCC. findingName is the full resource name of the finding to update.
func updateFindingSourceProperties(w io.Writer, findingName string) error {
// findingName := "organizations/111122222444/sources/1234/findings/findingid"
// Instantiate a context and a security service client to make API calls.
ctx := context.Background()
client, err := securitycenter.NewClient(ctx)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %w", err)
}
defer client.Close() // Closing the client safely cleans up background resources.
// Use now as the eventTime for the security finding.
eventTime, err := ptypes.TimestampProto(time.Now())
if err != nil {
return fmt.Errorf("TimestampProto: %w", err)
}
req := &securitycenterpb.UpdateFindingRequest{
Finding: &securitycenterpb.Finding{
Name: findingName,
EventTime: eventTime,
SourceProperties: map[string]*structpb.Value{
"s_value": {
Kind: &structpb.Value_StringValue{StringValue: "new_string_example"},
},
},
},
// Needed to only update the specific source property s_value
// and EventTime. EventTime is a required field.
UpdateMask: &field_mask.FieldMask{
Paths: []string{"event_time", "source_properties.s_value"},
},
}
finding, err := client.UpdateFinding(ctx, req)
if err != nil {
return fmt.Errorf("UpdateFinding: %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", eventTime.Seconds)
fmt.Fprintf(w, "Source Properties:\n")
for k, v := range finding.SourceProperties {
fmt.Fprintf(w, "%s = %v\n", k, v)
}
return nil
}
Node.js
// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');
// Creates a new client.
const client = new SecurityCenterClient();
// findingName is the full resource name of the finding to update.
/*
* TODO(developer): Uncomment the following lines
*/
// const findingName =
// "organizations/111122222444/sources/1234/findings/findingid";
// Use now as the eventTime for the security finding.
const eventTime = new Date();
console.log(findingName);
async function updateFinding() {
const [newFinding] = await client.updateFinding({
updateMask: {paths: ['event_time', 'source_properties.s_value']},
finding: {
name: findingName,
// The time associated with discovering the issue.
eventTime: {
seconds: Math.floor(eventTime.getTime() / 1000),
nanos: (eventTime.getTime() % 1000) * 1e6,
},
sourceProperties: {
s_value: {stringValue: 'new_string_example'},
},
},
});
console.log('Updated Finding: %j', newFinding);
}
updateFinding();
更新发现结果的状态
Security Command Center 还提供了一个 API,可让您仅更新发现结果的状态。此 API 的存在只是为了提供仅更新发现结果的状态。它是一种简单 API,允许权限主账号只能修改发现结果的状态,而无权修改结果的其他方面。以下示例展示了如何将发现结果的状态更改为非活跃。
gcloud
# ORGANIZATION=12344321 # SOURCE=43211234 # FINDING_ID=testfindingid # EVENT_TIME follows the format YYYY-MM-DDThh:mm:ss.ffffffZ EVENT_TIME=2019-02-28T09:00:06.861Z STATE=INACTIVE gcloud scc findings update $FINDING_ID \ --source $SOURCE \ --organization $ORGANIZATION \ --state $STATE \ --event-time $EVENT_TIME
如需查看更多示例,请运行以下命令:
gcloud scc findings update --help
Python
import datetime
from google.cloud import securitycenter
from google.cloud.securitycenter_v1 import Finding
# Create a client.
client = securitycenter.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"
finding_name = f"{source_name}/findings/samplefindingid2"
# Call the API to change the finding state to inactive as of now.
new_finding = client.set_finding_state(
request={
"name": finding_name,
"state": Finding.State.INACTIVE,
"start_time": datetime.datetime.now(tz=datetime.timezone.utc),
}
)
print(f"New state: {new_finding.state}")
Java
static Finding setFindingState(FindingName findingName) {
try (SecurityCenterClient client = SecurityCenterClient.create()) {
// FindingName findingName = FindingName.of(/*organization=*/"123234324",
// /*source=*/"423432321", /*findingId=*/"samplefindingid2");
// Use the current time as the finding "event time".
Instant eventTime = Instant.now();
Finding response =
client.setFindingState(
findingName,
State.INACTIVE,
Timestamp.newBuilder()
.setSeconds(eventTime.getEpochSecond())
.setNanos(eventTime.getNano())
.build());
System.out.println("Updated Finding: " + response);
return response;
} catch (IOException e) {
throw new RuntimeException("Couldn't create client.", e);
}
}
Go
import (
"context"
"fmt"
"io"
"time"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
"github.com/golang/protobuf/ptypes"
)
// updateFindingState demonstrates how to update a security finding's state
// in CSCC. findingName is the full resource name of the finding to update.
func setFindingState(w io.Writer, findingName string) error {
// findingName := "organizations/111122222444/sources/1234"
// Instantiate a context and a security service client to make API calls.
ctx := context.Background()
client, err := securitycenter.NewClient(ctx)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %w", err)
}
defer client.Close() // Closing the client safely cleans up background resources.
// Use now as the eventTime for the security finding.
now, err := ptypes.TimestampProto(time.Now())
if err != nil {
return fmt.Errorf("TimestampProto: %w", err)
}
req := &securitycenterpb.SetFindingStateRequest{
Name: findingName,
State: securitycenterpb.Finding_INACTIVE,
// New state is effective immediately.
StartTime: now,
}
finding, err := client.SetFindingState(ctx, req)
if err != nil {
return fmt.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)
return nil
}
Node.js
// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');
// Creates a new client.
const client = new SecurityCenterClient();
// findingName is the full resource name of the source the finding should
// be associated with.
/*
* TODO(developer): Uncomment the following lines
*/
// const findingName =
// "organizations/111122222444/sources/1234/findings/findingid";
async function setFindingState() {
const eventTime = new Date();
const [updatedFinding] = await client.setFindingState({
name: findingName,
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,
},
});
console.log('Updated Finding: %j', updatedFinding);
}
setFindingState();
验证发现结果权限
创建和更新发现结果需要以下 IAM 权限之一:
- 创建和更新发现结果:
securitycenter.findings.update
。 - 仅更新发现结果:
securitycenter.findings.setState
。
如果您无法为来源创建发现结果,请使用以下代码确认您的账号具有 准备工作 部分所需的权限。如果您没有必要的权限,请参阅 创建和管理安全来源 以设置适当的 IAM 政策。
Python
from google.cloud import securitycenter
# Create a client.
client = securitycenter.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"
# Check for permssions to call create_finding or update_finding.
permission_response = client.test_iam_permissions(
request={
"resource": source_name,
"permissions": ["securitycenter.findings.update"],
}
)
print(
"Permision to create or update findings? {}".format(
len(permission_response.permissions) > 0
)
)
# Check for permissions necessary to call set_finding_state.
permission_response = client.test_iam_permissions(
request={
"resource": source_name,
"permissions": ["securitycenter.findings.setState"],
}
)
print(f"Permision to update state? {len(permission_response.permissions) > 0}")
Java
static TestIamPermissionsResponse testIamPermissions(SourceName sourceName) {
try (SecurityCenterClient client = SecurityCenterClient.create()) {
// SourceName sourceName = SourceName.of(/*organizationId=*/"123234324",
// /*sourceId=*/"423432321");
// Iam permission to test.
List<String> permissionsToTest = new ArrayList<>();
permissionsToTest.add("securitycenter.findings.update");
// Call the API.
TestIamPermissionsResponse response =
client.testIamPermissions(sourceName.toString(), permissionsToTest);
System.out.println("IAM Permission:");
System.out.println(response);
return response;
} catch (IOException e) {
throw new RuntimeException("Couldn't create client.", e);
}
}
Go
import (
"context"
"fmt"
"io"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
iam "google.golang.org/genproto/googleapis/iam/v1"
)
// testIam demonstrates how to determine if your service user has appropriate
// access to create and update findings, it writes permissions to w.
// sourceName is the full resource name of the source to test for permissions.
func testIam(w io.Writer, sourceName string) 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)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %w", err)
}
defer client.Close() // Closing the client safely cleans up background resources.
// Check for create/update Permissions.
req := &iam.TestIamPermissionsRequest{
Resource: sourceName,
Permissions: []string{"securitycenter.findings.update"},
}
policy, err := client.TestIamPermissions(ctx, req)
if err != nil {
return fmt.Errorf("Error getting IAM policy: %w", err)
}
fmt.Fprintf(w, "Permision to create/update findings? %t",
len(policy.Permissions) > 0)
// Check for updating state Permissions
req = &iam.TestIamPermissionsRequest{
Resource: sourceName,
Permissions: []string{"securitycenter.findings.setState"},
}
policy, err = client.TestIamPermissions(ctx, req)
if err != nil {
return fmt.Errorf("Error getting IAM policy: %w", err)
}
fmt.Fprintf(w, "Permision to update state? %t",
len(policy.Permissions) > 0)
return nil
}
Node.js
// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');
// Creates a new client.
const client = new SecurityCenterClient();
// sourceName is the full resource name of the source to test for permissions.
/*
* TODO(developer): Uncomment the following lines
*/
// const sourceName = "organizations/111122222444/sources/1234";
async function testIam() {
{
const [policy] = await client.testIamPermissions({
resource: sourceName,
permissions: ['securitycenter.findings.update'],
});
console.log(
`Permissions to create/update findings? ${
policy.permissions.length > 0
}`
);
}
{
const [policy] = await client.testIamPermissions({
resource: sourceName,
permissions: ['securitycenter.findings.setState'],
});
console.log(
`Permissions to update state? ${policy.permissions.length > 0}`
);
}
}
testIam();
后续步骤
详细了解如何使用 SDK 访问 Security Command Center。