Création et utilisation d’une intégration d’accès externe

Pour permettre l’accès à des emplacements de réseau externes spécifiques, vous créez une intégration d’accès externe qui spécifie une liste d’emplacements externes et une liste de secrets que vous êtes autorisé à utiliser. En utilisant la clause EXTERNAL_ACCESS_INTEGRATIONS pour faire référence à cette intégration lors de la création de l’UDF ou de la procédure avec CREATE FUNCTION ou CREATE PROCEDURE, vous permettez au code du gestionnaire d’utiliser le secret pour s’authentifier auprès de l’emplacement externe.

Pour une séquence complète d’exemples de code que vous pourriez utiliser pour configurer et utiliser l’accès externe, reportez-vous à Exemples d’accès au réseau externe.

Les étapes suivantes permettent de configurer l’accès à un emplacement de réseau externe à partir d’une UDF ou d’une procédure.

  1. Créez une règle de réseau pour représenter l’emplacement de réseau externe.

  2. Créez un secret pour conserver les identifiants de connexion.

  3. Créez une intégration d’accès externe, en regroupant le secret et la règle de réseau de manière à ce qu’ils puissent être utilisés par le gestionnaire lors de l’accès à l’emplacement externe.

  4. Créez l’UDF ou la procédure avec le paramètre EXTERNAL_ACCESS_INTEGRATIONS ayant pour valeur le nom de l’intégration. Cela permet à la fonction ou à la procédure d’accéder aux emplacements de réseau externes et d’utiliser les identifiants de connexion spécifiés par les règles de réseau et les secrets dans l’intégration.

    Vous pouvez définir séparément le paramètre SECRET comme étant le nom d’un secret inclus dans l’intégration afin d’avoir accès au contenu du secret à partir du code du gestionnaire.

    Dans le code du gestionnaire de fonction ou de procédure, accéder à l’emplacement de réseau externe spécifié dans une règle de réseau incluse dans l’intégration. Une tentative d’accès à un emplacement réseau qui n’est pas spécifié par une règle de réseau autorisée sera refusée.

Création d’une règle de réseau pour représenter l’emplacement réseau externe

Vous pouvez utiliser la commande CREATE NETWORK RULE pour créer une règle de réseau qui représente l’emplacement réseau externe et les restrictions d’accès. Par exemple, une règle de réseau spécifie des identificateurs de réseau tels qu’un nom d’hôte et la direction de la communication avec le réseau (entrée ou sortie).

Pour créer une règle de réseau dans un schéma, vous devez utiliser un rôle doté du privilège CREATE NETWORK RULE sur ce schéma.

Pour prendre en charge l’accès à un réseau externe, un administrateur inclura la règle lors de la création d’une intégration d’accès externe. Chaque règle incluse dans l’intégration spécifie un emplacement réseau externe auquel la fonction ou la procédure est autorisée à accéder.

Lors de la création d’une règle de réseau à utiliser dans le cadre d’une intégration d’accès externe, vous devez spécifier les éléments suivants :

  • EGRESS comme valeur du paramètre MODE.

  • HOST_PORT comme valeur du paramètre TYPE.

  • Le point de terminaison de l’emplacement externe dans le paramètre VALUE_LIST.

  • (Facultatif) Un numéro de port avec le nom du point de terminaison de l’emplacement externe. Si vous omettez un numéro de port, Snowflake utilisera le numéro de port par défaut pour l’accès externe, 443.

    Par exemple, si le point de terminaison requiert le port 80, le paramètre VALUE_LIST peut être le suivant :

    VALUE_LIST = ('example.com:80')
    
    Copy

Le code de l’exemple suivant crée une règle de réseau appelée google_apis_network_rule pour les requêtes sortantes vers l’API de traduction Google.

CREATE OR REPLACE NETWORK RULE google_apis_network_rule
  MODE = EGRESS
  TYPE = HOST_PORT
  VALUE_LIST = ('translation.googleapis.com');
Copy

Création d’un secret pour représenter les identifiants de connexion

Vous pouvez utiliser CREATE SECRET pour créer un secret qui représente les identifiants de connexion requis pour s’authentifier auprès de l’emplacement réseau externe. Par exemple, le secret peut contenir des identifiants de connexion tels qu’un nom d’utilisateur et un mot de passe.

Pour créer un secret, vous devez utiliser un rôle doté du privilège CREATE SECRET.

