如何为运行R脚本的Azure Batch服务安全提供机密凭据
问题描述
探索Azure Batch服务作业传递敏感数据的可行方案,需传递的敏感数据为R脚本连接SQL数据库、拉取表数据使用的SQL连接凭据。批处理工作目录存放配置文件时,对应业务实现代码如下:
dbConfig <- config::get(file = "config.yml") db_connect <- function(database_config_name){ dbConfig <- config::get(database_config_name) connection <- DBI::dbConnect(odbc::odbc(), Driver = dbConfig$driver, Server = dbConfig$server, UID = dbConfig$uid, PWD = dbConfig$pwd, Database = dbConfig$database, encoding = "UTF-8" )
原方案计划使用AzureKeyVault包完成认证,访问Azure Key Vault中存储的机密,将配置文件写入Azure Batch运行环境,对应实现代码如下:
devtools::install_github("Azure/AzureKeyVault") vault <- AzureKeyVault::key_vault("https://mykeyvault.vault.azure.net") secret <- vault$secrets$get("secretname") yaml::write_yaml(secret$value,"config.yml") dbConfig <- config::get(file = "config.yml")
机密使用完成后,计划执行如下操作删除临时配置文件:
unlink("config.yml", recursive = FALSE, force = TRUE)
该方案存在认证阻塞:无法实现自动认证,控制台输出如下交互式设备码认证提示:
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code xxxxxxxx to authenticate. Waiting for device code in browser...
交互式设备码认证方式不符合无人值守批处理的业务要求,需实现Azure Batch自动认证完成机密获取,或其他可向Azure Batch安全传递机密的可行方案。
解决方案
方案1:托管标识非交互访问Key Vault(首选)
该方案无需硬编码任何凭据,安全性最高,运维成本最低:
- 为Azure Batch池开启系统分配托管标识,或绑定预创建的用户分配托管标识
- 为该托管标识配置Key Vault访问策略,授予机密读取(Get)权限
- 修改认证逻辑,直接使用托管标识获取访问令牌,无需交互式操作,代码示例如下:
library(AzureAuth) library(AzureKeyVault) # Batch运行环境会自动识别托管标识端点,无需手动传入凭据 token <- get_managed_token("https://vault.azure.net") vault <- key_vault("https://mykeyvault.vault.azure.net", token = token) secret <- vault$secrets$get("secretname") yaml::write_yaml(secret$value,"config.yml") # 用on.exit保证即使脚本运行异常,临时配置文件也会被清理,避免凭据残留 on.exit(unlink("config.yml", recursive = FALSE, force = TRUE), add = TRUE) dbConfig <- config::get(file = "config.yml")
方案2:Batch加密环境变量传参
该方案无需对接Key Vault,实现逻辑最简单:
- 提交Batch任务时,将SQL连接相关的敏感值配置为机密类型的环境变量,Azure Batch会对这类值做静态加密,仅在任务运行时在节点内存中解密,不会明文出现在日志、任务配置中
- R脚本直接从环境变量读取配置即可,无需落地临时配置文件,代码示例如下:
db_connect <- function(){ connection <- DBI::dbConnect(odbc::odbc(), Driver = Sys.getenv("SQL_DRIVER"), Server = Sys.getenv("SQL_SERVER"), UID = Sys.getenv("SQL_UID"), PWD = Sys.getenv("SQL_PWD"), Database = Sys.getenv("SQL_DATABASE"), encoding = "UTF-8" ) return(connection) }
方案3:服务主体认证(备选)
如果无法使用托管标识,可提前创建Azure AD服务主体,为其授予Key Vault机密读取权限,将服务主体的凭据通过Batch加密环境变量传入节点,运行时用服务主体凭据认证访问Key Vault。该方案需要定期轮转服务主体密钥,维护成本和凭据泄露风险高于托管标识方案,仅作备选。
内容的提问来源于stack exchange,提问作者Yasin Amini
相关产品推荐
相关产品推荐

