Elenco di asset utilizzando l'API Security Command Center

Gli asset sono le risorse Google Cloud di un'organizzazione, ad esempio istanze Compute Engine o bucket Cloud Storage.

Questa guida mostra come utilizzare le librerie client di Security Command Center per accedere ai record ritirati gestiti da Security Command Center per le risorse di un progetto o di un'organizzazione.

Security Command Center conserva i record solo per un sottoinsieme di asset nell'Cloud Asset Inventory. Per l'elenco più completo delle risorse nel tuo ambiente, utilizza Cloud Asset Inventory per elencarle.

Per ulteriori informazioni, consulta le seguenti risorse:

Livelli di concessione per i ruoli IAM

I ruoli IAM per Security Command Center possono essere concessi a livello di organizzazione, cartella o progetto. La possibilità di visualizzare, modificare, creare o aggiornare risultati, asset e origini di sicurezza dipende dal livello per cui ti è stato concesso l'accesso. Per scoprire di più sui ruoli di Security Command Center, consulta Controllo degli accessi.

Prima di iniziare

Prima di configurare una sorgente, devi completare i seguenti passaggi:

Dimensioni pagina

Tutte le API di elenco di Security Command Center sono paginate. Ogni risposta restituisce una pagina di risultati e un token per restituire la pagina successiva. Le dimensioni della pagina sono configurabili. Il valore predefinito di pageSize è 10, ma può essere impostato su un valore minimo di 1 e un valore massimo di 1000.

Tipi di risorse

L'attributo resourceType in Security Command Center utilizza una convenzione di denominazione diversa da quella di Cloud Asset Inventory. Per un elenco dei formati dei tipi di risorsa, consulta Tipi di asset supportati in Security Command Center.

Elenco di tutti gli asset

Questi esempi mostrano come elencare tutti gli asset:

gcloud

Per elencare tutti gli asset in un progetto, una cartella o un'organizzazione, esegui il seguente comando:

gcloud scc assets list PARENT_ID

Sostituisci PARENT_ID con uno dei seguenti valori:

  • Un ID organizzazione nel seguente formato: ORGANIZATION_ID (solo l'ID numerico)
  • Un ID cartella nel seguente formato: folders/FOLDER_ID
  • Un ID progetto nel seguente formato: projects/PROJECT_ID

Per altri esempi, esegui:

 gcloud scc assets list --help

Per esempi nella documentazione, consulta gcloud scc assets list.

Python

from google.cloud import securitycenter

client = securitycenter.SecurityCenterClient()
# 'parent' must be in one of the following formats:
#   "organizations/{organization_id}"
#   "projects/{project_id}"
#   "folders/{folder_id}"
parent = f"organizations/{organization_id}"

# Call the API and print results.
asset_iterator = client.list_assets(request={"parent": parent})
for i, asset_result in enumerate(asset_iterator):
    print(i, asset_result)

Java

static ImmutableList<ListAssetsResult> listAssets(OrganizationName organizationName) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Start setting up a request to search for all assets in an organization, project, or folder.
    //
    // Parent must be in one of the following formats:
    //    OrganizationName organizationName = OrganizationName.of("organization-id");
    //    ProjectName projectName = ProjectName.of("project-id");
    //    FolderName folderName = FolderName.of("folder-id");
    ListAssetsRequest.Builder request =
        ListAssetsRequest.newBuilder().setParent(organizationName.toString());

    // Call the API.
    ListAssetsPagedResponse response = client.listAssets(request.build());

    // This creates one list for all assets.  If your organization has a large number of assets
    // this can cause out of memory issues.  You can process them incrementally by returning
    // the Iterable returned response.iterateAll() directly.
    ImmutableList<ListAssetsResult> results = ImmutableList.copyOf(response.iterateAll());
    System.out.println("All assets:");
    System.out.println(results);
    return results;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Vai

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"google.golang.org/api/iterator"
)

