在云计算与DevOps实践中,Azure CLI是管理员和开发者最常用的命令行工具之一。然而,许多人在长期使用中都会遇到一个令人困扰的问题:如何在避免每次都进行交互式登录(即“持久登录”)的前提下,安全高效地执行Azure CLI命令?特别是当需要将CLI集成到CI/CD管道、自动化脚本或无人值守的服务器上时,传统的az login方式显然不再适用。本文将为您系统梳理几种无持久登录的解决方案,并分析各自适用场景与安全考量。

一、为什么需要“无持久登录”?

Azure CLI默认的az login会弹出浏览器窗口要求用户交互式登录,并将在本地生成一个包含访问令牌的缓存文件(通常位于~/.azure/accessTokens.json)。这种方式的隐患在于:

  • 令牌会过期(默认约1小时),但刷新令牌可能维持数天甚至更长,一旦泄露可被滥用。
  • 在自动化环境(如Jenkins、GitHub Actions)中,交互式登录完全不可行。
  • 多人共享服务器时,令牌缓存可能意外暴露给其他用户。

因此,我们需要一种不依赖持久化令牌、无需手动交互的身份验证方法。

二、四大主流方案详解

1. 服务主体(Service Principal) + 客户端密钥/证书

这是最常用的无交互登录方式。用户需要在Azure AD中创建一个服务主体(类似于机器人账号),并为其分配所需权限。然后在CLI中使用:

az login --service-principal -u <app-id> -p <password> --tenant <tenant-id>

或者使用证书:

az login --service-principal -u <app-id> --certificate <certificate-path> --tenant <tenant-id>

优点:权限可以精细控制,支持密码或证书两种凭据;令牌在CLI退出后即释放,不会持久化。

缺点:需要事先管理服务主体及其凭据安全;密码形式存在泄露风险,建议优先使用证书或托管身份。

2. 托管身份(Managed Identity)

如果您的环境运行在Azure内部(如Azure VM、Azure Functions、App Service),托管身份是最佳选择。它完全消除了凭据管理问题:

az login --identity

Azure基础架构自动为资源分配一个托管身份,CLI可直接使用该身份获取令牌。

优点:零凭据管理,自动轮换,安全性最高;无需任何客户端密钥或证书。

缺点:仅适用于Azure托管资源;无法在本地或第三方环境使用。

3. 设备代码流(Device Code Flow)

适合无法弹出浏览器的无头环境(如SSH会话)。通过az login --use-device-code生成一个设备验证码,用户需在另一台设备上访问https://microsoft.com/devicelogin并输入该码完成登录。令牌同样会缓存到本地。

优点:无需服务主体,适合临时性手动操作;无需安装浏览器。

缺点:仍需要人工介入,不适合完全自动化;令牌会持久化。

4. 环境变量中的默认凭据(Azure DefaultAzureCredential)

对于现代应用程序(非CLI直接使用),Azure SDK提供了DefaultAzureCredential链式身份验证,但CLI本身并不直接支持该方式。不过,您可以通过设置环境变量AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_CLIENT_SECRET,结合az login --service-principal的简略形式,实现类似的效果。

三、最佳实践与安全建议

  • 永远不要在脚本中硬编码密码。使用Azure Key Vault或环境变量(如Pipeline Secret)注入敏感信息。
  • 优先使用托管身份。只要资源在Azure上,就用它替代服务主体。
  • 考虑使用Azure CLI的“登录范围”。通过az login --scope限制令牌申请的权限范围。
  • 定期轮换服务主体凭据。建议使用证书并设置自动续期。
  • 日志与审计。开启Azure CLI的调试日志(--debug),并监控服务主体的活动。

四、实际场景示例:在GitHub Actions中无登录使用Azure CLI

在GitHub Actions工作流中,最佳方案是通过azure/login Action实现无持久登录:

- name: Azure Login
  uses: azure/login@v1
  with:
    creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Run Azure CLI
  run: az vm list --output table

这里的AZURE_CREDENTIALS是一个JSON对象,包含服务主体的clientIdclientSecretsubscriptionIdtenantId。每次Action运行时,登录都是临时的,运行结束后令牌即失效。

五、结语

“无持久登录”的本质是将用户身份验证从交互式、长生命周期的凭据,转向短时、自动化、可撤销的机制。Azure CLI提供了多种方式满足不同场景,关键是理解每种方法的适用边界与安全代价。作为管理员,应养成“最小权限、最短时效、最少存储”的习惯,让Azure CLI真正成为既强大又安全的自动化利器。