コンテンツまでスキップ

【Okta】SmartHRのWebhookを起点にOkta Workflowsでユーザー作成・更新・無効化を自動化する

はじめに

こんにちは、ネクストモード株式会社テクニカルサポート担当です。

SmartHRの更新情報をもとにOkta側でユーザーを作成・更新する方法を検討する機会が多かったため、SmartHRのWebhook機能とOkta Workflowsを組み合わせた実現方法をご紹介します。

前提

この記事では、以下のような状況を想定しています。

  • 人事部
    • SmartHRの主管部署
    • CSVを利用したユーザーインポートや更新、管理画面での個別ユーザーの作成・更新を行います。
  • 情報システム部
    • Oktaの主管部署
    • SmartHRには機微な情報が含まれるため、必要最小限の情報のみを扱いたいと考えています。
    • Okta WorkflowsによるOktaユーザーの作成はStagedとし、有効化は手動運用とします。

 

処理の全体像

SmartHRからOkta WorkflowsがWebhookで「更新されたIDのみ」を受け取り、イベントタイプごとにOktaユーザーの作成・更新・無効化を行います。

  • Webhook受信(Main flow)
    • SmartHRの従業員イベントをトリガーに、変更対象レコードのIDのみをOkta Workflowsへ送信
  • 詳細情報の取得(Helper flow)
    • 受け取ったIDでSmartHR APIをコールし、必要最小限の属性のみ取得
    • カスタム項目(例: 法人メールアドレス)は custom_fields をグルーピングして参照
  • アクション決定
    • Okta既存ユーザーの有無や在籍ステータスを考慮し、アクションを決定
  • アクション実行と結果出力
    • 決定結果に応じてOkta APIカードを実行
    • 成否に応じたメッセージを生成し、ログや通知に利用

 

SmartHRの設定

Okta Workflowsと連携するためにWebhookの設定とAPIトークン設定を行います。

 

Webhook設定

URLにはOkta WorkflowsのAPI Endpointカードで発行されたURLを指定します。

シークレットトークンは自動生成し、Okta Workflowsのトークン確認で利用します。

送信のトリガーとなるイベントは「従業員の追加」「従業員の更新」「従業員のインポート」とします。

送信する内容は「変更されたデータのIDのみ送信する」

この設定にチェックを入れない状態ではWebhookに送信されるデータには従業員の機微な情報も含まれています。そこでIDのみとし、必要な情報は限定した権限設定をしたアクセストークンを用いAPIを実行し取得します。

参考:https://support.smarthr.jp/ja/help/articles/5260914962073/

SmartHRでWebhook設定をしている画面です。

 

アクセストークン設定

以下のように従業員情報の参照のみとします。

SmartHRでアクセストークンの基本的な情報を設定している画面です。

 

さらに従業員項目のアクセス許可で以下のように必要最小限の項目のみを参照します。退職事由や等級のようなOkta連携において不要な項目はチェックをオフにします。

 SmartHRで従業員項目のアクセス許可の設定画面上段です。

中略

 SmartHRで従業員項目のアクセス許可の設定画面中段です。

中略

 SmartHRで従業員項目のアクセス許可の設定画面下段です。

 

Okta Workflowsの作成

作成したflowは合計で2つです。それぞれご紹介します。

まず、SmartHR APIを実行するための汎用APIコネクタを以下のように設定します。SmartHRコネクタのRead Employeeカードを使用しない理由は後述します。

  • Auth Type:Custom
  • Header Name:Authorization
  • Header Value:Bearer {発行したアクセストークン}

okta-smarthr-workflows-automation-21

 

01. SmartHR Employee Record Event Handler

SmartHRから更新情報をWebhookで受け取り、ステータスコードの返却やトークンが一致した場合のみ処理を継続します。

SmartHRのWebhookを受け取るOkta Workflowsのflowの前半部分です。

 

受け取ったBodyから必要な値として、「event」「crew」「crew_import_result.created_crews」「crew_import_result.updated_crews」を取得します。「crew」についてはリストに変換します。リストに変換する理由については後述します。

また、「event」に応じて処理を分岐し、Helper flowである02. SmartHR Employee Record Sync to Oktaへリスト内のレコードを送信します。

SmartHRのWebhookを受け取るOkta Workflowsのflowの後半部分です。

 

If/ElseIfカードでは、第1条件として「event」がcrew_createdまたはcrew_updatedに該当する場合を設定し、リスト化したcrewをHelper flowに渡して処理を実行しています。

SmartHRのWebhookを受け取るOkta Workflowsのflowの後半部分で条件分岐をしている画面です。

 

第2条件では「event」がcrew_importedの場合とし、「crew_import_result.created_crews」と「crew_import_result.updated_crews」それぞれをHelper flowに渡して処理を実行しています。

SmartHRのWebhookを受け取るOkta Workflowsのflowの後半部分で条件分岐をしている画面です。

 

02. SmartHR Employee Record Sync to Okta

Main flowから呼び出されるHelper flowです。CrewのIDからAPIコール用のURLを作成します。

Main flowからリスト内のレコードを処理するOkta Workflowsの1/5部分です。

 

If Errorカードの中で汎用APIコネクタからSmartHR APIを実行し、エラーがなくレスポンスBodyが存在する場合に処理を続行します。

Main flowからリスト内のレコードを処理するOkta Workflowsの2/5部分です。

 

レスポンスBodyから必要な項目を取得します。SmartHR上で追加したカスタム項目はcustom_fieldsとしてリスト形式で取得できます。リスト形式からGroup byカードにより項目名でグループ化し、取得したい項目名.0.valueという形式で値を取得します。今回はカスタム項目として法人メールアドレスという項目を追加しているため、その値を法人メールアドレス.0.valueとして取得します。

