Contrôler l'accès aux ensembles de données

Ce document explique comment contrôler l'accès aux ensembles de données dans BigQuery.

Vous pouvez également effectuer les opérations suivantes :

Présentation

Les autorisations au niveau des ensembles de données déterminent les utilisateurs, les groupes et les comptes de service autorisés à accéder aux tables, aux vues et aux données de table d'un ensemble de données spécifique. Par exemple, si vous accordez le rôle IAM (Identity and Access Management) bigquery.dataOwner à un utilisateur d'un ensemble de données spécifique, celui-ci pourra créer, mettre à jour et supprimer des tables et des vues dans ensemble de données.

Vous pouvez appliquer des contrôles d'accès lors de la création d'un ensemble de données en appelant la méthode API datasets.insert.

Il n'est pas possible d'appliquer des contrôles d'accès lors de la création d'un ensemble de données dans Google Cloud Console, dans l'outil de ligne de commande bq ou via des instructions LDD (langage de définition de données).

Vous pouvez appliquer des contrôles d'accès à un ensemble de données après sa création de plusieurs façons :

  • Utiliser la console
  • Utiliser les instructions LCD GRANT et REVOKE
  • Utiliser la commande bq update de l'outil de ligne de commande bq
  • En appelant la méthode API datasets.patch
  • Utiliser les bibliothèques clientes

Avant de commencer

Accordez des rôles IAM qui donnent aux utilisateurs les autorisations nécessaires pour effectuer chaque tâche de ce document.

Autorisations requises

Pour contrôler l'accès à un ensemble de données, vous devez disposer des autorisations IAM suivantes :

  • bigquery.datasets.update
  • bigquery.datasets.get
  • bigquery.datasets.getIamPolicy (vous permet de contrôler l'accès à un ensemble de données à l'aide de la console)
  • bigquery.datasets.setIamPolicy (vous permet de contrôler l'accès à un ensemble de données à l'aide de la console)

Le rôle Cloud IAM prédéfini roles/bigquery.dataOwner inclut les autorisations dont vous avez besoin pour contrôler l'accès à un ensemble de données.

Pour en savoir plus sur les rôles et les autorisations IAM dans BigQuery, consultez la page Rôles prédéfinis et autorisations.

Accorder l'accès à un ensemble de données

Pour accorder l'accès à un ensemble de données, procédez comme suit :

Console

  1. Dans le panneau Explorateur, développez votre projet et sélectionnez un ensemble de données.

  2. Dans le panneau des détails, cliquez sur Partage > Autorisations.

  3. Cliquez sur Ajouter un compte principal.

  4. Dans le champ Nouveaux comptes principaux, saisissez l'entité que vous souhaitez ajouter. Vous pouvez ajouter l'une des entités suivantes :

    • Adresse e-mail du compte Google : permet à un compte Google individuel d'accéder à l'ensemble de données
    • Groupe Google : permet à tous les membres d'un groupe Google d'accéder à l'ensemble de données
    • Domaine Google Apps : permet à tous les utilisateurs et groupes d'un domaine Google d'accéder à l'ensemble de données
    • Compte de service : permet à un compte de service d'accéder à l'ensemble de données
    • Tous les utilisateurs : saisissez allUsers pour accorder l'accès au grand public
    • Tous les comptes Google : saisissez allAuthenticatedUsers pour autoriser l'accès à tous les comptes de service et à tous les utilisateurs qui se sont authentifiés avec un compte Google. Exemple : user@gmail.com.
  5. Pour Rôle, sélectionnez BigQuery et choisissez un rôle IAM prédéfini approprié pour les nouveaux membres. Pour en savoir plus sur les autorisations affectées à chaque rôle BigQuery prédéfini, reportez-vous à la section Rôles de la page "Contrôle des accès".

  6. Cliquez sur OK.

SQL