// listAllAssets prints every asset to w for orgID. orgID is the numeric
// Organization ID.
func listAllAssets(w io.Writer, orgID string) error {
	// orgID := "12321311"
	// 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.

	req := &securitycenterpb.ListAssetsRequest{
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}"
		//		"projects/{projectId}"
		//		"folders/{folderId}"
		Parent: fmt.Sprintf("organizations/%s", orgID),
	}

	assetsFound := 0
	it := client.ListAssets(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("ListAssets: %w", err)
		}
		asset := result.Asset
		properties := asset.SecurityCenterProperties
		fmt.Fprintf(w, "Asset Name: %s,", asset.Name)
		fmt.Fprintf(w, "Resource Name %s,", properties.ResourceName)
		fmt.Fprintf(w, "Resource Type %s\n", properties.ResourceType)
		assetsFound++
	}
	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();
//  organizationId is the numeric ID of the organization.
/*
 * TODO(developer): Uncomment the following lines
 */
// parent: must be in one of the following formats:
//    `organizations/${organization_id}`
//    `projects/${project_id}`
//    `folders/${folder_id}`
const parent = `organizations/${organizationId}`;
// Call the API with automatic pagination.
async function listAssets() {
  const [response] = await client.listAssets({parent: parent});
  let count = 0;
  Array.from(response).forEach(result =>
    console.log(
      `${++count} ${result.asset.name} ${
        result.asset.securityCenterProperties.resourceName
      }`
    )
  );
}

listAssets();

L'output per ogni risorsa è un oggetto JSON simile al seguente:

asset:
  createTime: '2020-10-05T17:55:14.823Z'
  iamPolicy:
    policyBlob: '{"bindings":[{"role":"roles/owner","members":["serviceAccount:SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com","user:USER_EMAIL@gmail.com"]}]}'
  name: organizations/ORGANIZATION_ID/assets/ASSET_ID
  resourceProperties:
    createTime: '2020-10-05T17:36:17.915Z'
    lifecycleState: ACTIVE
    name: PROJECT_ID
    parent: '{"id":"ORGANIZATION_ID","type":"organization"}'
    projectId: PROJECT_ID
    projectNumber: 'PROJECT_NUMBER'
  securityCenterProperties:
    resourceDisplayName: PROJECT_ID
    resourceName: //cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER
    resourceOwners:
    - serviceAccount:SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com
    - user:USER_EMAIL@gmail.com
    resourceParent: //cloudresourcemanager.googleapis.com/organizations/ORGANIZATION_ID
    resourceParentDisplayName: ORGANIZATION_NAME
    resourceProject: //cloudresourcemanager.googleapis.com/projects/PROJECT_NUMBER
    resourceProjectDisplayName: PROJECT_ID
    resourceType: google.cloud.resourcemanager.Project
  securityMarks:
    name: organizations/ORGANIZATION_ID/assets/ASSET_ID/securityMarks
  updateTime: '2020-10-05T17:55:14.823Z'

Filtra asset

Un progetto, una cartella o un'organizzazione può avere molti asset. L'esempio precedente non utilizza filtri, pertanto vengono restituiti tutti gli asset. Security Command Center ti consente di utilizzare i filtri per asset per ottenere informazioni su asset specifici. I filtri sono simili alle clausole "where" nelle istruzioni SQL, tranne per il fatto che, anziché alle colonne, si applicano agli oggetti retitrati dall'API.

L'output di esempio nell'esempio precedente mostra alcuni campi e sottocampi e le relative proprietà che possono essere utilizzati nei filtri degli asset. Security Command Center supporta array e oggetti JSON completi come potenziali tipi di proprietà. Puoi filtrare in base a:

  • Elementi array
  • Oggetti JSON completi con corrispondenza parziale della stringa all'interno dell'oggetto
  • Subcampi dell'oggetto JSON

I campi secondari devono essere numeri, stringhe o valori booleani e le espressioni di filtro devono utilizzare i seguenti operatori di confronto:

  • Stringhe:
    • Parità di genere =
    • Corrispondenza parziale delle stringhe :
  • Numeri:
    • Diseguaglianze <, >, <=, >=
    • Uguaglianza =
  • Operatori booleani:
    • Uguaglianza =

