Gérer les marques de sécurité à l'aide de l'API Security Command Center

>

Ce guide explique comment utiliser l'API Security Command Center pour gérer les marques de sécurité. Les marques de sécurité, ou simplement "marques", sont des annotations personnalisables sur les éléments ou les résultats dans Security Command Center qui vous permettent d'ajouter votre propre contexte commercial à ces objets.

Avant de commencer

Pour pouvoir utiliser des marques de sécurité, vous devez remplir les conditions suivantes :

Pour ajouter ou modifier des marques de sécurité, vous devez disposer d'un rôle de gestion de l'authentification et des accès incluant des autorisations pour le type de marque que vous souhaitez utiliser :

  • Marques d'éléments : Rédacteur de marques de sécurité d'élément, securitycenter.assetSecurityMarksWriter
  • Marques de résultats : Rédacteur de marques de sécurité de résultat, securitycenter.findingSecurityMarksWriter

Pour en savoir plus, consultez les pages Contrôle des accès et Utiliser les marques de sécurité de Security Command Center.

Ajouter ou mettre à jour des marques de sécurité sur des éléments

Lorsque vous utilisez l'API Security Command Center, l'ajout et la mise à jour de marques de sécurité sont identiques. L'exemple ci-dessous montre comment ajouter des marques de sécurité pour deux paires clé/valeur (key_a, value_a) et (key_b, value_b).

Le code suivant utilise des masques de champ pour garantir que seules ces valeurs sont mises à jour. Si vous ne fournissez pas de masques de champ, tous les marques de sécurité sont effacées avant d'ajouter les clés et les valeurs données.

gcloud

  # ORGANIZATION=12344321
  # ASSET=43211234
  SECURITY_MARKS="key_a=value_a,key_b=value_b"
  UPDATE_MASK="marks.key_a,marks.key_b"

  gcloud scc assets update-marks $ASSET \
      --organization $ORGANIZATION \
      --security-marks $SECURITY_MARKS \
      --update-mask $UPDATE_MASK

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

  gcloud scc assets update-marks --help

Python

from google.cloud import securitycenter
from google.protobuf import field_mask_pb2

# Create a new client.
client = securitycenter.SecurityCenterClient()

# asset_name is the resource path for an asset that exists in CSCC.
# Its format is "organization/{organization_id}/assets/{asset_id}
# e.g.:
# asset_name = organizations/123123342/assets/12312321
marks_name = "{}/securityMarks".format(asset_name)

# Notice the suffix after "marks." in the field mask matches the keys
# in marks.
field_mask = field_mask_pb2.FieldMask(paths=["marks.key_a", "marks.key_b"])
marks = {"key_a": "value_a", "key_b": "value_b"}

updated_marks = client.update_security_marks(
    {"name": marks_name, "marks": marks},
    # If this field was left empty, all marks would be cleared before adding
    # the new values.
    update_mask=field_mask,
)
print(updated_marks)

Java

static SecurityMarks addToAsset(String assetName) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // String assetName = "organizations/123123342/assets/12312321";
    // Start setting up a request to add security marks for an asset.
    ImmutableMap markMap = ImmutableMap.of("key_a", "value_a", "key_b", "value_b");

    // Add security marks and field mask for security marks.
    SecurityMarks securityMarks =
        SecurityMarks.newBuilder()
            .setName(assetName + "/securityMarks")
            .putAllMarks(markMap)
            .build();
    FieldMask updateMask =
        FieldMask.newBuilder().addPaths("marks.key_a").addPaths("marks.key_b").build();

    UpdateSecurityMarksRequest request =
        UpdateSecurityMarksRequest.newBuilder()
            .setSecurityMarks(securityMarks)
            .setUpdateMask(updateMask)
            .build();

    // Call the API.
    SecurityMarks response = client.updateSecurityMarks(request);

    System.out.println("Security Marks:");
    System.out.println(response);
    return response;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
	"google.golang.org/genproto/protobuf/field_mask"
)