L'exemple suivant utilise l'instruction LDD GRANT pour attribuer le rôle de lecteur de données BigQuery (roles/bigquery.dataViewer) à l'utilisateur joe@example.com sur l'ensemble de données mydataset :

  1. Dans la console, accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez l'instruction suivante :

    GRANT `roles/bigquery.dataViewer`
    ON SCHEMA mydataset
    TO 'user:joe@example.com';
    

  3. Cliquez sur Exécuter.

Pour en savoir plus sur l'exécution des requêtes, consultez la page Exécuter des requêtes interactives.

bq

  1. Écrivez les informations sur l'ensemble de données existant (y compris les contrôles d'accès) dans un fichier JSON à l'aide de la commande show. Si l'ensemble de données se trouve dans un projet autre que votre projet par défaut, ajoutez l'ID du projet au nom de l'ensemble de données, en respectant le format suivant : project_id:dataset.

    bq show \
    --format=prettyjson \
    project_id:dataset > path_to_file
    

    Remplacez l'élément suivant :

    • project_id est l'ID de votre projet.
    • dataset est le nom de votre ensemble de données ;
    • path_to_file est le chemin d'accès au fichier JSON sur votre ordinateur local.

    Exemples :

    Saisissez la commande suivante pour écrire les contrôles d'accès pour mydataset dans un fichier JSON. mydataset se trouve dans votre projet par défaut.

      bq show --format=prettyjson mydataset > /tmp/mydataset.json
    

    Saisissez la commande suivante pour écrire les contrôles d'accès pour mydataset dans un fichier JSON. mydataset se trouve dans myotherproject.

      bq show --format=prettyjson \
      myotherproject:mydataset > /tmp/mydataset.json
    
  2. Apportez vos modifications à la section "access" du fichier JSON. Vous pouvez ajouter n'importe quelle entrée specialGroup : projectOwners, projectWriters, projectReaders et allAuthenticatedUsers. Vous pouvez également ajouter ou modifier l'un des éléments suivants : userByEmail, groupByEmail et domain.

    Par exemple, la section d'accès du fichier JSON d'un ensemble de données ressemblerait à ceci :

    {
     "access": [
      {
       "role": "READER",
       "specialGroup": "projectReaders"
      },
      {
       "role": "WRITER",
       "specialGroup": "projectWriters"
      },
      {
       "role": "OWNER",
       "specialGroup": "projectOwners"
      },
      {
       "role": "READER",
       "specialGroup": "allAuthenticatedUsers"
      },
      {
       "role": "READER",
       "domain": "domain_name"
      },
      {
       "role": "WRITER",
       "userByEmail": "user_email"
      },
      {
       "role": "WRITER",
       "userByEmail": "service_account_email"
      },
      {
       "role": "READER",
       "groupByEmail": "group_email"
      }
     ],
     ...
    }
    

  3. Une fois vos modifications terminées, exécutez la commande update et incluez le fichier JSON à l'aide de l'option --source. Si l'ensemble de données se trouve dans un projet autre que votre projet par défaut, ajoutez l'ID du projet au nom de l'ensemble de données, en respectant le format suivant : project_id:dataset.

    bq update \
    --source path_to_file \
    project_id:dataset
    

    Remplacez l'élément suivant :

    • path_to_file est le chemin d'accès au fichier JSON sur votre ordinateur local.
    • project_id est l'ID de votre projet ;
    • dataset est le nom de votre ensemble de données.

    Exemples :

    Saisissez la commande suivante pour mettre à jour les contrôles d'accès pour mydataset. mydataset se trouve dans votre projet par défaut.

        bq update --source /tmp/mydataset.json mydataset
    

    Saisissez la commande suivante pour mettre à jour les contrôles d'accès pour mydataset. mydataset se trouve dans myotherproject.

        bq update --source /tmp/mydataset.json myotherproject:mydataset
    
  4. Pour vérifier les modifications apportées aux contrôles d'accès, saisissez à nouveau la commande show sans écrire les informations dans un fichier.

    bq show --format=prettyjson dataset
    

    ou

    bq show --format=prettyjson project_id:dataset
    

