Always Encrypted com mssql-django

Este artigo explica como usar SQL Server Always Encrypted com aplicativos Django por meio do mssql-django back-end. O Always Encrypted fornece criptografia em nível de coluna que protege dados confidenciais em repouso e em trânsito.

Pré-requisitos

  • Microsoft Driver ODBC 17 ou 18 para SQL Server
  • SQL Server 2016 ou posterior, ou Banco de Dados SQL do Azure
  • Criptografia de coluna configurada no lado SQL Server (chave mestra de coluna e chave de criptografia de coluna)

Como funciona

O Always Encrypted é tratado pela camada de driver ODBC, não pelo próprio Django. Quando você habilita o ColumnEncryption parâmetro ODBC, o driver criptografa e descriptografa dados automaticamente à medida que passa entre seu aplicativo e SQL Server. Modelos e consultas do Django funcionam da mesma maneira se as colunas são criptografadas ou não.

Repositório de certificados do Windows

Quando as chaves mestras de coluna são armazenadas no repositório de certificados Windows, habilite o Always Encrypted adicionando ColumnEncryption=Enabled aextra_params:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "ColumnEncryption=Enabled",
        },
    },
}

Essa abordagem funciona apenas em Windows.

Azure Key Vault com o ID do cliente e o segredo

Quando as chaves mestras de coluna são armazenadas em Azure Key Vault, forneça as credenciais do aplicativo emextra_params:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": (
                "ColumnEncryption=Enabled;"
                "KeyStoreAuthentication=KeyVaultClientSecret;"
                "KeyStorePrincipalId=<application-client-id>;"
                "KeyStoreSecret=<client-secret>"
            ),
        },
    },
}

Substitua <application-client-id> e <client-secret> pelo ID do aplicativo (cliente) do registro do aplicativo e pelo valor do segredo do cliente.

Importante

Não codifique segredos diretamente em settings.py. Use variáveis de ambiente ou um gerenciador de segredos para fornecer credenciais em runtime.

Azure Key Vault com identidade gerenciada

Ao executar em Azure (por exemplo, Máquinas Virtuais do Azure ou Serviço de Aplicativo do Azure), use a identidade gerenciada para acessar Azure Key Vault.

Identidade gerenciada atribuída pelo sistema

Nenhuma configuração extra é necessária além do KeyStoreAuthentication parâmetro:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": (
                "ColumnEncryption=Enabled;"
                "KeyStoreAuthentication=KeyVaultManagedIdentity"
            ),
        },
    },
}

Identidade gerenciada atribuída pelo usuário

Inclua a ID do cliente da identidade gerenciada (também chamada de ID do aplicativo):

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": (
                "ColumnEncryption=Enabled;"
                "KeyStoreAuthentication=KeyVaultManagedIdentity;"
                "KeyStorePrincipalId=<managed-identity-client-id>"
            ),
        },
    },
}

Conceder permissões de identidade gerenciada

  1. Conceda acesso à identidade gerenciada ao banco de dados SQL do Azure:

    CREATE USER [<identity-name>] FOR EXTERNAL PROVIDER;
    
    ALTER ROLE db_datareader ADD MEMBER [<identity-name>];
    ALTER ROLE db_datawriter ADD MEMBER [<identity-name>];
    
    GRANT VIEW ANY COLUMN MASTER KEY DEFINITION TO [<identity-name>];
    GRANT VIEW ANY COLUMN ENCRYPTION KEY DEFINITION TO [<identity-name>];
    
  2. Conceda à identidade gerenciada acesso ao Azure Key Vault que armazena a chave mestra de coluna, com as permissões listadas na documentação do Always Encrypted Azure Key Vault.

Permitir que o Django gerencie tabelas criptografadas

Ao usar o Always Encrypted com o Django, configure os objetos de criptografia no SQL Server primeiro e execute as migrações.

Ordem recomendada:

  1. Crie a CMK (chave mestra) de coluna e a CEK (chave de criptografia de coluna) em SQL Server ou SQL do Azure.
  2. Defina ColumnEncryption=Enabled nas configurações de conexão do Django.
  3. Execute migrações do Django.
  4. Criptografar colunas de destino com SQL Server Management Studio ou T-SQL.

Executar migrações:

python manage.py migrate

mssql-django não cria nem gerencia metadados de chave Always Encrypted. A criação de chaves e a política de criptografia de coluna continuam sendo tarefas administrativas do SQL Server.

Métodos de autenticação sem suporte

Não há suporte para a autenticação com nome de usuário/senha nem para a autenticação interativa do Azure Key Vault para acesso ao repositório de chaves do Always Encrypted.