// addSecurityMarks adds/updates a the security marks for the assetName.
// Specifically, it sets "key_a" an "key_b" to "value_a" and "value_b"
// respectively.  assetName is the resource path for an asset.
func addSecurityMarks(w io.Writer, assetName string) error {
	// assetName := "organizations/123123342/assets/12312321"
	// 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: %v", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.UpdateSecurityMarksRequest{
		// If not set or empty, all marks would be cleared before
		// adding the new marks below.
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"marks.key_a", "marks.key_b"},
		},
		SecurityMarks: &securitycenterpb.SecurityMarks{
			Name: fmt.Sprintf("%s/securityMarks", assetName),
			// Note keys correspond to the last part of each path.
			Marks: map[string]string{"key_a": "value_a", "key_b": "value_b"},
		},
	}
	updatedMarks, err := client.UpdateSecurityMarks(ctx, req)
	if err != nil {
		return fmt.Errorf("UpdateSecurityMarks: %v", err)
	}

	fmt.Fprintf(w, "Updated marks: %s\n", updatedMarks.Name)
	for k, v := range updatedMarks.Marks {
		fmt.Fprintf(w, "%s = %s\n", k, v)
	}
	return nil

}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');

// Creates a new client.
const client = new SecurityCenterClient();

async function addSecurityMarks() {
  // assetName is the full resource path for the asset to update.
  /*
   * TODO(developer): Uncomment the following lines
   */
  // const assetName = "organizations/123123342/assets/12312321";
  const [newMarks] = await client.updateSecurityMarks({
    securityMarks: {
      name: `${assetName}/securityMarks`,
      marks: {key_a: 'value_a', key_b: 'value_b'},
    },
    // Only update the marks with these keys.
    updateMask: {paths: ['marks.key_a', 'marks.key_b']},
  });

  console.log('New marks: %', newMarks);
}
addSecurityMarks();

Supprimer des marques de sécurité sur des éléments

La suppression de marques de sécurité spécifiques s'effectue de la même manière que leur ajout ou mise à jour, c'est-à-dire en appelant une mise à jour avec un masque de champ, mais sans aucune valeur correspondante. Dans l'exemple ci-dessous, les marques de sécurité dotées des clés key_a et key_b sont supprimées.

gcloud

  # ORGANIZATION=12344321
  # ASSET=43211234
  UPDATE_MASK="marks.key_a,marks.key_b"

  gcloud scc assets update-marks $ASSET \
      --organization $ORGANIZATION \
      --update-mask $UPDATE_MASK

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

  gcloud scc assets update-marks --help

Python

from google.cloud import securitycenter
from google.protobuf import field_mask_pb2

# Create a new client.
client = securitycenter.SecurityCenterClient()

# asset_name is the resource path for an asset that exists in CSCC.
# Its format is "organization/{organization_id}/assets/{asset_id}
# e.g.:
# asset_name = organizations/123123342/assets/12312321
marks_name = "{}/securityMarks".format(asset_name)

field_mask = field_mask_pb2.FieldMask(paths=["marks.key_a", "marks.key_b"])

updated_marks = client.update_security_marks(
    {
        "name": marks_name
        # Note, no marks specified, so the specified values in
        # the fields masks will be deleted.
    },
    # If this field was left empty, all marks would be cleared.
    update_mask=field_mask,
)
print(updated_marks)

Java

static SecurityMarks clearFromAsset(String assetName) {
  // String assetName = "organizations/123123342/assets/12312321";
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Start setting up a request to clear security marks for an asset.
    // Create security mark and field mask for clearing security marks.
    SecurityMarks securityMarks =
        SecurityMarks.newBuilder().setName(assetName + "/securityMarks").build();
    FieldMask updateMask =
        FieldMask.newBuilder().addPaths("marks.key_a").addPaths("marks.key_b").build();

    UpdateSecurityMarksRequest request =
        UpdateSecurityMarksRequest.newBuilder()
            .setSecurityMarks(securityMarks)
            .setUpdateMask(updateMask)
            .build();

    // Call the API.
    SecurityMarks response = client.updateSecurityMarks(request);

    System.out.println("Security Marks cleared:");
    System.out.println(response);
    return response;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
	"google.golang.org/genproto/protobuf/field_mask"
)

// deleteSecurityMarks deletes security marks "key_a" and  "key_b" from
// assetName's marks. assetName is the resource path for an asset.
func deleteSecurityMarks(w io.Writer, assetName string) error {
	// assetName := "organizations/123123342/assets/12312321"
	// 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: %v", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.UpdateSecurityMarksRequest{
		// If not set or empty, all marks would be cleared.
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"marks.key_a", "marks.key_b"},
		},
		SecurityMarks: &securitycenterpb.SecurityMarks{
			Name: fmt.Sprintf("%s/securityMarks", assetName),
			// Intentionally not setting marks with the
			// corresponding field mask deletes them.
		},
	}
	updatedMarks, err := client.UpdateSecurityMarks(ctx, req)
	if err != nil {
		return fmt.Errorf("UpdateSecurityMarks: %v", err)
	}

	fmt.Fprintf(w, "Updated marks: %s\n", updatedMarks.Name)
	for k, v := range updatedMarks.Marks {
		fmt.Fprintf(w, "%s = %s\n", k, v)
	}
	return nil
}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');