Gli esempi riportati di seguito filtrano gli asset:

gcloud

Utilizza il seguente comando per filtrare gli asset:

gcloud scc assets list PARENT_ID --filter="FILTER"

Sostituisci quanto segue:

  • FILTER con il filtro che devi utilizzare. Ad esempio, il seguente filtro restituisce solo le risorse del progetto:
    --filter="security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\""
  • PARENT_ID con uno dei seguenti valori:
    • Un ID organizzazione nel seguente formato: ORGANIZATION_ID (solo l'ID numerico)
    • Un ID cartella nel seguente formato: folders/FOLDER_ID
    • Un ID progetto nel seguente formato: projects/PROJECT_ID

Per altri esempi, esegui:

gcloud scc assets list --help

Per esempi nella documentazione, consulta gcloud scc assets list.

Python

from google.cloud import securitycenter

client = securitycenter.SecurityCenterClient()

# 'parent' must be in one of the following formats:
#   "organizations/{organization_id}"
#   "projects/{project_id}"
#   "folders/{folder_id}"
parent = f"organizations/{organization_id}"

project_filter = (
    "security_center_properties.resource_type="
    + '"google.cloud.resourcemanager.Project"'
)
# Call the API and print results.
asset_iterator = client.list_assets(
    request={"parent": parent, "filter": project_filter}
)
for i, asset_result in enumerate(asset_iterator):
    print(i, asset_result)

Java

static ImmutableList<ListAssetsResult> listAssetsWithFilter(OrganizationName organizationName) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Start setting up a request to search for all assets in an organization, project, or folder.
    //
    // Parent must be in one of the following formats:
    //    OrganizationName organizationName = OrganizationName.of("organization-id");
    //    ProjectName projectName = ProjectName.of("project-id");
    //    FolderName folderName = FolderName.of("folder-id");
    ListAssetsRequest.Builder request =
        ListAssetsRequest.newBuilder()
            .setParent(organizationName.toString())
            .setFilter(
                "security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\"");

    // Call the API.
    ListAssetsPagedResponse response = client.listAssets(request.build());

    // This creates one list for all assets.  If your organization has a large number of assets
    // this can cause out of memory issues.  You can process them incrementally by returning
    // the Iterable returned response.iterateAll() directly.
    ImmutableList<ListAssetsResult> results = ImmutableList.copyOf(response.iterateAll());
    System.out.println("Project assets:");
    System.out.println(results);
    return results;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Vai

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"google.golang.org/api/iterator"
)

// listAllProjectAssets lists all current GCP project assets in orgID and
// prints out results to w. orgID is the numeric organization ID of interest.
func listAllProjectAssets(w io.Writer, orgID string) error {
	// orgID := "12321311"
	// 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.
	req := &securitycenterpb.ListAssetsRequest{
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}"
		//		"projects/{projectId}"
		//		"folders/{folderId}"
		Parent: fmt.Sprintf("organizations/%s", orgID),
		Filter: `security_center_properties.resource_type="google.cloud.resourcemanager.Project"`,
	}

	assetsFound := 0
	it := client.ListAssets(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("ListAssets: %w", err)
		}
		asset := result.Asset
		properties := asset.SecurityCenterProperties
		fmt.Fprintf(w, "Asset Name: %s,", asset.Name)
		fmt.Fprintf(w, "Resource Name %s,", properties.ResourceName)
		fmt.Fprintf(w, "Resource Type %s\n", properties.ResourceType)
		assetsFound++
	}
	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();
//  organizationId is the numeric ID of the organization.
/*
 * TODO(developer): Uncomment the following lines
 */
// const organizationId = "1234567777";
const orgName = client.organizationPath(organizationId);

