はじめに
こんにちは、ネクストモード株式会社テクニカルサポート担当です。
OktaでさまざまなSaaSを管理していると特定の部署に対してアクセス制御をしたり、プロビジョニング機能のひとつであるGroup Push機能で部署グループをSaaSに対して反映し、SaaS側の設定に活用したくなります。
この目的のために部署毎のOktaグループを作成し、所属メンバー管理を手動で行うことは大きな負担となりがちです。この記事ではOkta Workflowsを活用し、SmartHRから部署情報を活用することで部署グループを作成・メンテナンスを自動化する方法をご紹介します。
部署グループのメンテナンスの難しさ
Oktaにはグループのメンテナンスを効率的に行うために手動以外にも、Group Ruleが存在します。Group RuleではOktaユーザーの属性などを活用しグループに所属するメンバーを自動化することができます。
例えば、Oktaユーザー属性のDepartmentが「営業部」であれば、Oktaグループの「営業部」に所属させるというものです。
Group Ruleは非常に便利な機能ですが、以下のような課題があります。
- Oktaグループの作成は別途必要
- ひとつのグループに対してGroup Ruleを作成する必要がある
- 兼務への対応にはOktaユーザーの属性の整備をし、Group Ruleに組み込む必要がある
- Oktaユーザーの属性更新の煩雑さ
- 部署名の変更時のGroup Ruleを更新する必要がある
- 部署統廃合時のOktaグループの削除猶予など柔軟な対応が難しい
まとめると、Group Ruleはユーザー属性をもとにグループ所属を自動化できる一方で、グループ作成自体は別途必要になります。また、部署単位で運用する場合は、グループごとにルール作成・保守が発生するため、兼務への対応や属性整備、日々の属性更新といった運用負荷が増えがちです。さらに、部署名の変更や統廃合が起きるたびにルール更新やグループ整理が必要となり、柔軟な運用が難しくなります。
Okta Workflowsを活用することでできること
今回ご紹介するOkta WorkflowsではSmartHRの情報をマスターにOktaグループの作成からグループに所属するメンバーの追加・削除をすることができます。
以下は処理結果をSlackに通知した例です。Oktaグループの作成からメンバーの所属を行った場合の通知です。

こちらは作成済みのOktaグループに新しいメンバーの追加やメンバーの削除を行った場合の通知です。

以下はOktaグループの削除を行った場合の通知です。

前提
今回ご紹介する仕組みは以下の前提のもとで成り立ちます。
- SmartHR上のユーザー情報にOktaユーザーを特定できるメールアドレスなどの情報があること
- 今回の例では法人メールアドレスというカスタム項目にOktaユーザーのメールアドレスが格納されています
- SmartHR上の部署情報にコードが設定されていること
- SmartHR上の部署名に重複がないこと
- 部署名をOktaグループ名とする想定のため、重複があるとエラーとなります
- Okta上に作成予定の部署名のOktaグループが存在しないこと
- Okta Workflowsで作成するOktaグループに特定のプレフィックスを付けることで回避可能です
また、本記事の仕組みでは 「部署名」ではなく「部署ID」と「部署コード」を判断軸にして突合・追従する ことを前提としています。部署名は改称され得るため、名前をキーにすると運用中に破綻しやすく、ID基準に寄せることで変更に強い設計になります。
Okta Workflowsについて
概要
今回の仕組みでは以下の構成となります。
テーブル
- SmartHR User Departments:SmartHR上のユーザーのメールアドレスと所属部署1から5のコードを記録
flow
- 01. SmartHR to Okta Group:Main flowとして以下の02.から04.までを直接呼び出す
- 02. List Departments:SmartHR上の部署情報を取得し、テーブル『SmartHR Department List』に記録する
- 03. List Employees:SmartHR上のユーザー情報を取得し、テーブル『SmartHR User Departments』に記録する
- 04. Okta Group Management:Oktaグループの作成・更新・削除の判定とSmartHR上の部署所属メンバーとOktaグループメンバーの差分を抽出し、05.を呼び出す
- 05. Okta Group Membership Update Helper trigger by SmartHR:Oktaグループに対して、ユーザーの追加もしくは除外を行う
flow解説(要点)
それぞれのflowについて、目的/入力/出力/ポイント(重要な分岐)の粒度で要点を抜粋して解説します(カードを1枚ずつ追う詳細説明は割愛します)。
01. SmartHR to Okta Group
- 目的:全体オーケストレーション(SmartHRからの最新データ取得 → Oktaグループ差分判定 → メンバー更新)を1つの入口にまとめる
- 入力:Scheduled実行
- 出力:SmartHR User Departments テーブルの初期化、02〜04を順に呼び出し、最終的に05(メンバー更新)までの処理を完走させる
- ポイント:実行頻度は運用に合わせて調整(初回は通知量が増えるため、まずは通知オフや検証環境で確認)
02. List Departments
- 目的:SmartHRの部署一覧を取得し、部署マスタ(SmartHR Department List)を最新化する
- 入力:SmartHRの部署一覧(部署コード/フルパス名など)
- 出力:SmartHR Department List テーブルをUpsert(部署IDをキーとする/タイムスタンプとしてYYYY-MM-DD-HHも保存)
- ポイント:部署名は変更され得るため、比較・追従の軸は「部署ID」に寄せる(名前をキーにすると改称時に破綻しやすい)
03. List Employees

