こんにちはー!たつみんです?
今回はOktaで特定のユーザーだけがプロビジョニングができずに、下記の画像のようにAutomatic profile push of <ユーザー名> to app <アプリ名> failed: Error while trying to push profile update for <ユーザーアカウント>:No user returned for user <External ID>
とエラーメッセーが表示される場合のトラブルシューティング方法についてご案内します。

現象の発生原因
OktaからSaaSに対してプロビジョニング設定している状態でSaaS側でアカウント削除を行った場合に発生します。OktaではSaaS側でのアカウント削除を認識できないまま、プロファイルプッシュを実施してしまうためにこのようなエラーが表示されます。
対処方法 1
Okta上でエラーが発生しているユーザーをアプリケーションのアサインを外し再度アサインを行います。ユーザー作成のプロビジョニングが実行され、SaaS側にユーザーが作成されます。
この操作でもエラーが表示されSaaS側にユーザー作成が行われない場合は対処方法 2をご確認ください。
対処方法 2
対処方法 1で解決しない場合以下の手順を実施します。
- Okta APIを利用し、該当ユーザーのExternal IDの値を確認する
- External IDがエラーメッセージに含まれることを確認する
- Okta上の対象SaaSのプロビジョニング設定をoffにする
- Okta上の対象SaaSでエラーが発生しているユーザーのアサインを外す
- Okta APIを利用し、該当ユーザーのExternal IDをnullに設定する
※API実行時にユーザーが自動的にアプリケーションにアサインされます - Okta上の対象SaaSのプロビジョニング設定をonにする
1から6の設定を行うことでSaaS側にユーザーが作成されます。
詳細な解説については本記事下部の4.補足解説 External IDとは何者か?にて触れます。
External IDの確認について
実行するAPIは以下の形式です。
- GET
/api/v1/apps/${applicationId}/users/${userId}
APIのドキュメントは下記のとおりです。
API実行時の${applicationId}および${userId}については以下の方法で確認することができます。
applicationId
アプリケーションの画面を開きURLの/instance/
の次の部分です。

userId
ユーザーを開きURLの/view/
の次の部分です。

APIの実行にはChrome拡張機能のrockstarを活用しました。
実際にrockstarでAPIを実行をした画面が下記です。

エラーメッセージとの確認
1.で確認したexternalIdがエラーメッセージに含まれていることを確認します。

プロビジョニング設定をoffにする
対象アプリケーション設定のProvisioningからOktaからのプロビジョニング設定を全てoffにします。

あらかじめ3.でプロビジョニング設定をoffにしておかないと5.のAPI実行時にプロビジョニングが実行されてしまい、結果としてExternal IDをnullに設定することはできません。
エラーが発生しているユーザーのアサインを外す

External IDにnullを設定する
実行するAPIは以下の形式です。
- POST
/api/v1/apps/${applicationId}/users/${userId}
- POSTするデータ
{"externalId":"null"}
実際にrockstarでAPIを実行をした画面が下記です。

APIのドキュメントは下記のとおりです。
プロビジョニング設定をonにする
最後に手順3.でオフにしたプロビジョニング設定を元に戻します。

Tips ユーザーアサインをグループで行っている場合の対処方法
グループを活用してアプリケーションにユーザーをアサインしている場合は以下の方法でエラーが発生しているユーザーのみのアサインを外すことができるようになります。
- 該当ユーザーの編集画面を表示します。
- Assignment masterを「Administrator(override group)」を選択し、Saveをクリックします。
- TypeがGroupからIndividualに変化し、グループからは独立してアサインを外すことができるようになります。
エラーが解消した後に再度ユーザーをグループ管理に戻す場合は以下の手順を行います。
- Convert assignmentsからSelect assignments to convertをクリックします。
- グループに戻したいユーザーを選択し、Convert selectedをクリックします。
補足解説 External IDとは何者か?
以下は今回の現象をより深く理解するための補足解説となります。
今回APIでExternal IDをnullに設定することで、問題を解決しましたが、そもそもこのExternal IDとは何者でしょうか?
SaaSによってはユーザーを識別するために内部的なIDを発行していることがあります。Oktaでプロビジョニングを有効にし、ユーザー作成の際に発行されたSaaSで発行された内部的なIDをOktaではExternal IDとして保持します。
External IDはSaaS側で確認できない場合やOktaでも通常は表示されません。Oktaで確認できるのはAPIを利用するか、アサインされたユーザーの編集画面で表示されるのみです。