Pour l’accès à un réseau externe qui prend en charge OAuth, la meilleure pratique consiste à faire en sorte que votre secret contienne une référence à une intégration de sécurité qui contient les valeurs nécessaires au flux OAuth, telles qu’un ID client, un secret client, un point de terminaison de jeton, etc.

Le secret sera utilisé de la manière suivante :

  • Par un administrateur lors de la création de l’intégration de l’accès externe.

    Lors de la création de l’intégration, l’administrateur spécifie les secrets que les développeurs peuvent utiliser dans le code du gestionnaire lorsqu’ils créent une fonction ou une procédure qui utilise l’intégration.

  • Par un développeur lors de la création d’une UDF ou d’un gestionnaire de procédure.

    Le développeur spécifiera le secret autorisé qui contient les identifiants de connexion que le code du gestionnaire peut utiliser pour s’authentifier lors d’une requête envoyée à l’emplacement externe. Lors de l’écriture d’un gestionnaire, un développeur peut utiliser une API Snowflake pour récupérer les identifiants de connexion contenus dans le secret plutôt que d’inclure les identifiants de connexion en tant que valeurs littérales dans le code du gestionnaire.

Pour des raisons de sécurité, Snowflake exige que si vous créez une UDF ou une procédure qui utilise un secret, vous devez utiliser un rôle qui a le privilège READ sur ce secret.

Note

Pour un secret OAuth qui nécessite un jeton d’actualisation, vous pouvez obtenir le jeton de plusieurs façons, notamment par le biais des fonctions système disponibles dans Snowflake. Pour un exemple, voir Accès à l’API Google Translate.

Le code de l’exemple suivant crée un secret appelé oauth_token qui spécifie une intégration de sécurité (représentée par google_translate_oauth) contenant les valeurs nécessaires pour s’authentifier à l’aide de OAuth.

Pour un exemple plus complet, y compris le code de création de l’intégration de la sécurité, reportez-vous à Exemples d’accès au réseau externe.

CREATE OR REPLACE SECRET oauth_token
  TYPE = OAUTH2
  API_AUTHENTICATION = google_translate_oauth
  OAUTH_REFRESH_TOKEN = 'my-refresh-token';
Copy

Astuce

Dans cet aperçu, vous pouvez spécifier le TYPE comme GENERIC_STRING lorsque vous souhaitez utiliser une clé d’API uniquement en tant qu’identifiant.

CREATE OR REPLACE SECRET bp_maps_api
  TYPE = GENERIC_STRING
  SECRET_STRING = 'replace-with-your-api-key';
Copy

Création d’une intégration d’accès externe

Vous pouvez utiliser la commande CREATE EXTERNAL ACCESS INTEGRATION pour créer une intégration d’accès externe qui regroupe les règles de réseau autorisées (représentant les emplacements de réseau externes) et les secrets autorisés (représentant les identifiants de connexion pour l’authentification) à utiliser avec des UDFs et des procédures.

En particulier, l’intégration de l’accès externe spécifie les règles de réseau et les secrets que les UDFs et les procédures faisant référence à l’intégration peuvent utiliser.

Pour des raisons de sécurité, Snowflake requiert les éléments suivants :

  • Pour créer ou modifier une intégration d’accès externe, vous devez utiliser un rôle disposant du privilège CREATE INTEGRATION.

  • Pour utiliser l’intégration dans une UDF ou une procédure, vous devez avoir obtenu le privilège USAGE sur l’intégration. Vous devez également avoir obtenu le privilège READ sur le secret.

    Le fait d’exiger ces privilèges permet à un administrateur de gérer l’ensemble des utilisateurs qui peuvent autoriser l’accès externe. Pour plus d’informations, reportez-vous à GRANT <privilèges> et à Privilèges de contrôle d’accès.

L’intégration de l’accès externe sera utilisée par un administrateur pour gérer l’accès aux emplacements réseau externes à partir d’UDFs et de procédures. L’intégration ne spécifie que les emplacements et les identifiants de connexion dont l’utilisation est autorisée par des UDFs et des procédures qui font référence à l’intégration. Un administrateur peut également activer ou désactiver l’intégration pour gérer l’accès à des emplacements externes.