- 目的:SmartHRの従業員情報を呼び出しもとflowから受け取り、「誰がどの部署に所属しているか」をテーブル化して差分比較に使える形にする
- 入力:SmartHRユーザー情報(Oktaユーザーを特定できるメールアドレス等)+所属部署(最大5階層など)
- 出力:SmartHR User Departments テーブルに追記
- ポイント:SmartHR側のメールアドレス項目(Oktaログインと一致する値)を必ず参照する
04. Okta Group Management

(クリックで拡大できます。重要な部分は後ほどクローズアップして解説します。)
- 目的:SmartHR側(部署・所属)とOkta側(グループ・メンバー)を突き合わせ、作成/更新/削除/メンバー差分を判定する中核ロジック
- 入力:Department List テーブル、User Departments テーブル、Oktaのグループ一覧/グループメンバー
- 出力:
- (必要に応じて)Oktaグループの作成/削除
- 各グループの「追加すべきメンバー」「削除すべきメンバー」の差分リストを生成し、05を呼び出す
- ポイント(重要な分岐):
- SmartHRに存在する部署 → Oktaグループが無い場合は作成対象
- SmartHRに存在しない部署 → Oktaグループを削除するか(猶予を設けるか)を運用方針として決める
- 部署メンバー差分がある場合のみ05に渡す(無駄なAPI呼び出しを減らす)
“削除” の運用(猶予・保護・誤検知対策)
グループ削除は影響が大きいため、SmartHRから部署が消えたことを検知した瞬間に削除せず、以下のような「猶予」と「保護」の考え方を入れています。
- 猶予(pending_delete → n日後にdelete):一時的なデータ不整合やSmartHR側のメンテナンス等で誤検知した場合に即時削除を避ける
- 保護(削除対象の限定):本フローが管理するグループ(テーブルに管理IDが記録されているもの)のみを削除対象にする
- 誤検知の早期発見:pending_delete になった段階でSlack通知し、運用側が「削除してよいか/復帰したか」を確認できるようにする
処理の流れ(概要):
- 必要な情報として以下の情報を揃える:
- Department List テーブルの情報(呼び出しもとflowから受信)
- 条件1:現在時刻のYYYY-MM-DD-HH形式を取得しテーブルに記録されたYYYY-MM-DD-HHと一致するか(True/False)
- n日前の時刻のYYYY-MM-DD-HH形式
- 条件2:SmartHR User Departmentsテーブル内の部署コードが一致するレコードの数
- 条件3:Department List テーブルにOktaグループIDがある場合は検索し存在するか(True/False)
- Oktaグループに対するアクション判定:
- 現在時刻YYYY-MM-DD-HH形式が一致する場合
- 条件2が0以下の場合は
nothing_to_doと判定 - 0より大きい場合
- 条件3がFalseの場合は
createと判定 - Trueの場合
- テーブルのupdateフラグがTrueの場合は
updateと判定 - Falseの場合は
skipと判定
- テーブルのupdateフラグがTrueの場合は
- 条件3がFalseの場合は
- 条件2が0以下の場合は
- 現在時刻YYYY-MM-DD-HH形式と一致しない場合
- 条件4:テーブル内にOktaグループステータスがpending_deleteと一致するか(True/False)
- 条件5:テーブルに記録されたYYYY-MM-DD-HHがn日前の時刻のYYYY-MM-DD-HH以下か(True/False)
- 条件3・4・5のすべてがTrueの場合は
deleteと判定 - Falseの場合は
update_statusと判定
create / update / skip / delete / update_status / nothing_to_doの判定条件部分です。
(クリックで拡大できます。) - 現在時刻YYYY-MM-DD-HH形式が一致する場合
- Oktaグループに対するアクション実行:それぞれのアクションを実行し、OktaグループIDとステータス(テーブル反映用)をアウトプット