// Creates a new client.
const client = new SecurityCenterClient();

async function deleteSecurityMarks() {
  // assetName is the full resource path for the asset to update.
  /*
   * TODO(developer): Uncomment the following lines
   */
  // const assetName = "organizations/123123342/assets/12312321";
  const [newMarks] = await client.updateSecurityMarks({
    securityMarks: {
      name: `${assetName}/securityMarks`,
      // Intentionally, not setting marks to delete them.
    },
    // Only delete marks for the following keys.
    updateMask: {paths: ['marks.key_a', 'marks.key_b']},
  });

  console.log('Updated marks: %j', newMarks);
}
deleteSecurityMarks();

Ajouter et supprimer des marques de sécurité dans la même requête

La technique permettant d'ajouter et de mettre à jour des marques de sécurité, et de les supprimer, peut être combinée dans la même requête. Dans l'exemple ci-dessous, key_a est mis à jour alors que key_b est supprimé.

gcloud

  # ORGANIZATION=12344321
  # ASSET=43211234
  SECURITY_MARKS="key_a=new_value_for_a"
  UPDATE_MASK="marks.key_a,marks.key_b"

  gcloud scc assets update-marks $ASSET \
      --organization $ORGANIZATION \
      --security-marks $SECURITY_MARKS \
      --update-mask $UPDATE_MASK

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

  gcloud scc assets update-marks --help

gcloud

  # ORGANIZATION=12344321
  # ASSET=43211234
  SECURITY_MARKS="key_a=new_value_for_a"
  UPDATE_MASK="marks.key_a,marks.key_b"

  gcloud scc assets update-marks $ASSET \
      --organization $ORGANIZATION \
      --security-marks $SECURITY_MARKS \
      --update-mask $UPDATE_MASK

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

  gcloud scc assets update-marks --help

Python

from google.cloud import securitycenter
from google.protobuf import field_mask_pb2

client = securitycenter.SecurityCenterClient()
# asset_name is the resource path for an asset that exists in CSCC.
# Its format is "organization/{organization_id}/assets/{asset_id}
# e.g.:
# asset_name = organizations/123123342/assets/12312321
marks_name = "{}/securityMarks".format(asset_name)

field_mask = field_mask_pb2.FieldMask(paths=["marks.key_a", "marks.key_b"])
marks = {"key_a": "new_value_for_a"}

updated_marks = client.update_security_marks(
    {"name": marks_name, "marks": marks}, update_mask=field_mask
)
print(updated_marks)

Java

static SecurityMarks deleteAndUpdateMarks(String assetName) {
  // String assetName = "organizations/123123342/assets/12312321";
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Start setting up a request to clear and update security marks for an asset.
    // Create security mark and field mask for clearing security marks.
    SecurityMarks securityMarks =
        SecurityMarks.newBuilder()
            .setName(assetName + "/securityMarks")
            .putMarks("key_a", "new_value_for_a")
            .build();
    FieldMask updateMask =
        FieldMask.newBuilder().addPaths("marks.key_a").addPaths("marks.key_b").build();

    UpdateSecurityMarksRequest request =
        UpdateSecurityMarksRequest.newBuilder()
            .setSecurityMarks(securityMarks)
            .setUpdateMask(updateMask)
            .build();

    // Call the API.
    SecurityMarks response = client.updateSecurityMarks(request);

    System.out.println("Security Marks updated and cleared:");
    System.out.println(response);
    return response;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
	"google.golang.org/genproto/protobuf/field_mask"
)