Le code de l’exemple suivant crée une intégration d’accès externe appelée google_apis_access_integration. L’intégration spécifie la règle de réseau google_apis_network_rule (représentant l’emplacement du réseau) et le secret oauth_token (représentant les identifiants de connexion).

Pour plus d’informations sur cette règle et ce secret, voir Création d’une règle de réseau pour représenter l’emplacement réseau externe et Création d’un secret pour représenter les identifiants de connexion.

CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION google_apis_access_integration
  ALLOWED_NETWORK_RULES = (google_apis_network_rule)
  ALLOWED_AUTHENTICATION_SECRETS = (oauth_token)
  ENABLED = true;
Copy

Utilisation de l’intégration de l’accès externe dans une fonction ou une procédure

Lorsque vous utilisez la commande CREATE FUNCTION ou CREATE PROCEDURE pour créer une UDF ou une procédure, vous pouvez activer l’accès à des emplacements de réseau externes de la manière suivante :

  • Inclure le paramètre EXTERNAL_ACCESS_INTEGRATIONS, en fixant sa valeur à une ou plusieurs intégrations.

    Chaque intégration spécifiée autorise l’accès aux emplacements de réseau externes et aux secrets spécifiés par l’intégration.

  • Incluez le paramètre SECRETS, en lui attribuant une valeur correspondant à un ou plusieurs secrets et aux noms que vous utiliserez pour y accéder à partir du code du gestionnaire.

    Les secrets que vous spécifiez comme valeurs doivent également être spécifiés dans l’intégration de l’accès externe.

  • Dans le code du gestionnaire, accédez au secret pour récupérer les identifiants de connexion permettant de s’authentifier auprès de l’emplacement réseau externe.

Pour des raisons de sécurité, Snowflake exige que, pour utiliser une intégration dans une UDF ou une procédure, vous ayez obtenu le privilège USAGE sur l’intégration ainsi que le privilège READ sur le secret.

Note

Utilisez toujours un secret Snowflake pour représenter les identifiants de connexion plutôt que de les inclure sous forme de valeurs littérales dans le code. Outre la protection des identifiants de connexion, l’utilisation d’un secret permet d’auditer et de gérer l’utilisation des identifiants de connexion, car seules les personnes bénéficiant du privilège READ sur le secret peuvent utiliser une intégration le contenant dans une UDF ou une procédure.

Snowflake limite le nombre total de connexions qui peuvent être établies à partir d’une UDF spécifique. Pour éviter les problèmes d’épuisement des ressources, réutilisez les connexions autant que possible. Vous pouvez y parvenir en créant le client ou la session TCP une fois pendant l’initialisation de l’UDF, puis en l’utilisant dans le gestionnaire d’UDF pour le reste de la requête.

Le code de l’exemple suivant crée une UDF appelée google_translate_python, spécifiant une intégration d’accès externe appelée google_apis_access_integration (voir Création d’une intégration d’accès externe pour plus de détails). L’intégration spécifie une règle de réseau (représentant un emplacement réseau externe) et un secret (représentant des identifiants de connexion) qu’une UDF faisant référence à l’intégration est autorisée à utiliser. Pour plus d’informations sur cette règle et ce secret, voir Création d’une règle de réseau pour représenter l’emplacement réseau externe et Création d’un secret pour représenter les identifiants de connexion.

Le code du gestionnaire Python utilise la fonction _snowflake.get_oauth_access_token pour récupérer le jeton OAuth du secret, puis utilise le jeton pour s’authentifier auprès de l’emplacement externe. Le code du gestionnaire peut adresser une requête à l’URL spécifiée, parce que l’hôte de l’URL figure dans la règle de réseau spécifiée par l’intégration.

CREATE OR REPLACE FUNCTION google_translate_python(sentence STRING, language STRING)
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.8
HANDLER = 'get_translation'
EXTERNAL_ACCESS_INTEGRATIONS = (google_apis_access_integration)
PACKAGES = ('snowflake-snowpark-python','requests')
SECRETS = ('cred' = oauth_token )
AS
$$
import _snowflake
import requests
import json
session = requests.Session()
def get_translation(sentence, language):
  token = _snowflake.get_oauth_access_token('cred')
  url = "https://translation.googleapis.com/language/translate/v2"
  data = {'q': sentence,'target': language}
  response = session.post(url, json = data, headers = {"Authorization": "Bearer " + token})
  return response.json()['data']['translations'][0]['translatedText']
$$;
Copy