- 差分(追加/削除)を算出:アクション判定がcreate / update / skipの場合に該当Oktaグループの現在メンバーを取得し、SmartHR側の期待メンバーと突き合わせます。以下のようにテーブルから算出したあるべきメンバーに対して現在のOktaグループのメンバーを算出することで追加すべきメンバーが求められます。 また比較するリストを入れ替えることでグループから除外すべきメンバーが求められます。

(クリックで拡大できます。) - 差分があるものだけ後続へ:リストと必要なパラメータ(アクションフラグ、グループID、グループ名、通知のためのSlackチャンネルID、スレッドタイムスタンプ)を組み立てて 05. Okta Group Membership Update Helper を呼び出します。 以下のように追加と除外それぞれの呼び出しを行います。

(クリックで拡大できます。)
05. Okta Group Membership Update Helper trigger by SmartHR

- 目的:04で作成した差分リストに基づき、Oktaグループへのユーザー追加/除外を実行する
- 入力:対象グループID、追加ユーザー一覧、除外ユーザー一覧
- 出力:Oktaグループメンバーの更新(必要に応じてSlack通知)
- ポイント:大量更新時はAPI制限・実行時間に注意(バッチ分割や通知抑制を検討)
補足
トリガーについて
最低限1日に1回実行するとよいと思います。この仕組みではSmartHR上で更新がない場合は処理がスキップされるため、1時間に1回の実行でもよいかもしれません。
ストッパーについて
Oktaグループの作成とメンバーの所属を実際に行う前に01. SmartHR to Okta Group上の04. Okta Group Managementを呼び出す直前にストッパーを設けています。
これによりまずはテーブルに記録された部署一覧やユーザーの所属部署に不備がないかをチェックすることをおすすめします。
初回実行時のSlack通知
Oktaグループの作成およびメンバー所属処理結果はSlackのスレッド返信としているため、大量のメッセージが生成される初回実行時はSlack APIの応答時間が長くなりOkta Workflowsの処理全体が遅延する可能性があります。
初回のみSlack通知部分を無効化することをおすすめします。
エラーハンドリング(よくあるエラーと対処)
- SmartHR側にOktaユーザーを特定できるメールアドレスが無い/空:Oktaユーザーを特定できず、グループメンバー反映ができません。SmartHRのカスタム項目と入力ルールを見直します。
- 部署名の重複によるグループ名衝突:部署名をそのままグループ名にすると衝突します。プレフィックスを付ける/命名規則を見直す/IDを名称に含める等で回避します。
- 初回実行で通知が大量・処理が遅い:初回はグループ作成とメンバー反映が集中します。初回のみ通知を無効化する、またはバッチ分割する等でAPI負荷を抑えます。
まとめ
今回ご紹介した仕組みでは、SmartHRの部署・従業員情報をマスターとして、Okta側の部署グループ(作成/更新/削除)とメンバー所属を自動で追従させることができました。手作業やGroup Ruleの保守に頼らず、部署の追加・改称・統廃合やメンバー増減といった変更に対して、一定のルールで運用できる点が大きなメリットです。
結果として、部署改編のたびに発生しがちな「グループ作成/メンバー棚卸し/ルール更新」といった手作業を大幅に削減できます(運用によっては、月次の棚卸し作業がほぼ不要になります)。
一方で、フロー数が増えやすい構成でもあるため、運用に合わせて共通化・統合を検討すると管理が楽になります。例えば以下のような工夫が有効です。
- トリガーとなるScheduled flowを以下の仕組みに組み込む
- SmartHRから行なっている部署情報と従業員情報の処理はひとつのflowで受け取り、条件分岐を作る
SmartHRの部署情報を起点に、Oktaグループの作成からメンバー管理までを自動で追従できるようになると、日々の運用負荷をぐっと下げつつ、組織変更にも強い仕組みになります。本記事のフロー構成や考え方が、みなさんの運用改善のヒントになれば幸いです。