// addDeleteSecurityMarks adds/updates "key_a" and deletes  "key_b" from
// assetName's securityMarks. assetName is the resource path for an asset.
func addDeleteSecurityMarks(w io.Writer, assetName string) error {
	// assetName := "organizations/123123342/assets/12312321"
	// 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: %v", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.UpdateSecurityMarksRequest{
		// If not set or empty, all marks would be cleared.
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"marks.key_a", "marks.key_b"},
		},
		SecurityMarks: &securitycenterpb.SecurityMarks{
			Name: fmt.Sprintf("%s/securityMarks", assetName),
			// Intentionally not setting marks for key_b to
			// delete it.
			Marks: map[string]string{"key_a": "new_value_a"},
		},
	}

	updatedMarks, err := client.UpdateSecurityMarks(ctx, req)
	if err != nil {
		return fmt.Errorf("UpdateSecurityMarks: %v", err)
	}

	fmt.Fprintf(w, "Updated marks: %s\n", updatedMarks.Name)
	for k, v := range updatedMarks.Marks {
		fmt.Fprintf(w, "%s = %s\n", k, v)
	}
	return nil
}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');

// Creates a new client.
const client = new SecurityCenterClient();

async function addDeleteSecurityMarks() {
  // assetName is the full resource path for the asset to update.
  /*
   * TODO(developer): Uncomment the following lines
   */
  // assetName = "organizations/123123342/assets/12312321";
  const [newMarks] = await client.updateSecurityMarks({
    securityMarks: {
      name: `${assetName}/securityMarks`,
      marks: {key_a: 'new_value_a'},
    },
    // Only update the enableAssetDiscovery field.
    updateMask: {paths: ['marks.key_a', 'marks.key_b']},
  });

  console.log('New marks: %j', newMarks);
}
addDeleteSecurityMarks();

Ajouter des marques de sécurité à des résultats

L'ajout, la mise à jour et la suppression de marques de sécurité sur des résultats suivent le même processus que la mise à jour de marques de sécurité sur des éléments. La seule différence réside dans le nom de la ressource utilisée dans l'appel d'API. Au lieu d'utiliser une ressource d'élément, vous devez fournir un nom de ressource de résultat.

Par exemple, pour mettre à jour des marques de sécurité dans un résultat, utilisez le code suivant :

gcloud

  # ORGANIZATION=12344321
  # SOURCE=43211234
  # FINDING_ID=testfindingid
  SECURITY_MARKS="key_a=value_a,key_b=value_b"
  UPDATE_MASK="marks.key_a,marks.key_b"

  gcloud scc findings update-marks $FINDING_ID \
      --source $SOURCE \
      --organization $ORGANIZATION \
      --security-marks $SECURITY_MARKS \
      --update-mask $UPDATE_MASK

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

  gcloud scc findings update-marks --help

Python

from google.cloud import securitycenter
from google.protobuf import field_mask_pb2

client = securitycenter.SecurityCenterClient()
# finding_name is the resource path for a finding that exists in CSCC.
# Its format is
# "organizations/{org_id}/sources/{source_id}/findings/{finding_id}"
# e.g.:
# finding_name = "organizations/1112/sources/1234/findings/findingid"
finding_marks_name = "{}/securityMarks".format(finding_name)

# Notice the suffix after "marks." in the field mask matches the keys
# in marks.
field_mask = field_mask_pb2.FieldMask(
    paths=["marks.finding_key_a", "marks.finding_key_b"]
)
marks = {"finding_key_a": "value_a", "finding_key_b": "value_b"}

updated_marks = client.update_security_marks(
    {"name": finding_marks_name, "marks": marks}, update_mask=field_mask
)

Java

static SecurityMarks addToFinding(FindingName findingName) {
  // FindingName findingName = FindingName.of(/*organization=*/"123234324",
  // /*source=*/"423432321", /*findingId=*/"samplefindingid2");
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Start setting up a request to add security marks for a finding.
    ImmutableMap markMap = ImmutableMap.of("key_a", "value_a", "key_b", "value_b");

    // Add security marks and field mask for security marks.
    SecurityMarks securityMarks =
        SecurityMarks.newBuilder()
            .setName(findingName + "/securityMarks")
            .putAllMarks(markMap)
            .build();
    FieldMask updateMask =
        FieldMask.newBuilder().addPaths("marks.key_a").addPaths("marks.key_b").build();

    UpdateSecurityMarksRequest request =
        UpdateSecurityMarksRequest.newBuilder()
            .setSecurityMarks(securityMarks)
            .setUpdateMask(updateMask)
            .build();

    // Call the API.
    SecurityMarks response = client.updateSecurityMarks(request);

    System.out.println("Security Marks:");
    System.out.println(response);
    return response;
  } catch (IOException e) {
    throw new RuntimeException("Couldn't create client.", e);
  }
}

Go

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
	"google.golang.org/genproto/protobuf/field_mask"
)

