この記事では、mssql-django バックエンドを介して SQL Server Always Encrypted と Django アプリケーションを使用する方法について説明します。 Always Encrypted では、保存時および転送中の機密データを保護する列レベルの暗号化が提供されます。
前提条件
- SQL Server 用 Microsoft ODBC Driver 17 または 18
- SQL Server 2016 以降、またはAzure SQL Database
- SQL Server側で構成された列暗号化 (列マスター キーと列暗号化キー)
どのように機能するのか
Always Encrypted は、Django 自体ではなく、ODBC ドライバー レイヤーによって処理されます。
ColumnEncryption ODBC パラメーターを有効にすると、ドライバーは、アプリケーションとSQL Serverの間を通過するときに、データを自動的に暗号化および復号化します。 Django のモデルとクエリは、列が暗号化されているかどうかに関係なく、同じように動作します。
Windows 証明書ストア
列マスター キーがWindows証明書ストアに格納されている場合は、ColumnEncryption=Enabledにextra_paramsを追加して Always Encrypted を有効にします。
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",
},
},
}
このアプローチは、Windowsでのみ機能します。
クライアント ID とシークレットを使用したAzure Key Vault
列マスター キーがAzure Key Vaultに格納されている場合は、extra_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>"
),
},
},
}
<application-client-id>と<client-secret>をアプリ登録のアプリケーション (クライアント) ID とクライアント シークレットの値に置き換えます。
Important
settings.pyでシークレットをハードコーディングしないでください。 環境変数またはシークレット マネージャーを使用して、実行時に資格情報を指定します。
マネージド ID を使用したAzure Key Vault
Azureで実行する場合 (Azure 仮想マシンやAzure App Serviceなど)、マネージド ID を使用してAzure Key Vaultにアクセスします。
システムによって割り当てられた管理ID
KeyStoreAuthentication パラメーターを超える追加の構成は必要ありません。
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"
),
},
},
}
ユーザー指定のマネージド ID
マネージド ID のクライアント ID (アプリケーション ID とも呼ばれます) を含めます。
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>"
),
},
},
}
マネージド ID のアクセス許可を付与する
マネージド ID に Azure SQL データベースへのアクセス権を付与します。
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>];Always Encrypted Azure Key Vault ドキュメントに記載されているアクセス許可を使用して、列マスター キーを格納するAzure Key Vaultへのアクセス権をマネージド ID に付与します。
Django で暗号化されたテーブルを管理できるようにする
Django で Always Encrypted を使用する場合は、最初にSQL Serverに暗号化オブジェクトを構成してから、移行を実行します。
推奨される順序:
- SQL ServerまたはAzure SQLに列マスター キー (CMK) と列暗号化キー (CEK) を作成します。
- Django 接続設定で
ColumnEncryption=Enabledを構成します。 - Django の移行を実行します。
- SQL Server Management Studioまたは T-SQL を使用してターゲット列を暗号化します。
移行を実行します。
python manage.py migrate
mssql-django は、Always Encrypted のキー メタデータを作成または管理しません。 キーの作成と列暗号化ポリシーは、引き続き SQL Server の管理タスクです。
サポートされていない認証方法
Always Encrypted キー ストアアクセスでは、ユーザー名/パスワードとAzure Key Vault対話型認証はサポートされていません。