Mostrar recursos con la API de Security Command Center

Los recursos son los recursos de una organización, como las instancias de Compute Engine o los segmentos de Cloud Storage. Google Cloud

En esta guía se explica cómo usar las bibliotecas de cliente de Security Command Center para acceder a los registros obsoletos que Security Command Center mantiene de los recursos de un proyecto o una organización.

Security Command Center solo registra un subconjunto de los recursos de Cloud Asset Inventory. Para obtener la lista más completa de recursos de tu entorno, usa Inventario de Recursos de Cloud.

Para obtener más información, consulta las siguientes secciones:

Niveles de concesión de roles de gestión de identidades y accesos

Los roles de gestión de identidades y accesos de Security Command Center se pueden conceder a nivel de organización, carpeta o proyecto. La posibilidad de ver, editar, crear o actualizar hallazgos, recursos y fuentes de seguridad depende del nivel de acceso que se te haya concedido. Para obtener más información sobre los roles de Security Command Center, consulta Control de acceso.

Antes de empezar

Antes de configurar una fuente, debes hacer lo siguiente:

Tamaño de página

Todas las APIs de lista de Security Command Center están paginadas. Cada respuesta devuelve una página de resultados y un token para devolver la página siguiente. El tamaño de la página se puede configurar. El valor predeterminado de pageSize es 10, pero se puede definir en un mínimo de 1 y un máximo de 1000.

Tipos de recursos

El atributo resourceType de Security Command Center usa una convención de nomenclatura diferente a la de Inventario de Recursos de Cloud. Para ver una lista de formatos de tipos de recursos, consulta Tipos de recursos admitidos en Security Command Center.

Mostrar todos los recursos

En estos ejemplos se muestra cómo enumerar todos los recursos:

gcloud

Para enumerar todos los recursos de un proyecto, una carpeta o una organización, ejecuta el siguiente comando:

gcloud scc assets list PARENT_ID

Sustituye PARENT_ID por uno de los siguientes valores:

  • Un ID de organización con el siguiente formato: ORGANIZATION_ID (solo el ID numérico)
  • Un ID de carpeta con el siguiente formato: folders/FOLDER_ID
  • Un ID de proyecto con el siguiente formato: projects/PROJECT_ID

Para ver más ejemplos, ejecuta el siguiente comando:

 gcloud scc assets list --help

Para ver ejemplos en la documentación, 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);
  }
}

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

La salida de cada recurso es un objeto JSON similar al siguiente:

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'

Filtrar recursos

Un proyecto, una carpeta o una organización pueden tener muchos recursos. En el ejemplo anterior no se usa ningún filtro, por lo que se devuelven todos los recursos. Security Command Center te permite usar filtros de recursos para obtener información sobre recursos específicos. Los filtros son como las cláusulas "where" de las instrucciones SQL, pero en lugar de aplicarse a las columnas, se aplican a los objetos devueltos por la API.

En el ejemplo de salida anterior se muestran algunos campos y subcampos, así como sus propiedades, que se pueden usar en los filtros de recursos. Security Command Center admite matrices y objetos JSON completos como posibles tipos de propiedad. Puedes filtrar por:

  • Elementos de matriz
  • Objetos JSON completos con coincidencias de cadena parciales en el objeto
  • Subcampos de objeto JSON

Los subcampos deben ser números, cadenas o valores booleanos, y las expresiones de filtro deben usar los siguientes operadores de comparación:

  • Cadenas:
    • Igualdad total =
    • Coincidencia parcial de cadenas :
  • Números:
    • Desigualdades <, >, <=, >=
    • Igualdad =
  • Booleanos:
    • Igualdad =

En los siguientes ejemplos se filtran recursos:

gcloud

Usa el siguiente comando para filtrar recursos:

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

Haz los cambios siguientes:

  • FILTER con el filtro que necesites usar. Por ejemplo, el siguiente filtro solo devuelve recursos de proyectos:
    --filter="security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\""
  • PARENT_ID con uno de los siguientes valores:
    • Un ID de organización con el siguiente formato: ORGANIZATION_ID (solo el ID numérico)
    • Un ID de carpeta con el siguiente formato: folders/FOLDER_ID
    • Un ID de proyecto con el siguiente formato: projects/PROJECT_ID

Para ver más ejemplos, ejecuta el siguiente comando:

gcloud scc assets list --help

Para ver ejemplos en la documentación, 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);
  }
}

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

Lista en un momento dado

En los ejemplos anteriores se muestra cómo enumerar un conjunto de recursos actual. Security Command Center también te permite ver un registro histórico de los recursos. En los siguientes ejemplos se devuelve el estado de todos los recursos en un momento dado. Security Command Center admite resoluciones de tiempo de milisegundos.

gcloud

Usa el siguiente comando para enumerar los recursos en un momento concreto:

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