// addSecurityMarks adds/updates a the security marks for the findingName and
// returns the updated marks. Specifically, it sets "key_a" an "key_b" to
// "value_a" and "value_b" respectively. findingName is the resource path for
// the finding to add marks to.
func addSecurityMarks(w io.Writer, findingName string) error {
	// findingName := "organizations/11123213/sources/12342342/findings/fidningid"
	// 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: %v", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.UpdateSecurityMarksRequest{
		// If not set or empty, all marks would be cleared before
		// adding the new marks below.
		UpdateMask: &field_mask.FieldMask{
			Paths: []string{"marks.key_a", "marks.key_b"},
		},
		SecurityMarks: &securitycenterpb.SecurityMarks{
			Name: fmt.Sprintf("%s/securityMarks", findingName),
			// Note keys correspond to the last part of each path.
			Marks: map[string]string{"key_a": "value_a", "key_b": "value_b"},
		},
	}

	updatedMarks, err := client.UpdateSecurityMarks(ctx, req)
	if err != nil {
		return fmt.Errorf("UpdateSecurityMarks: %v", err)
	}

	fmt.Fprintf(w, "Updated marks: %s\n", updatedMarks.Name)
	for k, v := range updatedMarks.Marks {
		fmt.Fprintf(w, "%s = %s\n", k, v)
	}
	return nil
}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');

// Creates a new client.
const client = new SecurityCenterClient();

async function addFindingSecurityMarks() {
  // findingName is the full resource path for the finding to update.
  /*
   * TODO(developer): Uncomment the following lines
   */
  // const findingName =
  // "organizations/123123342/sources/1213/findings/findingid";
  const [newMarks] = await client.updateSecurityMarks({
    securityMarks: {
      name: `${findingName}/securityMarks`,
      marks: {key_a: 'value_a', key_b: 'value_b'},
    },
    // Only update the marks with these keys.
    updateMask: {paths: ['marks.key_a', 'marks.key_b']},
  });

  console.log('New marks: %j', newMarks);
}
addFindingSecurityMarks();

Répertorier des éléments avec des filtres de marque de sécurité

Une fois les marques de sécurité définies sur un élément, elles peuvent être utilisées dans l'argument de filtre de l'appel d'API ListAssets. Par exemple, pour appeler tous les éléments utilisant key_a = value_a, utilisez le code suivant :

gcloud

  # ORGANIZATION=12344321
  FILTER="security_marks.marks.key_a = \"value_a\""

  gcloud scc assets list $ORGANIZATION \
      --filter "$FILTER"

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

  gcloud scc assets list --help

Python

from google.cloud import securitycenter

client = securitycenter.SecurityCenterClient()

# organization_id is the numeric ID of the organization.
# organization_id=1234567777
org_name = "organizations/{org_id}".format(org_id=organization_id)

marks_filter = 'security_marks.marks.key_a = "value_a"'
# Call the API and print results.
asset_iterator = client.list_assets(org_name, filter_=marks_filter)

# Call the API and print results.
asset_iterator = client.list_assets(org_name, filter_=marks_filter)
for i, asset_result in enumerate(asset_iterator):
    print(i, asset_result)

Java

static ImmutableList<ListAssetsResult> listAssetsWithQueryMarks(
    OrganizationName organizationName) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Start setting up a request for to list all assets filtered by a specific security mark.
    // OrganizationName organizationName = OrganizationName.of(/*organizationId=*/"123234324");
    ListAssetsRequest request =
        ListAssetsRequest.newBuilder()
            .setParent(organizationName.toString())
            .setFilter("security_marks.marks.key_a = \"value_a\"")
            .build();

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

    // 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 batches by returning
    // the Iterable returned response.iterateAll() directly.
    ImmutableList<ListAssetsResult> results = ImmutableList.copyOf(response.iterateAll());
    System.out.println("Assets with security mark - key_a=value_a:");
    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"
	"google.golang.org/api/iterator"
	securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
)

// listAssetsWithMarks prints assets that have a mark of key_a equal to value_a
// to w for orgID.  orgID is the numeric Organization ID.
func listAssetsWithMarks(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: %v", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.ListAssetsRequest{
		Parent: fmt.Sprintf("organizations/%s", orgID),
		Filter: `security_marks.marks.key_a = "value_a"`,
	}

	it := client.ListAssets(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("ListAssets: %v", 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)
	}
	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.