API

Appelez datasets.insert avec une ressource d'ensemble de données définie pour appliquer les contrôles d'accès lors de la création de l'ensemble de données. Appelez datasets.patch et utilisez la propriété access de la ressource Dataset pour mettre à jour les contrôles d'accès.

Comme la méthode datasets.update remplace la ressource d'ensemble de données dans son intégralité, il est préférable d'utiliser la méthode datasets.patch.

Go

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Go décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery en langage Go.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// updateDatasetAccessControl demonstrates how the access control policy of a dataset
// can be amended by adding an additional entry corresponding to a specific user identity.
func updateDatasetAccessControl(projectID, datasetID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	ds := client.Dataset(datasetID)
	meta, err := ds.Metadata(ctx)
	if err != nil {
		return err
	}
	// Append a new access control entry to the existing access list.
	update := bigquery.DatasetMetadataToUpdate{
		Access: append(meta.Access, &bigquery.AccessEntry{
			Role:       bigquery.ReaderRole,
			EntityType: bigquery.UserEmailEntity,
			Entity:     "sample.bigquery.dev@gmail.com"},
		),
	}

	// Leverage the ETag for the update to assert there's been no modifications to the
	// dataset since the metadata was originally read.
	if _, err := ds.Update(ctx, update, meta.ETag); err != nil {
		return err
	}
	return nil
}

Java

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Java décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Java.

import com.google.cloud.bigquery.Acl;
import com.google.cloud.bigquery.Acl.Role;
import com.google.cloud.bigquery.Acl.User;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Dataset;
import java.util.ArrayList;

public class UpdateDatasetAccess {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    // Create a new ACL granting the READER role to "sample.bigquery.dev@gmail.com"
    // For more information on the types of ACLs available see:
    // https://cloud.google.com/storage/docs/access-control/lists
    Acl newEntry = Acl.of(new User("sample.bigquery.dev@gmail.com"), Role.READER);

    updateDatasetAccess(datasetName, newEntry);
  }

  public static void updateDatasetAccess(String datasetName, Acl newEntry) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      Dataset dataset = bigquery.getDataset(datasetName);

      // Get a copy of the ACLs list from the dataset and append the new entry
      ArrayList<Acl> acls = new ArrayList<>(dataset.getAcl());
      acls.add(newEntry);

      bigquery.update(dataset.toBuilder().setAcl(acls).build());
      System.out.println("Dataset Access Control updated successfully");
    } catch (BigQueryException e) {
      System.out.println("Dataset Access control was not updated \n" + e.toString());
    }
  }
}

Python

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Python décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Python.

Définissez la propriété dataset.access_entries avec les contrôles d'accès pour un ensemble de données. Appelez ensuite la fonction client.update_dataset() pour mettre à jour la propriété.

# TODO(developer): Set dataset_id to the ID of the dataset to fetch.
dataset_id = "your-project.your_dataset"

# TODO(developer): Set entity_id to the ID of the email or group from whom
# you are adding access. Alternatively, to the JSON REST API representation
# of the entity, such as a view's table reference.
entity_id = "user-or-group-to-add@example.com"

from google.cloud.bigquery.enums import EntityTypes

# TODO(developer): Set entity_type to the type of entity you are granting access to.
# Common types include:
#
# * "userByEmail" -- A single user or service account. For example "fred@example.com"
# * "groupByEmail" -- A group of users. For example "example@googlegroups.com"
# * "view" -- An authorized view. For example
#       {"projectId": "p", "datasetId": "d", "tableId": "v"}
#
# For a complete reference, see the REST API reference documentation:
# https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets#Dataset.FIELDS.access
entity_type = EntityTypes.GROUP_BY_EMAIL