Oktaがプロファイルのアップデートを行う時にはExternal IDを基準にSaaSに対してプッシュします。
今回のエラーは、SaaS側でユーザー削除を行っているためExternal IDで識別されるアカウントは存在しなくなっています。そのため、Okta側で存在しないExternal IDに基づいてプロファイルプッシュや再アサインを行ってしまいエラーが発生してしまいました。
この記事の冒頭のエラーメッセージは、Oktaは存在すると思ったのにSaaS側はそのExternal IDをもつユーザーはいませんということをNo user returned for user {externalId}として表現している状態でした。
Slackでも検証してみました
Slackの場合、ユーザーの削除は行えずに解除することしかできません。解除済みのユーザーを再度有効化する場合の挙動についてもExternal IDに注目してみていきます。
まずユーザーがOkta上のSlackアプリケーションにアサインされている状態つまり正常である状態でExternal IDを確認してみます。
実行するAPIは以下の形式です。
- GET
/api/v1/apps/${applicationId}/users/${userId}
今回の場合は以下のような結果が返ってきます。

余談ですが、このAPI実行結果のexternalIdはSlack上で確認できるメンバーIDと一致することがわかります。

ではあえてエラーが発生するようにSlack側でユーザーを解除します。
解除後にOkta側でも一度ユーザーのアサインを解除し、再度アサインを実施します。
下記のようなエラーが表示されました。このエラー内容はこの記事冒頭のエラーとは少し違うことに気づきました。
User account is inactive ユーザーアカウントがアクティブでないというメッセージですね。

それでは再度、External IDを確認してみます。

今回はexternalIdの値がnullとなっています。
今回は解除済みユーザーを復元する操作を行うためnullになってしまったexternalIdにSlackユーザーIDを設定する必要があります。
手順は下記の通りです。
- Okta上のSlackのプロビジョニング設定をoffにする
- Slackで解除済みユーザーを有効化する
- Okta上のSlackでエラーが発生しているユーザーのアサインを外す
- Okta APIを利用し、該当ユーザーのExternal IDをSlackのユーザーIDに設定する
※API実行時にユーザーが自動的にアプリケーションにアサインされます - Okta上のSlackのプロビジョニング設定をonにする
rockstarでAPIを実行をした画面が下記です。
レスポンスのexternalIdがnullとなっていますが実際には反映されています。

これでOkta上でのexternalIdとSlackのユーザーIDが紐付き、アカウント状態もOkta、Slackの双方で有効であるためユーザーはOkta認証を使いSlackに再びアクセスできるようになります。
検証のオチ
ここまで検証した後に気づいたのですが、このSlackの場合の挙動はプロビジョニング設定でDeactivate Usersを無効にしている場合に発生します。
そのため、この検証で行った方法は、Deactivate Usersを有効化できない組織で、Slack解除済みのユーザーを再有効化したいという場合のみ有効です。

まとめ
External IDは普段Okta上では表示されない値のため、予めこの存在を知っているか知らないかでエラーに直面した際の対応策にたどり着くまでに差が出ると思います。またSaaSによってはアカウント解除なのか削除なのか、Oktaでのプロビジョニング解除時の挙動についても意識しておく必要もあることがわかります。
プロビジョニングとExternal IDの関係はとても深いものなので、Oktaでアプリケーションアサインの画面でユーザーにエラーが表示されている場合はまずはAPIでGET /api/v1/apps/${applicationId}/users/${userId}
で確認してみると糸口が掴めるのではないかと思います。
今回の記事の内容がトラブルシューティングの一助になれば幸いです。