// Call the API with automatic pagination.
// You can also list assets in a project/ folder. To do so, modify the parent
// value and filter condition.
async function listFilteredAssets() {
  const [response] = await client.listAssets({
    parent: orgName,
    filter:
      'security_center_properties.resource_type="google.cloud.resourcemanager.Project"',
  });
  let count = 0;
  Array.from(response).forEach(result =>
    console.log(
      `${++count} ${result.asset.name} ${
        result.asset.securityCenterProperties.resourceName
      } ${result.stateChange}`
    )
  );
}

listFilteredAssets();

Elenco in un determinato momento

Gli esempi precedenti mostrano come elencare un set corrente di asset. Security Command Center ti consente anche di visualizzare uno snapshot storico degli asset. Gli esempi riportati di seguito restituiscono lo stato di tutti gli asset in un determinato momento. Security Command Center supporta risoluzioni di tempo in millisecondi.

gcloud

Utilizza il seguente comando per elencare gli asset a partire da un determinato momento:

gcloud scc assets list PARENT_ID --read-time="READ_TIME"

Sostituisci quanto segue:

  • READ_TIME con l'ora in cui elencare le risorse. Utilizza il formato seguente: YYYY-MM-DDThh:mm:ss.ffffffZ. Ad esempio:
    --read-time="2022-12-21T07:00:06.861Z"
  • PARENT_ID con uno dei seguenti valori:
    • Un ID organizzazione nel seguente formato: ORGANIZATION_ID (solo l'ID numerico)
    • Un ID progetto nel seguente formato: projects/PROJECT_ID
    • Un ID cartella nel seguente formato: folders/FOLDER_ID

Per altri esempi, esegui:

gcloud scc assets list --help

Per esempi nella documentazione, consulta gcloud scc assets list.

Python

from datetime import datetime, timedelta, timezone

from google.cloud import securitycenter

client = securitycenter.SecurityCenterClient()

# 'parent' must be in one of the following formats:
#   "organizations/{organization_id}"
#   "projects/{project_id}"
#   "folders/{folder_id}"
parent = f"organizations/{organization_id}"

project_filter = (
    "security_center_properties.resource_type="
    + '"google.cloud.resourcemanager.Project"'
)

# Lists assets as of yesterday.
read_time = datetime.now(tz=timezone.utc) - timedelta(days=1)

# Call the API and print results.
asset_iterator = client.list_assets(
    request={"parent": parent, "filter": project_filter, "read_time": read_time}
)
for i, asset_result in enumerate(asset_iterator):
    print(i, asset_result)

Java

static ImmutableList<ListAssetsResult> listAssetsAsOfYesterday(
    OrganizationName organizationName, Instant asOf) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Start setting up a request to search for all assets in an organization, project, or folder.
    //
    // Parent must be in one of the following formats:
    //    OrganizationName organizationName = OrganizationName.of("organization-id");
    //    ProjectName projectName = ProjectName.of("project-id");
    //    FolderName folderName = FolderName.of("folder-id");
    // Initialize the builder with the parent and filter
    ListAssetsRequest.Builder request =
        ListAssetsRequest.newBuilder()
            .setParent(organizationName.toString())
            .setFilter(
                "security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\"");

    // Set read time to either the instant passed in or one day ago.
    asOf = MoreObjects.firstNonNull(asOf, Instant.now().minus(Duration.ofDays(1)));
    request.getReadTimeBuilder().setSeconds(asOf.getEpochSecond()).setNanos(asOf.getNano());

    // Call the API.
    ListAssetsPagedResponse response = client.listAssets(request.build());

    // This creates one list for all assets.  If your organization has a large number of assets
    // this can cause out of memory issues.  You can process them incrementally by returning
    // the Iterable returned response.iterateAll() directly.
    ImmutableList<ListAssetsResult> results = ImmutableList.copyOf(response.iterateAll());
    System.out.println("Projects:");
    System.out.println(results);
    return results;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Vai

import (
	"context"
	"fmt"
	"io"
	"time"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"github.com/golang/protobuf/ptypes"
	"google.golang.org/api/iterator"
)

// listAllProjectAssets lists all GCP Projects in orgID at asOf time and prints
// out results to w. orgID is the numeric organization ID of interest.
func listAllProjectAssetsAtTime(w io.Writer, orgID string, asOf time.Time) error {
	// orgID := "12321311"
	// 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.

	// Convert the time to a Timestamp protobuf
	readTime, err := ptypes.TimestampProto(asOf)
	if err != nil {
		return fmt.Errorf("TimestampProto(%v): %w", asOf, err)
	}

	// You can also list assets in a project/ folder. To do so, modify the parent and
	// filter condition.
	req := &securitycenterpb.ListAssetsRequest{
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}"
		//		"projects/{projectId}"
		//		"folders/{folderId}"
		Parent:   fmt.Sprintf("organizations/%s", orgID),
		Filter:   `security_center_properties.resource_type="google.cloud.resourcemanager.Project"`,
		ReadTime: readTime,
	}

	assetsFound := 0
	it := client.ListAssets(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("ListAssets: %w", err)
		}
		asset := result.Asset
		properties := asset.SecurityCenterProperties
		fmt.Fprintf(w, "Asset Name: %s,", asset.Name)
		fmt.Fprintf(w, "Resource Name %s,", properties.ResourceName)
		fmt.Fprintf(w, "Resource Type %s\n", properties.ResourceType)
		assetsFound++
	}
	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();