# TODO(developer): Set role to a one of the "Basic roles for datasets"
# described here:
# https://cloud.google.com/bigquery/docs/access-control-basic-roles#dataset-basic-roles
role = "READER"

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

dataset = client.get_dataset(dataset_id)  # Make an API request.

entries = list(dataset.access_entries)
entries.append(
    bigquery.AccessEntry(
        role=role,
        entity_type=entity_type,
        entity_id=entity_id,
    )
)
dataset.access_entries = entries

dataset = client.update_dataset(dataset, ["access_entries"])  # Make an API request.

full_dataset_id = "{}.{}".format(dataset.project, dataset.dataset_id)
print(
    "Updated dataset '{}' with modified user permissions.".format(full_dataset_id)
)

Révoquer l'accès à un ensemble de données

Pour révoquer l'accès à un ensemble de données, procédez comme suit :

Console

  1. Dans le panneau Explorateur, développez votre projet et sélectionnez un ensemble de données.

  2. Dans le panneau des détails, cliquez sur Partage > Autorisations.

  3. Dans la boîte de dialogue Autorisations d'ensemble de données, développez le rôle dont vous souhaitez modifier l'appartenance.

  4. Pour le compte utilisateur que vous souhaitez supprimer, cliquez sur Supprimer.

  5. Dans la boîte de dialogue Supprimer le membre ?, cliquez sur Supprimer.

  6. Cliquez sur OK.

SQL

L'exemple suivant utilise l'instruction LCD REVOKE pour supprimer le rôle de lecteur de données BigQuery (roles/bigquery.dataViewer) de l'utilisateur joe@example.com sur l'ensemble de données mydataset :

  1. Dans la console, accédez à la page BigQuery.

    Accéder à BigQuery

  2. Dans l'éditeur de requête, saisissez l'instruction suivante :

    REVOKE `roles/bigquery.dataViewer`
    ON SCHEMA mydataset
    FROM 'user:joe@example.com';
    

  3. Cliquez sur Exécuter.

Pour en savoir plus sur l'exécution des requêtes, consultez la page Exécuter des requêtes interactives.

bq

  1. Écrivez les informations sur l'ensemble de données existant (y compris les contrôles d'accès) dans un fichier JSON à l'aide de la commande show. Si l'ensemble de données se trouve dans un projet autre que votre projet par défaut, ajoutez l'ID du projet au nom de l'ensemble de données, en respectant le format suivant : project_id:dataset.

    bq show \
    --format=prettyjson \
    project_id:dataset > path_to_file
    

    Remplacez l'élément suivant :

    • project_id est l'ID de votre projet.
    • dataset est le nom de votre ensemble de données ;
    • path_to_file est le chemin d'accès au fichier JSON sur votre ordinateur local.

    Exemples :

    Saisissez la commande suivante pour écrire les contrôles d'accès pour mydataset dans un fichier JSON. mydataset se trouve dans votre projet par défaut.

      bq show --format=prettyjson mydataset > /tmp/mydataset.json
    

    Saisissez la commande suivante pour écrire les contrôles d'accès pour mydataset dans un fichier JSON. mydataset se trouve dans myotherproject.

      bq show --format=prettyjson \
      myotherproject:mydataset > /tmp/mydataset.json
    
  2. Apportez vos modifications à la section "access" du fichier JSON. Vous pouvez supprimer n'importe quelle entrée specialGroup : projectOwners, projectWriters, projectReaders et allAuthenticatedUsers. Vous pouvez également supprimer l'un des éléments suivants : userByEmail, groupByEmail et domain.

    Par exemple, la section d'accès du fichier JSON d'un ensemble de données ressemblerait à ceci :

    {
     "access": [
      {
       "role": "READER",
       "specialGroup": "projectReaders"
      },
      {
       "role": "WRITER",
       "specialGroup": "projectWriters"
      },
      {
       "role": "OWNER",
       "specialGroup": "projectOwners"
      },
      {
       "role": "READER",
       "specialGroup": "allAuthenticatedUsers"
      },
      {
       "role": "READER",
       "domain": "domain_name"
      },
      {
       "role": "WRITER",
       "userByEmail": "user_email"
      },
      {
       "role": "READER",
       "groupByEmail": "group_email"
      }
     ],
     ...
    }
    

  3. Une fois vos modifications terminées, exécutez la commande update et incluez le fichier JSON à l'aide de l'option --source. Si l'ensemble de données se trouve dans un projet autre que votre projet par défaut, ajoutez l'ID du projet au nom de l'ensemble de données, en respectant le format suivant : project_id:dataset.

    bq update \
    --source path_to_file \
    project_id:dataset
    

    Remplacez l'élément suivant :

    • path_to_file est le chemin d'accès au fichier JSON sur votre ordinateur local.
    • project_id est l'ID de votre projet ;
    • dataset est le nom de votre ensemble de données.

    Exemples :

    Saisissez la commande suivante pour mettre à jour les contrôles d'accès pour mydataset. mydataset se trouve dans votre projet par défaut.

        bq update --source /tmp/mydataset.json mydataset
    

    Saisissez la commande suivante pour mettre à jour les contrôles d'accès pour mydataset. mydataset se trouve dans myotherproject.

        bq update --source /tmp/mydataset.json myotherproject:mydataset
    
  4. Pour vérifier les modifications apportées aux contrôles d'accès, saisissez à nouveau la commande show sans écrire les informations dans un fichier.

    bq show --format=prettyjson dataset
    

    ou

    bq show --format=prettyjson project_id:dataset
    

