Répertorier des éléments à l'aide de l'API Security Command Center

Les éléments sont des ressources Google Cloud d'une organisation, telles que des instances Compute Engine ou des buckets Cloud Storage.

Ce guide explique comment utiliser les bibliothèques clientes de Security Command Center pour accéder aux enregistrements obsolètes conservés par Security Command Center pour les éléments d'un projet ou d'une organisation.

Security Command Center ne conserve des enregistrements que pour un sous-ensemble des éléments de l'inventaire des éléments cloud. Pour obtenir la liste la plus complète des éléments de votre environnement, utilisez l'inventaire des éléments cloud.

Pour en savoir plus, consultez les ressources suivantes :

Niveaux d'attribution des rôles IAM

Les rôles IAM pour Security Command Center peuvent être attribués au niveau de l'organisation, d'un dossier ou d'un projet. Votre capacité à afficher, modifier, créer ou mettre à jour des résultats, des éléments et des sources de sécurité dépend du niveau d'accès qui vous est accordé. Pour en savoir plus sur les rôles Security Command Center, consultez la page Contrôle des accès.

Avant de commencer

Avant de configurer une source, vous devez effectuer les opérations suivantes :

Taille de la page

Toutes les API de liste Security Command Center sont paginées. Chaque réponse renvoie une page de résultats et un jeton pour renvoyer la page suivante. La taille de la page est configurable. La valeur pageSize par défaut est de 10. Elle peut être définie sur une valeur comprise entre 1 et 1 000.

Types de ressources

L'attribut resourceType dans Security Command Center utilise une convention de nommage différente de celle de l'inventaire des éléments cloud. Pour obtenir la liste des formats des types de ressources, consultez la page Types d'éléments acceptés dans Security Command Center.

Répertorier tous les éléments

Ces exemples montrent comment répertorier tous les éléments:

gcloud

Pour répertorier tous les composants d'un projet, d'un dossier ou d'une organisation, exécutez la commande suivante:

gcloud scc assets list PARENT_ID

Remplacez PARENT_ID par l'une des valeurs suivantes :

  • Un ID d'organisation au format suivant : ORGANIZATION_ID (l'ID numérique uniquement)
  • ID de dossier au format suivant: folders/FOLDER_ID
  • Un ID de projet au format suivant: projects/PROJECT_ID

Pour plus d'exemples, exécutez la commande suivante :

 gcloud scc assets list --help

Pour obtenir des exemples dans la documentation, consultez 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);
  }
}

Go

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();

Le résultat pour chaque élément est un objet JSON qui se présente comme suit :

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'

Filtrer les éléments

Un projet, un dossier ou une organisation peut comporter de nombreux composants. L'exemple précédent n'utilise aucun filtre. Tous les éléments sont donc renvoyés. Security Command Center vous permet d'utiliser des filtres d'éléments pour obtenir des informations sur des éléments spécifiques. Les filtres sont semblables à des clauses "where" dans les instructions SQL, à ceci près qu'ils s'appliquent aux objets renvoyés par l'API et non à des colonnes.

L'exemple de résultat de l'exemple précédent montre certains champs et sous-champs, ainsi que leurs propriétés, qui peuvent être utilisés dans les filtres d'éléments. Security Command Center est compatible avec les tableaux et objets JSON entiers en tant que types de propriétés potentiels. Vous pouvez appliquer les filtres suivants :

  • Éléments de tableau
  • Objets JSON entiers avec correspondance de chaîne partielle dans l'objet
  • Sous-champs d'objets JSON

Les sous-champs doivent être des nombres, des chaînes ou des valeurs booléennes, et les expressions de filtre doivent utiliser les opérateurs de comparaison suivants :

  • Chaînes :
    • Égalité parfaite =
    • Chaîne partielle correspondant à :
  • Chiffres :
    • Inégalités <, >, <=, >=
    • Égalité =
  • Booléens :
    • Égalité =

Les exemples suivants permettent de filtrer les éléments:

gcloud

Utilisez la commande suivante pour filtrer les éléments:

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

Remplacez les éléments suivants :

  • FILTER par le filtre que vous devez utiliser. Par exemple, le filtre suivant renvoie uniquement les ressources du projet:
    --filter="security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\""
  • PARENT_ID par l'une des valeurs suivantes :
    • Un ID d'organisation au format suivant : ORGANIZATION_ID (l'ID numérique uniquement)
    • ID de dossier au format suivant: folders/FOLDER_ID
    • Un ID de projet au format suivant: projects/PROJECT_ID

Pour plus d'exemples, exécutez la commande suivante :

gcloud scc assets list --help

Pour obtenir des exemples dans la documentation, consultez 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);
  }
}

Go

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();

Lister à un moment précis

Les exemples précédents montrent comment répertorier un ensemble actuel d'assets. Security Command Center vous permet également d'afficher un instantané historique des éléments. Les exemples suivants renvoient l'état de tous les éléments à un moment précis. Security Command Center est compatible avec des résolutions à la milliseconde.

gcloud

Utilisez la commande suivante pour répertorier les éléments à un moment précis:

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

