こんにちは、ネクストモード株式会社テクニカルサポート担当です。
SmartHRの更新情報をもとにOkta側でユーザーを作成・更新する方法を検討する機会が多かったため、SmartHRのWebhook機能とOkta Workflowsを組み合わせた実現方法をご紹介します。
この記事では、以下のような状況を想定しています。
SmartHRからOkta WorkflowsがWebhookで「更新されたIDのみ」を受け取り、イベントタイプごとにOktaユーザーの作成・更新・無効化を行います。
Okta Workflowsと連携するためにWebhookの設定とAPIトークン設定を行います。
URLにはOkta WorkflowsのAPI Endpointカードで発行されたURLを指定します。
シークレットトークンは自動生成し、Okta Workflowsのトークン確認で利用します。
送信のトリガーとなるイベントは「従業員の追加」「従業員の更新」「従業員のインポート」とします。
送信する内容は「変更されたデータのIDのみ送信する」
この設定にチェックを入れない状態ではWebhookに送信されるデータには従業員の機微な情報も含まれています。そこでIDのみとし、必要な情報は限定した権限設定をしたアクセストークンを用いAPIを実行し取得します。
参考:https://support.smarthr.jp/ja/help/articles/5260914962073/
以下のように従業員情報の参照のみとします。
さらに従業員項目のアクセス許可で以下のように必要最小限の項目のみを参照します。退職事由や等級のようなOkta連携において不要な項目はチェックをオフにします。
中略
中略
作成したflowは合計で2つです。それぞれご紹介します。
まず、SmartHR APIを実行するための汎用APIコネクタを以下のように設定します。SmartHRコネクタのRead Employeeカードを使用しない理由は後述します。
SmartHRから更新情報をWebhookで受け取り、ステータスコードの返却やトークンが一致した場合のみ処理を継続します。
受け取ったBodyから必要な値として、「event」「crew」「crew_import_result.created_crews」「crew_import_result.updated_crews」を取得します。「crew」についてはリストに変換します。リストに変換する理由については後述します。
また、「event」に応じて処理を分岐し、Helper flowである02. SmartHR Employee Record Sync to Oktaへリスト内のレコードを送信します。
If/ElseIfカードでは、第1条件として「event」がcrew_createdまたはcrew_updatedに該当する場合を設定し、リスト化したcrewをHelper flowに渡して処理を実行しています。
第2条件では「event」がcrew_importedの場合とし、「crew_import_result.created_crews」と「crew_import_result.updated_crews」それぞれをHelper flowに渡して処理を実行しています。
Main flowから呼び出されるHelper flowです。CrewのIDからAPIコール用のURLを作成します。
If Errorカードの中で汎用APIコネクタからSmartHR APIを実行し、エラーがなくレスポンスBodyが存在する場合に処理を続行します。
レスポンスBodyから必要な項目を取得します。SmartHR上で追加したカスタム項目はcustom_fieldsとしてリスト形式で取得できます。リスト形式からGroup byカードにより項目名でグループ化し、取得したい項目名.0.valueという形式で値を取得します。今回はカスタム項目として法人メールアドレスという項目を追加しているため、その値を法人メールアドレス.0.valueとして取得します。
既存Oktaユーザーが存在するかをOktaのプライマリーメールアドレスと従業員番号の2点が一致することで判定します。従業員のが存在状況とSmartHRの在籍状況と組み合わせてどのようなアクションを行うかを決定します。
決定されたアクションに基づき、Oktaに対して「ユーザー作成」「ユーザー更新」「ユーザー無効化」を実行します。それぞれの処理に応じたメッセージを作成します。今回はデバッグ目的としていますが、SlackやTeamsなどのメッセージツールに送信することもできます。
If/ElseIfカードでは、第1条件としてアクションが「Create」の場合、If ErrorカードでCreate Userカードを実行します。正常に動作した場合はメッセージを作成し、If Errorカードの出力とします。
エラーが発生した場合は、エラーメッセージを作成してIf Errorカードの出力とします。
これらのIf Errorカードのアウトプットを、If/ElseIfカードの第1条件のアウトプットとします。
第2条件として、アクションが「Update」の場合、Update Userカードを実行します。メッセージを作成し、第2条件のアウトプットとします。
第3条件として、アクションが「Deactivated」の場合、Deactivate Userカードを実行します。メッセージを作成し、第3条件のアウトプットとします。
第4条件として、アクションが「Do nothing」の場合、メッセージを作成し、第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コネクタは最終更新が2023/5/25のバージョンは0.141.0となっています。
このバージョンでは部署情報に「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の在籍状況(在職中・休職中・退職済)の組み合わせで「アクションの決定」を行い、「アクションの実行」は別の独立したブロックとしています。
この設計には以下のメリットがあります:
特にアクション追加の対応が容易になります。たとえば、Oktaユーザーが存在し、SmartHRで休職中のステータスを処理する場合、アクション決定の定義とアクション実行の条件分岐を追加するだけで完了します。
SmartHRの情報をもとにOktaユーザーを作成・更新することは、多くの組織が日々取り組んでいる課題の一つです。本記事では、Okta Workflowsを活用した具体的な実現方法について詳しくご紹介しました。
実際の運用においては、入社日に基づいた処理のタイミング制御など、組織ごとに固有の要件やビジネスルールが存在することが一般的です。中間DBやテーブルとの組み合わせによるデータ管理、日時ベースでの処理スケジューリングなど、より複雑で高度なflowの設計が必要になるケースも少なくないでしょう。
この記事で紹介した設計思想や実装のポイントが、そのような様々な状況においても皆さんの実装作業のお役に立てればうれしいです。