Main flowからリスト内のレコードを処理するOkta Workflowsの3/5部分です。

 

既存Oktaユーザーが存在するかをOktaのプライマリーメールアドレスと従業員番号の2点が一致することで判定します。従業員のが存在状況とSmartHRの在籍状況と組み合わせてどのようなアクションを行うかを決定します。

Main flowからリスト内のレコードを処理するOkta Workflowsの4/5部分です。

 

決定されたアクションに基づき、Oktaに対して「ユーザー作成」「ユーザー更新」「ユーザー無効化」を実行します。それぞれの処理に応じたメッセージを作成します。今回はデバッグ目的としていますが、SlackやTeamsなどのメッセージツールに送信することもできます。

Main flowからリスト内のレコードを処理するOkta Workflowsの5/5部分です。

 

If/ElseIfカードでは、第1条件としてアクションが「Create」の場合、If ErrorカードでCreate Userカードを実行します。正常に動作した場合はメッセージを作成し、If Errorカードの出力とします。

条件分岐の第1条件でOktaユーザー作成を実行しています。

エラーが発生した場合は、エラーメッセージを作成してIf Errorカードの出力とします。

Oktaユーザー作成でエラーが発生した時の処理です。

これらのIf Errorカードのアウトプットを、If/ElseIfカードの第1条件のアウトプットとします。

 

第2条件として、アクションが「Update」の場合、Update Userカードを実行します。メッセージを作成し、第2条件のアウトプットとします。

条件分岐の第2条件でOktaユーザー更新を実行しています。

 

第3条件として、アクションが「Deactivated」の場合、Deactivate Userカードを実行します。メッセージを作成し、第3条件のアウトプットとします。

条件分岐の第3条件でOktaユーザー無効化を実行しています。

 

第4条件として、アクションが「Do nothing」の場合、メッセージを作成し、第4条件のアウトプットとします。

条件分岐の第4条件でメッセージ作成のみをしています。

 

設計のポイント

今回のflowでは効率的でメンテナンス性を高めるために以下の3つのポイントで実現しました。

 

リスト化の意味

今回、SmartHRのWebhook設定で送信のトリガーとなるイベントで「従業員の追加」「従業員の更新」「従業員のインポート」を選択しています。

以下のドキュメントを参照するとイベントIDが「crew_created」「crew_updated」の場合は送信オブジェクトは「Crew」となり、イベントIDが「crew_imported」の場合は「CrewImportResult」となります。「Crew」は単一のオブジェクトですが、「CrewImportResult」はリストです。

https://developer.smarthr.jp/api/about_webhook

Okta Workflowsではリストの場合はHelper flowを実行する必要がありますが、単一オブジェクトでは本来、その必要はありません。つまり、「Crew」の場合は02. SmartHR Employee Record Sync to Oktaを利用せず、01. SmartHR Employee Record Event Handlerの中で処理を実行することができます。

しかし、この状態では同じ処理を複数のflowに分散してしまい将来のメンテナンス工数も増加することが予想されます。

そこで、単一のオブジェクトであってもリストに変換することで後続処理を共通化し、02. SmartHR Employee Record Sync to Oktaに集約する設計としました。

 

SmartHRコネクタのRead Employeeカードを利用しない理由

現在のSmartHRコネクタは最終更新が2023/5/25のバージョンは0.141.0となっています。

Okta WorkflowsのSmartHRコネクタです。

このバージョンでは部署情報に「full_name」が含まれていません。そのため「xx本部/yy部/zzチーム」のような値を取得するには、階層構造を別途解析する必要があり、専用のHelper flowが必要です。一方、APIを直接実行すればレスポンスの部署情報に「full_name」が含まれます。また、役職についても現在は非推奨の「position」のみを取得でき、新しく追加された「positions」は取得できません。これらの理由から、SmartHRコネクタのRead Employeeカードではなく汎用的なAPIカードを利用しています。

この点に気づくまでに時間を要したため、今後SmartHRコネクタがアップデートされ、最新のAPIに対応することを期待しています。

 

アクション決定と実行を分けるメリット

Okta Workflowsで処理を実装する際、条件分岐の中に「Create User」「Update User」「Deactivate User」などのカードを直接配置することも可能です。しかし今回は、「アクションの決定」と「アクションの実行」を分離する設計にしました。

今回のケースでは、Oktaユーザーの存在状況(存在する・しない)とSmartHRの在籍状況(在職中・休職中・退職済)の組み合わせで「アクションの決定」を行い、「アクションの実行」は別の独立したブロックとしています。

この設計には以下のメリットがあります:

  • 条件判定ロジックがシンプルになり、flowの可読性が向上する
  • エラーハンドリングを実行部分に集約できる
  • 新しいアクションを追加する際の変更箇所が明確になる

特にアクション追加の対応が容易になります。たとえば、Oktaユーザーが存在し、SmartHRで休職中のステータスを処理する場合、アクション決定の定義とアクション実行の条件分岐を追加するだけで完了します。

 

まとめ

SmartHRの情報をもとにOktaユーザーを作成・更新することは、多くの組織が日々取り組んでいる課題の一つです。本記事では、Okta Workflowsを活用した具体的な実現方法について詳しくご紹介しました。

実際の運用においては、入社日に基づいた処理のタイミング制御など、組織ごとに固有の要件やビジネスルールが存在することが一般的です。中間DBやテーブルとの組み合わせによるデータ管理、日時ベースでの処理スケジューリングなど、より複雑で高度なflowの設計が必要になるケースも少なくないでしょう。

この記事で紹介した設計思想や実装のポイントが、そのような様々な状況においても皆さんの実装作業のお役に立てればうれしいです。