Políticas de pacotes

Introdução

O uso de uma política de pacotes permite definir listas de permissões e listas de bloqueio para pacotes Python de terceiros do Anaconda no nível da conta. Isso permite atender a requisitos mais rígidos de auditoria e segurança e oferece um controle mais refinado sobre quais pacotes estão disponíveis ou bloqueados em seu ambiente.

Para obter mais informações sobre como o Snowpark Python permite trazer pacotes de terceiros do Anaconda, consulte Como usar pacotes de terceiros.

Ao criar uma UDF, UDTF de Python ou procedimento armazenado, a lista de permissões e a lista de bloqueio serão levadas em consideração ao criar o ambiente Python. A lista de permissões e a lista de bloqueio serão aplicadas a todos os pacotes necessários para criar o ambiente Python. Se não for possível criar um ambiente com os pacotes especificados, a consulta falhará.

Quando você executa uma UDF, UDTF de Python ou procedimento armazenado, o Snowflake verificará a lista de permissões e a lista de bloqueio e garantirá que todos os pacotes sejam permitidos pela política de pacotes. Caso contrário, a consulta falhará.

Limitações

  • As políticas de pacotes só serão aplicadas se os termos legais da Anaconda forem aceitos.

  • As políticas de pacotes não serão aplicadas a funções internas e também não serão aplicadas a aplicativos nativos.

Implementação e uso de uma política de pacotes

Para criar um objeto de política de pacotes, você deve ter os seguintes privilégios:

  • USAGE no banco de dados e esquema no qual você planeja criar a política de pacotes.

  • CREATE PACKAGES POLICY no esquema no qual você planeja criar a política de pacotes.

Após a criação do objeto de política de pacotes, você deve ter os seguintes privilégios para aplicá-lo à conta:

  • OWNERSHIP no objeto da política de pacotes.

  • APPLY PACKAGES POLICY na conta.

Siga esses passos para implementar uma política de pacotes.

Etapa 1: Criar uma função personalizada de administrador de política de pacotes

Crie uma função personalizada que permita aos usuários criar e gerenciar políticas de pacotes. Ao longo deste tópico, a função personalizada de exemplo é denominada policy_admin, embora a função possa ter qualquer nome apropriado.

Se a função personalizada já existir, continue para o próximo passo.

Caso contrário, crie a função personalizada policy_admin.

use role useradmin;

create role policy_admin;
Copy

Passo 2: Conceder privilégios à função personalizada policy_admin

Se a função personalizada policy_admin ainda não tiver os seguintes privilégios, conceda-os como mostrado abaixo:

  • USAGE no banco de dados e no esquema que conterá a política de pacotes.

  • CREATE PACKAGES POLICY no esquema que conterá a política de pacotes.

  • APPLY PACKAGES POLICY na conta.

use role securityadmin;

grant usage on database yourdb to role policy_admin;

grant usage, create packages policy on schema yourdb.yourschema to role policy_admin;

grant apply packages policy on account to role policy_admin;
Copy

Etapa 3: Criar uma nova política de pacotes

Usando a função personalizada policy_admin, crie uma nova política de pacotes, com uma linguagem, lista de permissões e lista de bloqueio especificados. ALLOWLIST, BLOCKLIST, ADDITIONAL_CREATION_BLOCKLIST e COMMENT são parâmetros opcionais. Por padrão, o valor da lista de permissões é ('*') e o valor da lista de bloqueio é ().

Se um pacote for especificado na lista de permissões e na lista de bloqueio, a lista de bloqueio terá precedência. Você deve adicionar explicitamente a versão do tempo de execução do Python na lista de permissões e também adicionar explicitamente todos os pacotes e dependências subjacentes de um pacote pai à lista de permissões.

Você pode especificar uma versão específica do pacote ou um intervalo de versões usando especificadores de versão na lista de permissões ou lista de bloqueio: ==, <=, >=, < ou >. Por exemplo, numpy>=1.2.3. Você pode usar curingas, como numpy==1.2.*, o que significa qualquer versão micro de numpy 1.2.

Nota

Atualmente, em uma lista de permissões ou de bloqueio, apenas um operador de intervalo pode ser especificado por pacote. Não há suporte para a especificação de vários operadores de intervalo, por exemplo pkg>1.0, <1.5. Por isso, para configurar uma política para permitir um intervalo de uma versão do pacote, defina um lado do intervalo na lista de permissões e o outro lado do intervalo na lista de bloqueio. Por exemplo, para permitir versões de pacotes superiores a 1.0 e inferiores a 1.5, defina a lista de permissões como pkg>1.0 e a lista de bloqueio como pkg>1.5.

USE ROLE policy_admin;

