在 Azure 資料科學虛擬機器上安全地儲存存取認證

雲端應用程式程式代碼通常包含向雲端服務驗證的認證。 這些認證的管理和安全性是眾所周知的挑戰,因為我們建置雲端應用程式。 在理想情況下,認證不應該出現在開發人員工作站上。 我們絕對不應該簽入認證至原始檔控制。

Azure 資源的受控識別功能可協助解決問題。 它會在 Microsoft Entra ID 中為 Azure 服務提供自動受控識別。 您可以使用此身分識別向任何支援 Microsoft Entra 驗證的服務進行驗證。 此外,此身分識別可避免在您的程式代碼中放置任何內嵌認證。

若要保護認證,請使用 Windows Installer (MSI) 搭配 Azure 金鑰保存庫。 Azure 金鑰保存庫 是受控 Azure 服務,可安全地儲存秘密和密碼編譯密鑰。 您可以使用受控識別來存取金鑰保存庫,然後從金鑰保存庫擷取授權祕密和密碼編譯金鑰。

Azure 資源 金鑰保存庫 和受控識別的相關文件會形成完整的資源,以深入了解這些服務的相關信息。 本文逐步解說在 資料科學虛擬機器 (DSVM) 上基本使用 MSI 和 金鑰保存庫 來存取 Azure 資源。

在 DSVM 上建立受控身分識別

# Prerequisite: You already created a Data Science VM in the usual way.

# Create an identity principal for the VM.
az vm assign-identity -g <Resource Group Name> -n <Name of the VM>
# Get the principal ID of the DSVM.
az resource list -n <Name of the VM> --query [*].identity.principalId --out tsv

將 Key Vault 存取權限指派給 VM 主體

# Prerequisite: You already created an empty Key Vault resource on Azure through use of the Azure portal or Azure CLI.

# Assign only get and set permissions but not the capability to list the keys.
az keyvault set-policy --object-id <Principal ID of the DSVM from previous step> --name <Key Vault Name> -g <Resource Group of Key Vault>  --secret-permissions get set

從 DSVM 存取金鑰保存庫中的祕密

# Get the access token for the VM.
x=`curl http://localhost:50342/oauth2/token --data "resource=https://vault.azure.net" -H Metadata:true`
token=`echo $x | python -c "import sys, json; print(json.load(sys.stdin)['access_token'])"`

# Access the key vault by using the access token.
curl https://<Vault Name>.vault.azure.net/secrets/SQLPasswd?api-version=2016-10-01 -H "Authorization: Bearer $token"

從 DSVM 存取儲存體金鑰

# Prerequisite: You granted your VMs MSI access to use storage account access keys, based on instructions at https://learn.microsoft.com/azure/active-directory/managed-service-identity/tutorial-linux-vm-access-storage. This article describes the process in more detail.

y=`curl http://localhost:50342/oauth2/token --data "resource=https://management.azure.com/" -H Metadata:true`
ytoken=`echo $y | python -c "import sys, json; print(json.load(sys.stdin)['access_token'])"`
curl https://management.azure.com/subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroup of Storage account>/providers/Microsoft.Storage/storageAccounts/<Storage Account Name>/listKeys?api-version=2016-12-01 --request POST -d "" -H "Authorization: Bearer $ytoken"

# Now you can access the data in the storage account from the retrieved storage account keys.

從 Python 存取金鑰保存庫

from azure.keyvault import KeyVaultClient
from msrestazure.azure_active_directory import MSIAuthentication

"""MSI Authentication example."""

# Get credentials.
credentials = MSIAuthentication(
    resource='https://vault.azure.net'
)

# Create a Key Vault client.
key_vault_client = KeyVaultClient(
    credentials
)

key_vault_uri = "https://<key Vault Name>.vault.azure.net/"

secret = key_vault_client.get_secret(
    key_vault_uri,  # Your key vault URL.
    # The name of your secret that already exists in the key vault.
    "SQLPasswd",
    ""              # The version of the secret; empty string for latest.
)
print("My secret value is {}".format(secret.value))

從 Azure CLI 存取金鑰保存庫

# With managed identities for Azure resources set up on the DSVM, users on the DSVM can use Azure CLI to perform the authorized functions. The following commands enable access to the key vault from Azure CLI, without a required Azure account login.
# Prerequisites: MSI is already set up on the DSVM, as indicated earlier. Specific permissions, like accessing storage account keys, reading specific secrets, and writing new secrets, are provided to the MSI.

# Authenticate to Azure CLI without a required Azure account. 
az login --msi

# Retrieve a secret from the key vault. 
az keyvault secret show --vault-name <Vault Name> --name SQLPasswd

# Create a new secret in the key vault.
az keyvault secret set --name MySecret --vault-name <Vault Name> --value "Helloworld"

# List access keys for the storage account.
az storage account keys list -g <Storage Account Resource Group> -n <Storage Account Name>