🐙

Check! GitHub Actions で OpenID Connect(OIDC) で Azure に安全に接続する

2023/02/26に公開

Prologue

こんにちは、@dz_ こと、岩永かづみです。

Microsoft Azure を外部から使うときは、サービス プリンシパル(Service principal)を利用することが多いですが、後述のワークロード ID フェデレーションを利用し OpenID Connect(OIDC)で接続する方が安全&簡単だと気づいたので、使えるときは積極的に使っていきたく、知見を共有します。

サクッと手順を知りたい方は、後述の GitHub Actions から OIDC で Azure に安全に接続する へお進みください。

Microsoft Azure で OpenID Connect(OIDC)を利用する概要

Microsoft Azure では、Azure Active Directory(Azure AD)を使用して OpenID Connect による認証を行うことができます。さらに、Azure AD のワークロード ID フェデレーションを使用することで、GitHub などのサポートされている IdP からのトークンを信頼するよう構成することができ、これによりシークレットを扱うことなく短期のアクセストークンを用いた接続を利用できるようになります。利用できるシナリオは、以下が挙げられており、ここでは GitHub Actions からの接続について取り上げます。

  • GitHub Actions からの Azure リソースのデプロイ
  • Google Cloud からの接続
  • Kubernetes で実行されているワークロード
  • 信頼関係を構成したその他の IdP を使用したワークロード

https://learn.microsoft.com/ja-jp/azure/active-directory/fundamentals/auth-oidc

https://learn.microsoft.com/ja-jp/azure/active-directory/develop/workload-identity-federation

GitHub Actions で OpenID Connect (OIDC) を利用する

GitHub Actions からみた OpenID Connect(OIDC)の情報は、こちらをご参考ください。

https://docs.github.com/ja/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect

ドキュメントでは、Microsoft Azure, Amazon Web Services, Google Cloud Platform, HashiCorp Vault に対する接続について記載されており、またその他のクラウド プロバイダー においても手順が解説されています。

なお、Microsoft Azure への接続についてのドキュメントがわかりにくいので、ご紹介するのがこの記事の主な目的です🎯

GitHub Actions から OIDC で Microsoft Azure のリソースに安全に接続する

ここでは Azure ポータルでの操作をご紹介します。大まかな手順は以下の通りです。

  • Microsoft Azure で Azure AD アプリケーションを作成する
  • 作成した Azure AD アプリケーションにフェデレーション資格情報を追加する
  • Azure で認可させたいリソースにロールを割り当てる
  • GitHub Actions のシークレットに、下記を設定する
    • Azure AD アプリケーションのクライアントID, Azure のテナントID, Azure のサブスクリプションID
  • GitHub Actions ワークフローで Azure/login アクションでログインする

Azure ポータルで、Azure AD アプリケーションを作成する