async function listAssetsWithSecurityMarks() {
  const [response] = await client.listAssets({
    parent: orgName,
    filter: 'security_marks.marks.key_a="value_a"',
  });
  let count = 0;
  Array.from(response).forEach(result =>
    console.log(
      `${++count} ${result.asset.name} ${
        result.asset.securityCenterProperties.resourceName
      }`
    )
  );
}

listAssetsWithSecurityMarks();

Répertorier des résultats avec des filtres de marque de sécurité

Une fois les marques de sécurité définies dans un résultat, elles peuvent être utilisées dans l'argument de filtre de l'appel d'API ListFindings. Par exemple, pour interroger tous les éléments utilisant key_a != value_a, utilisez le code suivant :

gcloud

  # ORGANIZATION=12344321
  # SOURCE=43211234
  FILTER="NOT security_marks.marks.key_a=\"value_a\""

  gcloud scc findings list $ORGANIZATION \
      --source $SOURCE \
      --filter "$FILTER"

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

  gcloud scc findings list --help

Python

from google.cloud import securitycenter

client = securitycenter.SecurityCenterClient()

# source_name is the resource path for a source that has been
# created previously (you can use list_sources to find a specific one).
# Its format is:
# source_name = "organizations/{organization_id}/sources/{source_id}"
# e.g.:
# source_name = "organizations/111122222444/sources/1234"
marks_filter = 'NOT security_marks.marks.finding_key_a="value_a"'

# Call the API and print results.
finding_iterator = client.list_findings(source_name, filter_=marks_filter)
for i, finding_result in enumerate(finding_iterator):
    print(i, finding_result)

Java

static ImmutableList<ListFindingsResult> listFindingsWithQueryMarks(SourceName sourceName) {
  try (SecurityCenterClient client = SecurityCenterClient.create()) {
    // Start setting up a request for to list all findings filtered by a specific security mark.
    // SourceName sourceName = SourceName.of(/*organization=*/"123234324",/*source=*/
    // "423432321");

    String filter = "NOT security_marks.marks.key_a=\"value_a\"";

    ListFindingsRequest.Builder request =
        ListFindingsRequest.newBuilder().setParent(sourceName.toString()).setFilter(filter);

    // Call the API.
    ListFindingsPagedResponse response = client.listFindings(request.build());

    // This creates one list for all findings in the filter.If your organization has a large
    // number of
    // findings this can cause out of memory issues.  You can process them batches by returning
    // the Iterable returned response.iterateAll() directly.
    ImmutableList<ListFindingsResult> results = ImmutableList.copyOf(response.iterateAll());
    System.out.println("Findings with security mark - key_a=value_a:");
    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"
	"google.golang.org/api/iterator"
	securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
)

// listFindingsWithMarks prints findings that don't have a security mark
// key_a equal to value_a to w.  sourceName is the full resource name
// of the source to search for findings under.
func listFindingsWithMarks(w io.Writer, sourceName string) error {
	// sourceName := "organizations/111122222444/sources/1234"
	// Instantiate a context and a security service client to make API calls.
	ctx := context.Background()
	client, err := securitycenter.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("securitycenter.NewClient: %v", err)
	}
	defer client.Close() // Closing the client safely cleans up background resources.

	req := &securitycenterpb.ListFindingsRequest{
		Parent: sourceName,
		Filter: `NOT security_marks.marks.key_a="value_a"`,
	}
	it := client.ListFindings(ctx, req)
	for {
		result, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("it.Next: %v", err)
		}
		finding := result.Finding
		fmt.Fprintf(w, "Finding Name: %s, ", finding.Name)
		fmt.Fprintf(w, "Resource Name %s, ", finding.ResourceName)
		fmt.Fprintf(w, "Category: %s\n", finding.Category)
	}
	return nil
}

Node.js

// Imports the Google Cloud client library.
const {SecurityCenterClient} = require('@google-cloud/security-center');

// Creates a new client.
const client = new SecurityCenterClient();
//  sourceName is the full resource path of the source to search for
//  findings.
/*
 * TODO(developer): Uncomment the following lines
 */
// const sourceName = "organizations/111122222444/sources/1234";

async function listFindingsWithSecurityMarks() {
  const [response] = await client.listFindings({
    // List findings across all sources.
    parent: sourceName,
    filter: 'NOT security_marks.marks.key_a="value_a"',
  });
  let count = 0;
  Array.from(response).forEach(result =>
    console.log(
      `${++count} ${result.finding.name} ${result.finding.resourceName}`
    )
  );
}
listFindingsWithSecurityMarks();

Étape suivante