//  organizationId is the numeric ID of the organization.
/*
 * TODO(developer): Uncomment the following lines
 */
// parent: must be in one of the following formats:
//    `organizations/${organization_id}`
//    `projects/${project_id}`
//    `folders/${folder_id}`
const parent = `organizations/${organizationId}`;

const oneDayAgo = new Date();
oneDayAgo.setDate(oneDayAgo.getDate() - 1);

// Call the API with automatic pagination.
async function listAssetsAtTime() {
  const [response] = await client.listAssets({
    parent: parent,
    filter:
      'security_center_properties.resource_type="google.cloud.resourcemanager.Project"',
    // readTime must be in the form of a google.protobuf.Timestamp object
    // which takes seconds and nanoseconds.
    readTime: {
      seconds: Math.floor(oneDayAgo.getTime() / 1000),
      nanos: (oneDayAgo.getTime() % 1000) * 1e6,
    },
  });
  let count = 0;
  Array.from(response).forEach(result =>
    console.log(
      `${++count} ${result.asset.name} ${
        result.asset.securityCenterProperties.resourceName
      }`
    )
  );
}

listAssetsAtTime();

Elenco delle risorse con modifiche dello stato

Security Command Center ti consente di confrontare un asset in due momenti per identificare se è stato aggiunto, rimosso o era presente durante il periodo di tempo specificato. I seguenti esempi confrontano i progetti esistenti in READ_TIME con un punto di tempo precedente specificato da COMPARE_DURATION. COMPARE_DURATION viene fornito in secondi.

Quando è impostato COMPARE_DURATION, l'attributo stateChange nei risultati dell'asset elenco viene aggiornato con uno dei seguenti valori:

  • ADDED: la risorsa non era presente all'inizio di compareDuration, ma era presente a readTime.
  • REMOVED: la risorsa era presente all'inizio di compareDuration, ma non in readTime.
  • ACTIVE: la risorsa era presente sia all'inizio che alla fine del periodo di tempo definito da compareDuration e readTime.

gcloud

Utilizza il seguente comando per confrontare lo stato delle risorse in due punti nel tempo:

gcloud scc assets list PARENT_ID \
    --filter="FILTER" \
    --read-time=READ_TIME \
    --compare-duration=COMPARE_DURATION