Remplacez les éléments suivants :

  • READ_TIME par l'heure à laquelle les éléments doivent être listés. Utilisez le format suivant : YYYY-MM-DDThh:mm:ss.ffffffZ. Exemple :
    --read-time="2022-12-21T07:00:06.861Z"
  • PARENT_ID par l'une des valeurs suivantes :
    • Un ID d'organisation au format suivant : ORGANIZATION_ID (l'ID numérique uniquement)
    • Un ID de projet au format suivant: projects/PROJECT_ID
    • ID de dossier au format suivant: folders/FOLDER_ID

Pour plus d'exemples, exécutez la commande suivante :

gcloud scc assets list --help

Pour obtenir des exemples dans la documentation, consultez 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);
  }
}

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"
	"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();

Répertorier des éléments avec des changements d'état

Security Command Center vous permet de comparer un élément à deux moments précis afin de déterminer s'il a été ajouté ou supprimé ou s'il était présent pendant la période spécifiée. Les exemples suivants comparent les projets existants à READ_TIME à un moment précis spécifié par COMPARE_DURATION. COMPARE_DURATION est fourni en secondes.

Lorsque COMPARE_DURATION est défini, l'attribut stateChange des résultats de liste des éléments est mis à jour avec l'une des valeurs suivantes :

  • ADDED : l'élément n'était pas présent au début de compareDuration, mais il était présent à readTime.
  • REMOVED : l'élément était présent au début de compareDuration, mais pas à readTime.
  • ACTIVE : l'élément était présent au début et à la fin de la période définie par compareDuration et readTime.

gcloud

Utilisez la commande suivante pour comparer l'état des éléments à deux moments précis:

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

Remplacez les éléments suivants :

  • COMPARE_DURATION par un nombre de secondes qui définit un moment antérieur à l'heure spécifiée dans l'option --read-time. Exemple :
    --compare-duration=84600s
  • FILTER par le filtre que vous devez utiliser. Par exemple, le filtre suivant renvoie uniquement les ressources du projet:
    --filter="security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\""
  • PARENT_ID par l'une des valeurs suivantes :
    • Un ID d'organisation au format suivant : ORGANIZATION_ID (l'ID numérique uniquement)
    • Un ID de projet au format suivant: projects/PROJECT_ID
    • ID de dossier au format suivant: folders/FOLDER_ID
  • READ_TIME par l'heure à laquelle les éléments doivent être listés. Utilisez le format suivant : YYYY-MM-DDThh:mm:ss.ffffffZ. Exemple :
    --read-time="2022-12-21T07:00:06.861Z"
    Pour plus d'exemples, exécutez la commande suivante :
gcloud scc assets list --help

Pour obtenir des exemples dans la documentation, consultez 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);
  }
}

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"
	"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();

Exemples de filtres

Voici d'autres filtres d'éléments utiles. Vous pouvez utiliser AND et OR dans les filtres pour combiner des paramètres et développer ou affiner les résultats.

Rechercher un élément de projet avec un propriétaire spécifique

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

$USER est généralement au format user:someone@domain.com. La comparaison de user utilise l'opérateur de sous-chaîne :. Une correspondance exacte n'est pas nécessaire.

Règles de pare-feu comprenant des ports HTTP ouverts

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

Ressources appartenant à des projets spécifiques

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

$PROJECT_1_NAME et $PROJECT_2_NAME sont des identifiants de ressources au format //cloudresourcemanager.googleapis.com/projects/$PROJECT_ID, où $PROJECT_ID est le numéro du projet. Voici un exemple complet : //cloudresourcemanager.googleapis.com/projects/100090906

Rechercher des images Compute Engine dont les noms contiennent une chaîne spécifique

Ce filtre renvoie des images Compute Engine contenant la sous-chaîne "Debia" :

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

Ressources dont les propriétés contiennent des paires clé/valeur

Ce filtre renvoie les buckets Cloud Storage où bucketPolicyOnly est désactivé. La valeur de resourceProperties.iamConfiguration est encodée sous forme de chaîne. Vous utilisez le caractère \ pour échapper les caractères spéciaux dans les chaînes, y compris l'opérateur : entre le nom de clé et la valeur.

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

Rechercher des éléments de projet créés à une heure précise ou avant

Ces exemples de filtres correspondent aux éléments créés au plus tard le 18 juillet 2019 à 20:26:21 GMT. Avec le filtre create_time, vous pouvez exprimer le temps à l'aide des formats et types suivants :

  • Heure Unix (en millisecondes) sous forme de littéral entier

    "create_time <= 1563481581000"
    
  • RFC 3339 en tant que littéral de chaîne

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

Exclure des éléments des résultats

Pour exclure un élément des résultats, utilisez la négation en plaçant un caractère - devant un paramètre. Cette opération est semblable à l'utilisation de l'opérateur NOT dans une instruction SQL.

Ce filtre renvoie toutes les ressources du projet, sauf Debia :

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

Étapes suivantes

En savoir plus sur l'accès à Security Command Center à l'aide d'un SDK.