しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

GitHub Actions の OpenID Connect と Azure AD を利用して Client Secret の管理を不要にする

激しく今更ですが、GitHub Actions の OpenID Connect 対応を利用して Azure リソースや Azure AD 自身へのアクセスを Client Secret 無しで行ってみます。

ぶっちゃけ全ては watahani さんのブログを読んでもらえれば良いのですが、少し時間が経過したこともあり若干扱いやすくなっているのと、Terraform との連携も確認しておきたいのが今回書いた理由です。

公式ドキュメントがアップデートされているので、この通りに Workflow を書いて Azure AD 側で Federated credentials の設定を追加すれば終わります。とても簡単ですね。

以前はベータ版の Azure CLI をインストールする必要がありましたが、現在はその必要はなくなっています。Workflow には azure/login だけ書けば済むのでスッキリしました。

ちゃんと azure/login のドキュメントもアップデートされているので、参考にしてください。

Azure Portal から選択できる Azure AD の Federated credentials の利用シナリオも、GitHub Actions 以外にも Kubernetes からの利用やカスタム設定が増えていました。Terraform Cloud が OpenID Connect に対応すると楽できるはずですが、現状は GitHub Actions での利用が中心でしょう。

Federated credentials の追加は GitHub Actions の場合はリポジトリの情報を追加するだけです。

これまでの Client Secret のように有効期限という概念が存在しないので安全に利用できます。今回 Entity type は Branch にしていますが、実際には Environment を使うことが多くなる気がします。

Azure AD である以上 Federated credentials を利用しても Client Id や Tenant Id からは逃れられないので、実際の Workflow は以下のようになります。

name: Publish

on:
  push:
    branches: [ master ]

permissions:
  id-token: write
  contents: read

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2

    - name: Azure Login
      uses: azure/login@v1
      with:
        client-id: ${{ secrets.AZURE_CLIENT_ID }}
        tenant-id: ${{ secrets.AZURE_TENANT_ID }}
        subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

Azure リソースにアクセスする場合にはサブスクリプションが必ず存在しているので、同時に Subscription Id も指定する必要があるのは変わりません。

実際に Workflow を実行してみると GitHub Actions が提供する id_token を使っていることが分かります。

定期的に Client Secret をローテートさせる必要が消滅したのは大きなメリットです。

デプロイなどで Azure リソースを操作する場合には Azure CLI でログインしてしまえば、後は公式で用意されたデプロイ用などの Action が利用できるので簡単です。

Federated credentials を使った場合でも Azure への認証情報は一時的に保存されるようなので、Azure CLI を使ってログインしておけば Terraform CLI 経由で問題なく利用出来ます。

Azure Provider: Authenticating via the Azure CLI | Guides | hashicorp/azurerm | Terraform Registry

Terraform Provider 側での OpenID Connect 対応も検討されているようなので、実現すると複数 Azure AD テナントに跨るリソースのデプロイが楽になる予感です。

最近は Azure AD 周りの Terraform 化ブームが来ているので、サブスクリプションを持たない Azure AD B2C に対しても問題なく動作するか確認しておきました。

Azure CLI や azure/login はデフォルトではサブスクリプションを持たないテナントへのログインをエラーにしてしまうので、Azure AD B2C をターゲットにする場合は allow-no-subscriptions を追加します。

これでサブスクリプションを持たないテナントに対しても Azure CLI ベースでアクセスが出来ます。

当然ながら Terraform CLI からも認証情報を利用できるので、Terraform Provider for Azure AD を使っている場合でも動作します。一般的には Terraform の利用には高い権限が必要になるので、出来るだけ Federated credentials を使って安全に運用できるようにしておきたいです。