Fonctions autorisées

Les fonctions autorisées vous permettent de partager les résultats d'une requête avec certains utilisateurs ou groupes sans leur donner accès aux tables sous-jacentes. Par exemple, une fonction autorisée peut calculer une agrégation sur des données ou rechercher une valeur de table et utiliser cette valeur dans un calcul.

Par défaut, si une fonction définie par l'utilisateur (UDF) ou une fonction de table interroge une table, un utilisateur qui appelle cette fonction doit disposer des autorisations nécessaires pour lire les données de la table. Vous pouvez également autoriser la fonction à accéder à l'ensemble de données contenant la table référencée. Une fonction autorisée peut interroger les tables de l'ensemble de données, même si l'utilisateur qui appelle la fonction ne peut pas interroger ces tables directement.

Autoriser une fonction

Vous pouvez autoriser à la fois les fonctions définies par l'utilisateur et les fonctions de table. Pour autoriser une fonction, vous pouvez utiliser Google Cloud Console, l'API REST ou l'outil de ligne de commande bq :

Console

  1. Accédez à la page BigQuery de Google Cloud Console.

    Accéder à BigQuery

  2. Dans la section Ressources du panneau de navigation, développez votre projet et sélectionnez un ensemble de données.

  3. Dans le panneau des détails, cliquez sur Autoriser les routines.

  4. Sur la page Routines autorisées, dans la section Autoriser la routine, sélectionnez l'ID du projet, l'ID de l'ensemble de données et l'ID de routine pour la fonction que vous souhaitez autoriser.

  5. Cliquez sur Ajouter une autorisation.

API

  1. Appelez la méthode datasets.get pour récupérer l'ensemble de données auquel la fonction doit accéder. Le corps de la réponse contient une représentation de la ressource Dataset.

  2. Ajoutez l'objet JSON suivant au tableau access de la ressource Dataset :

    {
     "routine": {
       "datasetId": "DATASET_NAME",
       "projectId": "PROJECT_ID",
       "routineId": "ROUTINE_NAME"
     }
    }

    Où :

    • DATASET_NAME correspond au nom de l'ensemble de données contenant la fonction définie par l'utilisateur.
    • PROJECT_ID est l'ID du projet contenant la fonction définie par l'utilisateur.
    • ROUTINE_NAME est le nom de la fonction.
  3. Appelez la méthode dataset.update avec la représentation Dataset modifiée.

bq

  1. Utilisez la commande bq show pour obtenir la représentation JSON de l'ensemble de données auquel la fonction doit accéder. Le résultat de la commande est une représentation JSON de la ressource Dataset. Enregistrez le résultat dans un fichier local.

    bq show --format=prettyjson TARGET_DATASET > dataset.json

    Remplacez TARGET_DATASET par le nom de l'ensemble de données auquel la fonction aura accès.

  2. Modifiez le fichier pour ajouter l'objet JSON suivant au tableau access de la ressource Dataset :

    {
     "routine": {
       "datasetId": "DATASET_NAME",
       "projectId": "PROJECT_ID",
       "routineId": "ROUTINE_NAME"
     }
    }

    Où :

    • DATASET_NAME correspond au nom de l'ensemble de données contenant la fonction.
    • PROJECT_ID est l'ID du projet contenant la fonction.
    • ROUTINE_NAME est le nom de la fonction.
  3. Exécutez la commande bq update pour mettre à jour l'ensemble de données.

    bq update --source dataset.json TARGET_DATASET

Exemple de fonction autorisée

Voici un exemple de bout en bout de la création et de l'utilisation d'une fonction définie par l'utilisateur autorisée.

  1. Créez deux ensembles de données nommés private_dataset et public_dataset. Pour en savoir plus sur la création d'un ensemble de données, consultez la page Créer un ensemble de données.

  2. Exécutez l'instruction suivante pour créer une table nommée private_table dans private_dataset :

    CREATE OR REPLACE TABLE private_dataset.private_table
    AS SELECT key FROM UNNEST(['key1', 'key1','key2','key3']) key;
    
  3. Exécutez l'instruction suivante pour créer une fonction définie par l'utilisateur nommée count_key dans public_dataset. La fonction définie par l'utilisateur inclut une instruction SELECT sur private_table.

    CREATE OR REPLACE FUNCTION public_dataset.count_key(input_key STRING)
    RETURNS INT64
    AS
    ((SELECT COUNT(1) FROM private_dataset.private_table t WHERE t.key = input_key));
    
  4. Attribuez le rôle bigquery.dataViewer à un utilisateur sur l'ensemble de données public_dataset. Ce rôle inclut l'autorisation bigquery.routines.get, qui permet à l'utilisateur d'appeler la fonction. Pour en savoir plus sur l'attribution de contrôles d'accès à un ensemble de données, consultez la page Contrôler l'accès aux ensembles de données.

  5. À ce stade, l'utilisateur est autorisé à appeler la fonction count_key, mais ne peut pas accéder à la table dans private_dataset. Si l'utilisateur tente d'appeler la fonction, il reçoit un message d'erreur semblable à celui-ci :

    Access Denied: Table myproject:private_dataset.private_table: User does
    not have permission to query table myproject:private_dataset.private_table.
    
  6. À l'aide de l'outil de ligne de commande bq, exécutez la commande show comme suit :

    bq show --format=prettyjson private_dataset > dataset.json

    Le résultat est enregistré dans un fichier local nommé dataset.json.

  7. Modifiez dataset.json pour ajouter l'objet JSON suivant au tableau access :

    {
     "routine": {
       "datasetId": "public_dataset",
       "projectId": "PROJECT_ID",
       "routineId": "count_key"
     }
    }

    Remplacez PROJECT_ID par l'ID du projet public_dataset.

  8. À l'aide de l'outil de ligne de commande bq, exécutez la commande update comme suit :

    bq update --source dataset.json private_dataset
  9. Pour vérifier que la fonction définie par l'utilisateur a accès à private_dataset, l'utilisateur peut exécuter la requête suivante :

    SELECT public_dataset.count_key('key1');