API

Appelez datasets.patch et utilisez la propriété access de la ressource Dataset pour mettre à jour les contrôles d'accès.

Comme la méthode datasets.update remplace la ressource d'ensemble de données dans son intégralité, il est préférable d'utiliser la méthode datasets.patch.

Go

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Go décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery en langage Go.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// revokeDatasetAccess updates the access control on a dataset to remove all
// access entries that reference a specific entity.
func revokeDatasetAccess(projectID, datasetID, entity string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// entity := "user@mydomain.com"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	ds := client.Dataset(datasetID)
	meta, err := ds.Metadata(ctx)
	if err != nil {
		return err
	}

	var newAccessList []*bigquery.AccessEntry
	for _, entry := range meta.Access {
		if entry.Entity != entity {
			newAccessList = append(newAccessList, entry)
		}
	}

	// Only proceed with update if something in the access list was removed.
	// Additionally, we use the ETag from the initial metadata to ensure no
	// other changes were made to the access list in the interim.
	if len(newAccessList) < len(meta.Access) {

		update := bigquery.DatasetMetadataToUpdate{
			Access: newAccessList,
		}
		if _, err := ds.Update(ctx, update, meta.ETag); err != nil {
			return err
		}
	}
	return nil
}

Python

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Python décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Python.

Définissez la propriété dataset.access_entries avec les contrôles d'accès pour un ensemble de données. Appelez ensuite la fonction client.update_dataset() pour mettre à jour la propriété.

# TODO(developer): Set dataset_id to the ID of the dataset to fetch.
dataset_id = "your-project.your_dataset"

# TODO(developer): Set entity_id to the ID of the email or group from whom you are revoking access.
entity_id = "user-or-group-to-remove@example.com"

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

dataset = client.get_dataset(dataset_id)  # Make an API request.

entries = list(dataset.access_entries)
dataset.access_entries = [
    entry for entry in entries if entry.entity_id != entity_id
]

dataset = client.update_dataset(
    dataset,
    # Update just the `access_entries` property of the dataset.
    ["access_entries"],
)  # Make an API request.

full_dataset_id = f"{dataset.project}.{dataset.dataset_id}"
print(f"Revoked dataset access for '{entity_id}' to ' dataset '{full_dataset_id}.'")

Étapes suivantes