まず、Azure ポータル( https://portal.azure.com )で「Active Directory」を開きます。

ポータル上部の検索ボックスで検索すると素早く移動できます。

Azure ポータルで「Active Directory」を開く

「Active Directory」画面の左のメニューから「アプリの登録」(App registrations)を開きます。

「アプリの登録」を開く

上部のメニューから「+新規登録」(New registration)を選択します。

「アプリの登録」画面で「新規登録」を選択する

任意の「名前」(Name)を入力し、「サポートされているアカウントの種類」(Supported account types) を選択し、「登録」ボタンから登録します。

「サポートされているアカウントの種類」は、特に理由がなければ「この組織ディレクトリのみに含まれるアカウント ( {ディレクトリ名} のみ - シングル テナント)」を選択してください。

新しい「アプリの登録」を作成する

アプリケーションの新規作成が完了すると、作成されたアプリケーションの画面に遷移します。

ここに表示されている、「アプリケーション(クライアント)ID」と「ディレクトリ(テナント)ID」は、後述の手順で必要なので控えておいてください。

「アプリの登録」

Azure ポータルで、作成した Azure AD アプリケーションにフェデレーション資格情報を追加する

つぎに、フェデレーション資格情報の設定を行います。

作成したアプリケーションの画面で、左のメニューから「証明書とシークレット」(Certificates & secrets)を開き、「フェデレーション資格情報」(Federated credentials)タブから、「+資格情報の追加」(+ Add credential)を選択します。

アプリケーションでフェデレーション資格情報を追加する

「フェデレーション資格情報のシナリオ」(Federated credential scenario)に「Azure リソースをデプロイする GitHub Actions」(GitHub Actions deploying Azure resources)を選択します。

「GitHub アカウントを接続する」(Connect your GitHub account)の項目で、「組織」(Organization)、「リポジトリ」(Repository)を入力します。

「エンティティ型」(Entity type)は、「環境」「ブランチ」「Pull request」「タグ」から選択でき、「サブジェクト識別子」に対応した文字列を入力します。筆者がよく使うのは「環境」(Environment)で、GitHub 側の Environment for deployments に対応させています。エンティティ型についての詳細は、subject 要求の例 をご参照ください。ここでは、エンティティ型に「環境」を指定し、サブジェクト識別子に staging と入力したとして進めます。

「資格情報の詳細」(Credential details)の項目で、「名前」(Name)に任意の名前を入力し、「追加」ボタンを選択して追加を完了します。

アプリケーションのフェデレーション資格情報の設定を追加する

Azure ポータルで、認可させたいリソースにロールを割り当てる

つぎに、作成したアプリケーションに、必要なロールを割り当てます。

ここでは、リソース グループに割り当てる手順を紹介します。他のリソースでも同様です。

Azure ポータルで、割り当てたいリソース グループを開き、「アクセス制御(IAM)」(Access control (IAM))を開きます。

リソース グループのアクセス制御(IAM)を開く

「+追加」(+Add)から「ロールの割り当ての追加」(Add role assignment)を選択します。

ロールの割り当ての追加を選択する

「ロール」(Role)タブで、割り当てるロールを選択します。ここでは、「共同作成者」(Contributor)を選択します。実際には適切なロールを割り当ててください。

割り当てるロールを選択する

「メンバー」(Members)タブで、「メンバーを選択する」(Select members)から作成した Azure AD アプリケーションを選択します。

割り当てるメンバーとして、作成したアプリケーションを選択する

選択したメンバーを決定する

「レビューと割り当て」(Review + assign)ボタンを選択し、内容を確認し再度「レビューと割り当て」(Review + assign)ボタンを選択し、ロール割り当てを完了します。

ロールの割り当てを完了する

Azure のサブスクリプションIDを取得する

サブスクリプションIDは、各リソースの概要画面で確認できるので、ここでついでに取得しておきます。

上記のリソース グループで「概要」(Overview)を開き、「サブスクリプションID」を控えておきます。

リソース グループの概要からサブスクリプションIDを確認する

GitHub Actions のシークレットに、下記を設定する

つぎに、GitHub Actions のシークレットに下記を設定します。

  • Azure AD アプリケーションのクライアントID
  • Azure のテナントID
  • Azure のサブスクリプションID

ここでは、下記のシークレット名で設定したとして進めます。

シークレット名(例) 説明
AZURE_CLIENT_ID 前述で控えた「アプリケーション(クライアント)ID」を入力
AZURE_TENANT_ID 前述で控えた「ディレクトリ(テナント)ID」を入力
AZURE_SUBSCRIPTION_ID 前述で控えた「サブスクリプションID」を入力

GitHub Actions ワークフローで、Azure/login アクションでログインする

さいごに、GitHub Actions ワークフローで Azure にログインする処理を記述します。

Azure へのログインは azure/login アクションを利用できます。下記のように、client-id, tenant-id, subscription-id を指定します。詳細については、下記をご参考ください。

jobs:
  login:
    runs-on: ubuntu-latest

    # この例では、エンティティ型で environment を指定したので、
    # environment の名前がサブジェクト識別子に指定した文字列と一致する必要がある
    environment:
      name: staging

    permissions:
      # OIDC 接続を実行するために必要
      id-token: write

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

      - name: Test access to Azure
        run: |
          az account show --query name

permissionsid-token: write は、OIDC 接続において JWT ID トークンを要求するために必要です。詳しくは下記をご参照ください。

また、この例では staging という名前で environment を作成している前提で記述してます。environment は、リポジトリの Settings から作成してください。

リポジトリの設定で、Environments に staging を作成した例

azure/login アクションでログインができたら、以降の step でその接続をもって Azure CLI や他の azure/* アクションを利用できるようになります🙆🏻‍♀️

Epilogue

一度覚えると、以降は OIDC による接続を選択すること間違いなしです。ぜひお試しください。

なお、実は同じ内容について、所属先の仲間 @BEACH_SIDE さんのブログでも紹介されているので、共にご参考ください🔍

https://blog.beachside.dev/entry/2022/09/30/213000

Discussion