CREATE PACKAGES POLICY yourdb.yourschema.packages_policy_prod_1
  LANGUAGE PYTHON
  ALLOWLIST = ('numpy', 'pandas==1.2.3', ...)
  BLOCKLIST = ('numpy==1.2.3', 'bad_package', ...)
  ADDITIONAL_CREATION_BLOCKLIST = ('bad_package2', 'bad_package3', ...)
  COMMENT = 'Packages policy for the prod_1 environment'
;
Copy

Onde:

yourdb.yourschema.packages_policy_prod_1

O nome completo e qualificado da política de pacotes.

LANGUAGE PYTHON

A linguagem que essa política de pacotes aplicará.

ALLOWLIST = ('numpy', 'pandas==1.2.3', ...)

A lista de permissões para esta política de pacotes. Esta é uma cadeia de caracteres separada por vírgula com especificações do pacote.

BLOCKLIST = ('numpy==1.2.3', 'bad_package', ...)

A lista de bloqueio para esta política de pacotes. Esta é uma cadeia de caracteres separada por vírgula com especificações do pacote.

ADDITIONAL_CREATION_BLOCKLIST = ('bad_package2', 'bad_package3', ...)

Especifica uma lista de especificações de pacotes bloqueadas no momento da criação. Para remover este parâmetro, especifique uma lista vazia. Se ADDITIONAL_CREATION_BLOCKLIST estiver definido, ele será anexado ao BLOCKLIST básico no momento da criação. Para UDFs temporárias e procedimentos armazenados anônimos, o ADDITIONAL_CREATION_BLOCKLIST é anexado ao BLOCKLIST no momento da criação e da execução.

COMMENT = 'Packages policy for the prod_1 environment'

Um comentário especificando o objetivo da política de pacotes.

No exemplo acima, a lista de bloqueio aplicada para o momento da criação será ADDITIONAL_CREATION_BLOCKLIST mais BLOCKLIST, portanto os pacotes bloqueados serão numpy==1.2.3, bad_package, bad_package2 e bad_package3. A lista de bloqueio aplicada para a execução será: numpy==1.2.3 e bad_package. Para UDFs temporárias e procedimentos armazenados anônimos, a lista de bloqueio contendo numpy==1.2.3, bad_package, bad_package2 e bad_package3 será aplicada no momento da criação e da execução.

Para obter uma lista das dependências de um pacote Python, use a função SHOW_PYTHON_PACKAGES_DEPENDENCIES. O primeiro parâmetro é a versão do tempo de execução do Python que você está usando e o segundo é uma lista dos pacotes para os quais mostrar dependências. Por exemplo, para mostrar as dependências do pacote numpy, use este comando.

USE ROLE ACCOUNTADMIN;

select SNOWFLAKE.SNOWPARK.SHOW_PYTHON_PACKAGES_DEPENDENCIES('3.8', ['numpy']);
Copy

O resultado é uma lista das dependências e suas versões.

['_libgcc_mutex==0.1', '_openmp_mutex==5.1', 'blas==1.0', 'ca-certificates==2023.05.30', 'intel-openmp==2021.4.0',
'ld_impl_linux-64==2.38', 'ld_impl_linux-aarch64==2.38', 'libffi==3.4.4', 'libgcc-ng==11.2.0', 'libgfortran-ng==11.2.0',
'libgfortran5==11.2.0', 'libgomp==11.2.0', 'libopenblas==0.3.21', 'libstdcxx-ng==11.2.0', 'mkl-service==2.4.0',
'mkl==2021.4.0', 'mkl_fft==1.3.1', 'mkl_random==1.2.2', 'ncurses==6.4', 'numpy-base==1.24.3', 'numpy==1.24.3',
'openssl==3.0.10', 'python==3.8.16', 'readline==8.2', 'six==1.16.0', 'sqlite==3.41.2', 'tk==8.6.12', 'xz==5.4.2', 'zlib==1.2.13']

Para mostrar as dependências do Python 3.8 no ambiente Snowpark, chame a função sem especificar nenhum pacote.

select SNOWFLAKE.SNOWPARK.SHOW_PYTHON_PACKAGES_DEPENDENCIES('3.8', []);
Copy

Se quiser saber quais pacotes estão sendo usados por uma função, você pode usar DESCRIBE FUNCTION para imprimi-los. Esta é uma forma alternativa de identificar todas as dependências de um pacote. Para fazer isso, crie uma função e na especificação do pacote forneça os pacotes de nível superior. A seguir, use DESCRIBE FUNCTION para obter uma lista de todos os pacotes e suas dependências. Você pode copiar e colar esta lista na lista de permissões do pacote. Observe que a política de pacotes deve ser temporariamente desativada ou alguns pacotes poderão ser bloqueados. O exemplo a seguir mostra como encontrar as dependências do pacote ‘snowflake-snowpark-python’.