Haz los cambios siguientes:

  • READ_TIME con la hora a la que se deben mostrar los recursos. Utiliza el siguiente formato: YYYY-MM-DDThh:mm:ss.ffffffZ. Por ejemplo:
    --read-time="2022-12-21T07:00:06.861Z"
  • PARENT_ID con uno de los siguientes valores:
    • Un ID de organización con el siguiente formato: ORGANIZATION_ID (solo el ID numérico)
    • Un ID de proyecto con el siguiente formato: projects/PROJECT_ID
    • Un ID de carpeta con el siguiente formato: folders/FOLDER_ID

Para ver más ejemplos, ejecuta el siguiente comando:

gcloud scc assets list --help

Para ver ejemplos en la documentación, 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);
  }
}

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

Mostrar recursos con cambios de estado

Security Command Center te permite comparar un recurso en dos momentos distintos para identificar si se ha añadido, eliminado o estaba presente durante el periodo especificado. En los siguientes ejemplos se comparan proyectos que existen en READ_TIME con un momento anterior especificado por COMPARE_DURATION. COMPARE_DURATION se proporciona en segundos.

Cuando se define COMPARE_DURATION, el atributo stateChange de los resultados de list asset se actualiza con uno de los siguientes valores:

  • ADDED: el recurso no estaba presente al inicio de compareDuration, pero sí en readTime.
  • REMOVED: el recurso estaba presente al principio de compareDuration, pero no en readTime.
  • ACTIVE: el recurso estaba presente tanto al principio como al final del periodo definido por compareDuration y readTime.

gcloud

Usa el siguiente comando para comparar el estado de los recursos en dos momentos distintos:

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

Haz los cambios siguientes:

  • COMPARE_DURATION con un número de segundos que define un momento anterior al especificado en la marca --read-time. Por ejemplo:
    --compare-duration=84600s
  • FILTER con el filtro que necesites usar. Por ejemplo, el siguiente filtro solo devuelve recursos de proyectos:
    --filter="security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\""
  • PARENT_ID con uno de los siguientes valores:
    • Un ID de organización con el siguiente formato: ORGANIZATION_ID (solo el ID numérico)
    • Un ID de proyecto con el siguiente formato: projects/PROJECT_ID
    • Un ID de carpeta con el siguiente formato: folders/FOLDER_ID
  • READ_TIME con la hora a la que se deben mostrar los recursos. Utiliza el siguiente formato: YYYY-MM-DDThh:mm:ss.ffffffZ. Por ejemplo:
    --read-time="2022-12-21T07:00:06.861Z"
    Para ver más ejemplos, ejecuta el siguiente comando:
gcloud scc assets list --help

Para ver ejemplos en la documentación, 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);
  }
}

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

Ejemplos de filtros

A continuación, se indican otros filtros de recursos útiles. Puedes usar AND y OR en los filtros para combinar parámetros y ampliar o acotar los resultados.

Buscar un recurso de proyecto con un propietario específico

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

$USER suele tener el formato user:someone@domain.com. La comparación de user usa el operador de subcadena : y no es necesario que sea una coincidencia exacta.

Reglas de cortafuegos que tienen puertos HTTP abiertos

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

Recursos que pertenecen a proyectos específicos

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

$PROJECT_1_NAME y $PROJECT_2_NAME son identificadores de recursos con el formato //cloudresourcemanager.googleapis.com/projects/$PROJECT_ID, donde $PROJECT_ID es el número de proyecto. Un ejemplo completo sería el siguiente: //cloudresourcemanager.googleapis.com/projects/100090906

Buscar imágenes de Compute Engine cuyos nombres contengan una cadena específica

Este filtro devuelve las imágenes de Compute Engine que contienen la subcadena "Debia":

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

Recursos cuyas propiedades contienen pares clave-valor

Este filtro devuelve los segmentos de Cloud Storage en los que bucketPolicyOnly está inhabilitado. El valor de resourceProperties.iamConfiguration se codifica como una cadena. El carácter \ se usa para aplicar caracteres de escape a los caracteres especiales de las cadenas, incluido el operador : entre el nombre de la clave y el valor.

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

Buscar recursos de proyectos creados en un momento concreto o antes

Estos filtros de ejemplo coinciden con los recursos creados el 18 de julio del 2019 o antes a las 20:26:21 (GMT). Con el filtro create_time, puede expresar el tiempo con los siguientes formatos y tipos:

  • Tiempo Unix (en milisegundos) como literal entero

    "create_time <= 1563481581000"
    
  • RFC 3339 como literal de cadena

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

Excluir recursos de los resultados

Para excluir un recurso de los resultados, usa la negación colocando el carácter - delante de un parámetro. La operación es similar a usar el operador NOT en una instrucción SQL.

Este filtro devuelve todos los recursos del proyecto, excepto Debia:

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

Siguientes pasos

Consulte más información sobre cómo acceder a Security Command Center mediante una biblioteca de cliente.