Sostituisci quanto segue:

  • COMPARE_DURATION con un numero di secondi che definisce un punto nel tempo precedente a quello specificato nel flag --read-time. Ad esempio:
    --compare-duration=84600s
  • FILTER con il filtro che devi utilizzare. Ad esempio, il seguente filtro restituisce solo le risorse del progetto:
    --filter="security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\""
  • PARENT_ID con uno dei seguenti valori:
    • Un ID organizzazione nel seguente formato: ORGANIZATION_ID (solo l'ID numerico)
    • Un ID progetto nel seguente formato: projects/PROJECT_ID
    • Un ID cartella nel seguente formato: folders/FOLDER_ID
  • READ_TIME con l'ora in cui elencare le risorse. Utilizza il seguente formato: YYYY-MM-DDThh:mm:ss.ffffffZ. Ad esempio:
    --read-time="2022-12-21T07:00:06.861Z"
    Per altri esempi, esegui:
gcloud scc assets list --help

Per esempi nella documentazione, consulta gcloud scc assets list.

Python

from datetime import timedelta

from google.cloud import securitycenter

client = securitycenter.SecurityCenterClient()

# 'parent' must be in one of the following formats:
#   "organizations/{organization_id}"
#   "projects/{project_id}"
#   "folders/{folder_id}"
parent = f"organizations/{organization_id}"
project_filter = (
    "security_center_properties.resource_type="
    + '"google.cloud.resourcemanager.Project"'
)

# List assets and their state change the last 30 days
compare_delta = timedelta(days=30)

# Call the API and print results.
asset_iterator = client.list_assets(
    request={
        "parent": parent,
        "filter": project_filter,
        "compare_duration": compare_delta,
    }
)
for i, asset in enumerate(asset_iterator):
    print(i, asset)

Java

static ImmutableList<ListAssetsResult> listAssetAndStatusChanges(
    OrganizationName organizationName, Duration timeSpan, Instant asOf) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {

    // Start setting up a request to search for all assets in an organization, project, or folder.
    //
    // Parent must be in one of the following formats:
    //    OrganizationName organizationName = OrganizationName.of("organization-id");
    //    ProjectName projectName = ProjectName.of("project-id");
    //    FolderName folderName = FolderName.of("folder-id");
    ListAssetsRequest.Builder request =
        ListAssetsRequest.newBuilder()
            .setParent(organizationName.toString())
            .setFilter(
                "security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\"");
    request
        .getCompareDurationBuilder()
        .setSeconds(timeSpan.getSeconds())
        .setNanos(timeSpan.getNano());

    // Set read time to either the instant passed in or now.
    asOf = MoreObjects.firstNonNull(asOf, Instant.now());
    request.getReadTimeBuilder().setSeconds(asOf.getEpochSecond()).setNanos(asOf.getNano());

    // Call the API.
    ListAssetsPagedResponse response = client.listAssets(request.build());

    // This creates one list for all assets.  If your organization has a large number of assets
    // this can cause out of memory issues.  You can process them incrementally by returning
    // the Iterable returned response.iterateAll() directly.
    ImmutableList<ListAssetsResult> results = ImmutableList.copyOf(response.iterateAll());
    System.out.println("Projects:");
    System.out.println(results);
    return results;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Vai

import (
	"context"
	"fmt"
	"io"
	"time"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"github.com/golang/protobuf/ptypes"
	"google.golang.org/api/iterator"
)

// listAllProjectAssetsAndStateChange lists all current GCP project assets in
// orgID and prints the projects and there change from a day ago out to w.
// orgID is the numeric // organization ID of interest.
func listAllProjectAssetsAndStateChanges(w io.Writer, orgID string) error {
	// orgID := "12321311"
	// 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.

	req := &securitycenterpb.ListAssetsRequest{
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}"
		//		"projects/{projectId}"
		//		"folders/{folderId}"
		Parent:          fmt.Sprintf("organizations/%s", orgID),
		Filter:          `security_center_properties.resource_type="google.cloud.resourcemanager.Project"`,
		CompareDuration: ptypes.DurationProto(24 * time.Hour),
	}

	assetsFound := 0
	it := client.ListAssets(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("ListAssets: %w", err)
		}
		asset := result.Asset
		properties := asset.SecurityCenterProperties
		fmt.Fprintf(w, "Asset Name: %s,", asset.Name)
		fmt.Fprintf(w, "Resource Name %s,", properties.ResourceName)
		fmt.Fprintf(w, "Resource Type %s", properties.ResourceType)
		fmt.Fprintf(w, "State Change %s\n", result.StateChange)
		assetsFound++
	}
	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();
//  organizationId is the numeric ID of the organization.
/*
 * TODO(developer): Uncomment the following lines
 */
// parent: must be in one of the following formats:
//    `organizations/${organization_id}`
//    `projects/${project_id}`
//    `folders/${folder_id}`
const parent = `organizations/${organizationId}`;
// Call the API with automatic pagination.
async function listAssetsAndChanges() {
  const [response] = await client.listAssets({
    parent: parent,
    compareDuration: {seconds: 30 * /*Second in Day=*/ 86400, nanos: 0},
    filter:
      'security_center_properties.resource_type="google.cloud.resourcemanager.Project"',
  });
  let count = 0;
  Array.from(response).forEach(result =>
    console.log(
      `${++count} ${result.asset.name} ${
        result.asset.securityCenterProperties.resourceName
      } ${result.stateChange}`
    )
  );
}

listAssetsAndChanges();

Esempi di filtro

Di seguito sono riportati altri filtri di asset utili. Puoi utilizzare AND e OR nei filtri per combinare i parametri ed espandere o perfezionare i risultati.

Trovare una risorsa del progetto con un proprietario specifico

"security_center_properties.resource_type = \"google.cloud.resourcemanager.Project\" AND security_center_properties.resource_owners : \"$USER\""

$USER ha in genere il formato user:someone@domain.com. Il confronto per user utilizza l'operatore sottostringa : e non è necessaria una corrispondenza esatta.

Regole firewall con porte HTTP aperte

"security_center_properties.resource_type = \"google.compute.Firewall\" AND resource_properties.name =\"default-allow-http\""

Risorse appartenenti a progetti specifici

"security_center_properties.resource_parent = \"$PROJECT_1_NAME\" OR security_center_properties.resource_parent = \"$PROJECT_2_NAME\""

$PROJECT_1_NAME e $PROJECT_2_NAME sono identificatori delle risorse nel formato //cloudresourcemanager.googleapis.com/projects/$PROJECT_ID, dove $PROJECT_ID è il numero del progetto. Un esempio completo potrebbe essere: //cloudresourcemanager.googleapis.com/projects/100090906

Trovare le immagini Compute Engine i cui nomi contengono una stringa specifica

Questo filtro restituisce le immagini Compute Engine che contengono la sottostringa "Debia":

"security_center_properties.resource_type = \"google.compute.Image\" AND resource_properties.name : \"Debia\""

Risorse le cui proprietà contengono coppie chiave-valore

Questo filtro restituisce i bucket Cloud Storage in cui bucketPolicyOnly è disabilitato. Il valore di resourceProperties.iamConfiguration è codificato come stringa. Utilizza il carattere \ per inserire caratteri di escape nelle stringhe, incluso l'operatore : tra il nome e il valore della chiave.

"resourceProperties.iamConfiguration:"\"bucketPolicyOnly\"\:{\"enabled\"\:false""

Trovare gli asset del progetto creati prima o in un momento specifico

Questi filtri di esempio corrispondono agli asset creati prima del 18 luglio 2019 alle 20:26:21 GMT. Con il filtro create_time, puoi esprimere l'ora utilizzando i seguenti formati e tipi:

  • Tempo Unix (in millisecondi) come valore letterale intero

    "create_time <= 1563481581000"
    
  • RFC 3339 come valore letterale di stringa

    "create_time <= \"2019-07-18T20:26:21+00:00\""
    

Esclusione di asset dai risultati

Per escludere una risorsa dai risultati, utilizza la negazione inserendo un carattere - davanti a un parametro. L'operazione è simile all'utilizzo dell'operatore NOT in un istruzione SQL.

Questo filtro restituisce tutte le risorse del progetto, ad eccezione di Debia:

"security_center_properties.resource_type = \"google.cloud.resourcemanager.Project\" AND -resource_properties.projectId = \"Debia\""

Passaggi successivi

Scopri di più su come accedere a Security Command Center utilizzando una libreria client.