create or replace function my_udf()
returns string
language python
packages=('snowflake-snowpark-python')
runtime_version=3.10
handler='echo'
as $$
def echo():
  return 'hi'
$$;

describe function my_udf();
Copy

Se você quiser mostrar todos os pacotes e versões disponíveis, consulte a exibição INFORMATION_SCHEMA.PACKAGES.

select * from information_schema.packages;
Copy

Se quiser ver o conjunto atual de pacotes que você está usando, você pode usar esta instrução SQL.

-- at the database level

CREATE OR REPLACE VIEW USED_ANACONDA_PACKAGES
ASSELECT FUNCTION_NAME, VALUE PACKAGE_NAME
FROM (SELECT FUNCTION_NAME,PARSE_JSON(PACKAGES)
PACKAGES FROM INFORMATION_SCHEMA.FUNCTIONS
WHERE FUNCTION_LANGUAGE='PYTHON') USED_PACKAGES,LATERAL FLATTEN(USED_PACKAGES.PACKAGES);

-- at the account level

CREATE OR REPLACE VIEW ACCOUNT_USED_ANACONDA_PACKAGES
ASSELECT  FUNCTION_CATALOG, FUNCTION_SCHEMA, FUNCTION_NAME, VALUE PACKAGE_NAME
FROM (SELECT FUNCTION_CATALOG, FUNCTION_SCHEMA, FUNCTION_NAME,PARSE_JSON(PACKAGES)
PACKAGES FROM SNOWFLAKE.ACCOUNT_USAGE.FUNCTIONS
WHERE FUNCTION_LANGUAGE='PYTHON') USED_PACKAGES,LATERAL FLATTEN(USED_PACKAGES.PACKAGES);
Copy

Etapa 4: Definir a política de pacotes em uma conta

Usando a função personalizada policy_admin, defina a política em uma conta com o comando ALTER ACCOUNT.

use role policy_admin;

alter account set packages policy yourdb.yourschema.packages_policy_prod_1;
Copy

Nota

Para substituir uma política de pacotes que já está definida para uma conta, primeiro desmarque a política de pacotes e depois defina a nova política de pacotes para a conta. Como alternativa, você pode usar FORCE para definir a política de pacotes sem precisar cancelar a definição da política de pacotes. Por exemplo:

alter account set packages policy yourdb.yourschema.packages_policy_prod_2 force;
Copy

Se quiser ver qual política está ativa na conta, você pode usar esta instrução SQL.

select * from table(information_schema.policy_references(ref_entity_domain=>'ACCOUNT', ref_entity_name=>'<your_account_name>'))
Copy

O resultado desta consulta exibirá uma coluna com o nome POLICY_STATUS.

Privilégios necessários para executar comandos DDL

A seguinte tabela resume a relação entre as operações DDL da política de pacotes e seus privilégios necessários.

Operação

Privilégio necessário

Criação da política de pacotes

Uma função com o privilégio CREATE PACKAGES POLICY no esquema.

Alteração da política de pacotes

Uma função com o privilégio OWNERSHIP na política de pacotes.

Descarte da política de pacotes

Uma função com o privilégio OWNERSHIP na política de pacotes.

Descrição da política de pacotes

Uma função com privilégio OWNERSHIP ou USAGE na política de pacotes.

Exibição das políticas de pacotes

Uma função com privilégio OWNERSHIP ou USAGE na política de pacotes.

Definição e cancelamento da política de pacotes

Uma função com o privilégio APPLY PACKAGES POLICY na conta e o privilégio OWNERSHIP na política de pacotes.

DDL da política de pacotes

O Snowflake fornece os seguintes comandos DDL para gerenciar os objetos da política de pacotes:

Observabilidade da política de pacotes

Os usuários que não têm acesso à política de pacotes definida na conta podem ver o conteúdo dela.

Os usuários podem controlar quem vê o conteúdo da política de pacotes adicionando o privilégio USAGE às políticas de pacotes. O administrador da conta ou o proprietário da política de pacotes pode conceder esse privilégio a funções que precisam usar políticas de pacotes.

A exibição CURRENT_PACKAGES_POLICY do Information Schema exibe uma linha para cada política de pacotes do Snowpark na conta atual.

select * from information_schema.current_packages_policy;
Copy
+------+----------+-----------+-----------+-------------------------------+---------+
| NAME | LANGUAGE | ALLOWLIST | BLOCKLIST | ADDITIONAL_CREATION_BLOCKLIST | COMMENT |
+------+----------+-----------+-----------+-------------------------------+---------+
| P1   | PYTHON   | ['*']     | []        | [NULL]                        | [NULL]  |
+------+----------+-----------+-----------+-------------------------------+---------+