APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

GitHub ActionsでMicrosoft Graph APIを利用したEntra IDユーザー招待を試してみた

本記事はAP Tech Blog Week Vol.5のものになります。

はじめに

こんにちは、ACS事業部 CIチームの平井です。この記事では、GitHub Actionsを使ってOIDCを利用し、Microsoft Graph APIでEntra IDユーザーを招待する方法をご紹介します。 ユーザー招待システムを構築するためのヒントとして、参考にしていただけたらと思います。

背景

Azure ADへのユーザー招待を自動化するにあたり、当初はTerraformのazureadプロバイダーazuread_invitationリソースを使用する予定でした。しかし、実装する過程で以下のような課題に直面しました。

ユーザープロパティが設定できない 通常、招待時にユーザープロパティを設定したいところですが、azuread_invitationリソースだけではこれができません。設定するためには、次の複雑な手順を踏む必要がありました。

  1. azuread_invitationでユーザーを招待
  2. terraform importコマンドで招待したユーザーリソースをインポート
  3. azuread_userリソースでプロパティを更新

このように、シンプルに見えるユーザー招待も、Terraformでは複数のステップが必要となり、運用が煩雑化してしまいます。

そこで行きついたのがMicroSoft Graph APIをGitHub ActionsのOIDCで使用する方法でした。

Microsoft Graph APIとは

Microsoft Graph APIはMicrosoftのクラウドサービスに対するRESTful APIです。Entra IDを含むMicrosoft 365のサービスを統合的に操作することができます。azureadプロバイダーも内部的にはMicrosoft Graph APIを利用して動いています。

learn.microsoft.com

実装の流れ

では早速実装に入ります。今回は簡易的に招待の際、表示名、姓、名のプロパティを設定する実装になります。 流れとしては以下のように進んでいきます。

  1. Entra IDアプリケーションの設定
  2. GitHub Actionsワークフローの作成
  3. ユーザー招待処理の作成(Node.js)

Entra IDアプリケーションの設定

まずはEntra IDにアプリケーションを登録し、フェデレーションの設定をします。以下の記事を参考に進めていきましょう。 zenn.dev

アプリケーションの作成が完了したら、ユーザー招待を行う上で必要なAPIの権限を付与していきます。 必要な権限は以下の二つです。

  • Directory.ReadWrite.All
  • User.ReadWrite.All

このように付与できていればEntra IDアプリケーションの設定は終了です。

GitHub Actionsワークフローの作成

GitHub ActionsでOIDC認証を使用してMicrosoft Graph APIを呼び出すワークフローを作成します。

ファイル名:.github/workflows/invitation_workflow.yml

name: user invitation

on:
  workflow_dispatch:
    inputs:
      user_email:
        description: "Email of the user to invite"
        required: true
      display_name:
        description: "Display name of the user to invite"
        required: true
      first_name:
        description: "First name of the user to invite"
        required: true
      last_name:
        description: "Last name of the user to invite"
        required: true

permissions:
  id-token: write
  contents: read

jobs:
  invite_user:
    runs-on: ubuntu-latest
    environment:
      name: staging
    defaults:
      run:
        working-directory: ./invitation

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"
          cache-dependency-path: "invitation/package-lock.json"

      - name: Install dependencies
        run: npm ci

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

      - name: Invite user
        env:
          TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          USER_EMAIL: ${{ github.event.inputs.user_email }}
          DISPLAY_NAME: ${{ github.event.inputs.display_name }}
          FIRST_NAME: ${{ github.event.inputs.first_name }}
          LAST_NAME: ${{ github.event.inputs.last_name }}
        run: npm start

なお、以下のGitHubシークレットの設定が必要です:

  • AZURE_CLIENT_ID: アプリケーションのクライアントID
  • AZURE_TENANT_ID: テナントID
  • AZURE_SUBSCRIPTION_ID: サブスクリプションID

ユーザー招待処理の作成(Node.js)

最後にユーザー招待処理の実装していきます。

# プロジェクトディレクトリの作成
mkdir user-invitation
cd user-invitation

# package.jsonの作成
npm init -y

# 必要なパッケージのインストール
npm install @azure/identity @microsoft/microsoft-graph-client isomorphic-fetch

package.jsonに以下の内容を追加

"scripts": {
  "start": "node userInvitaiton.js"
},
"type": "module",

ユーザー招待処理コードを追加します。 今回利用するAPIエンドポイントのリファレンスになります。

learn.microsoft.com

learn.microsoft.com

こちらをもとに作成していきます。

ファイル名:/invitation/userInvitaiton.js

import { DefaultAzureCredential } from "@azure/identity";
import { Client } from "@microsoft/microsoft-graph-client";
import { TokenCredentialAuthenticationProvider } from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials/index.js";
import "isomorphic-fetch";

const credential = new DefaultAzureCredential();

// Microsoft Graph APIクライアントを初期化
const authProvider = new TokenCredentialAuthenticationProvider(credential, {
  scopes: ["https://graph.microsoft.com/.default"],
});

const client = Client.initWithMiddleware({ authProvider: authProvider });

// ユーザーの招待内容
const invitation = {
  invitedUserEmailAddress: process.env.USER_EMAIL,
  inviteRedirectUrl: `https://myapplications.microsoft.com/?tenantId=${process.env.TENANT_ID}`,
  sendInvitationMessage: true, // メール通知を送信する
};

// 招待ユーザーのプロパティ
const properties = {
  displayName: process.env.DISPLAY_NAME,
  givenName: process.env.FIRST_NAME,
  surname: process.env.LAST_NAME,
};

// ユーザーの招待とプロパティの設定
async function sendInvitation() {
  try {
    const invitationResponse = await client.api("/invitations").post(invitation);
    const userId = invitationResponse.invitedUser.id;
    console.log(
      `Invitation sent to ${process.env.USER_EMAIL} with id: ${userId}`
    );
    return userId;
  } catch (error) {
    console.error("Errer sending invitation:", error);
    throw error;
  }
}

async function updateProperties() {
  try {
    const userId = await sendInvitation();
    await client.api(`/users/${userId}`).patch(properties);
    console.log(`User ${userId} properties updated`);
  } catch (error) {
    console.error("Error updating user properties:", error);
    throw error;
  }
}

updateProperties().catch((error) => {
  console.error(error);
  process.exit(1);
});

これで準備は終わりました。コードをPushして、さっそくワークフローの動作確認をしていきます。

動作確認

リポジトリのActionsタブより、user invitationをworkflow_dispatchで動かします。

無事ワークフローが実行できました。

Azureポータルより招待ユーザーが実際に作成されたか確認してみます。

無事、招待ユーザーの表示名、姓、名のプロパティが設定されています。

おわりに

今回はGitHub Actionsを使ってOIDCを利用し、Microsoft Graph APIでユーザーを招待する方法をご紹介しました。今回は一つのユーザーのみの招待ですが、ワークフロー内でマトリックスを使用することで 単一のワークフローで複数のユーザーを並行して処理することも可能になります。この記事が皆さんの学びや実践に少しでも役立てば嬉しいです。

私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: <平井亨>