SlackとAzureADとの自動プロビジョニングとそれに関する運用

こちらの記事は、Slack Advent Calendar 2020 25日目 最終日の記事になります。
作成時間を確保したくて後ろのほうでエントリーしようとしたらトリになってしまいました。

## はじめに
Windows系の社内SEとして主にMicrosoft製品関連のお守りをしているのですが、社内の様々な諸事情によりMS畑の私がMSTeamsではなくSlackを管理することとなりました。
Slackのアクティブユーザー数に対して運用者が非常に少なかったため、アカウント管理などのルーチン作業系は極力自動化する必要があります。
そこで、AzureADの自動プロビジョニング機能を活用しSlackアカウント管理の工数を大幅に削減することを目標としました。

## 導入背景など
2018年頃より全社用Slackワークスペースの利用をスタートしましたが、継続的にアクティブ数が増え続け、2020年初旬にはコロナ流行に伴いリモートワークの比率が増加しさらにユーザー数が増加しました。
その結果アクティブユーザー数が4000ユーザーを超えてしまい、アカウントの手動管理の範疇を大幅に超えてしまったため、アカウント管理（入退職によるアカウントの停止、棚卸など）の方法を大きく見直す必要が発生しました。
このユーザー数の急増を受け、会社としての契約をPlusからEnterpriseGridへ変更するとともに、AzureADとのSAML連携＋アカウントの自動プロビジョニング環境を構成しました。

##AzureADとの自動プロビジョニング構成
基本的な構成そのものは、Microsoft Docsに記載のある通りに構成するだけで簡単に設定が可能です。
各手順における若干の注意点のみ抜粋して記載します。

**手順①：Azure Active Directory シングル サインオン (SSO) と Slack の統合**
https://docs.microsoft.com/ja-jp/azure/active-directory/saas-apps/slack-tutorial
https://get.slack.help/hc/articles/220403548-Guide-to-single-sign-on-with-Slack%60

**[基本的な SAML 構成] セクション**
EnterpriseGridプランの場合、他のプランと異なりGrid全体を管理するためのURLが存在します。
例）`https://DOMAIN-NAME.enterprise.slack.com/`
これに照らし合わせた場合、SAML構成のセクションは以下のような記述になります。

```
識別子(エンティティID)：https://DOMAIN-NAME.enterprise.slack.com/
応答URL：https://DOMAIN-NAME.enterprise.slack.com/sso/saml
サインオンURL：https://DOMAIN-NAME.enterprise.slack.com/sso/saml/start
```
また、このURLはSlackSSOの設定にある「サービスプロバイダ発行者」の値にも利用します。

```
サービスプロバイダ発行者：https://DOMAIN-NAME.enterprise.slack.com/
```
**手順②：Slack を構成し、自動ユーザー プロビジョニングに対応させる**
https://docs.microsoft.com/ja-jp/azure/active-directory/saas-apps/slack-provisioning-tutorial

**[属性マッピング] セクション**
基本的な属性マッピングはデフォルトで問題ありません。
自社テナント内でカスタムの値を入れている場合は、`emailaddress/name/displayname` の値に注意してセットしてください。

しかしながら、デフォルトの設定だと実運用上でいろいろと不都合な点もありました。
具体的な事象については次項で記載します。

##自動プロビジョニング実行中のTIPS

### [TIPS#1] Slackでの表示名変更可能オプション問題
EnterpriseGrid全体の設定（以降、OrG設定とします）の中に、[セキュリティ]>[SSO設定]>[環境設定]>[表示名の変更をユーザーに許可する] という設定があります。
これはIdPから連携された表示名（displayName属性）をユーザー側が任意の値に変更可能かどうかの設定なのですが、弊社ではこれを`ON`として設定しています。
実はこの設定を`ON`にした場合、裏では`自動プロビジョニングにてIdPからdisplayName属性値に更新があったとしても、その更新をSlack側では受け付けない`という設定に変わります。

ここで、AzureADの自動プロビジョニングのデフォルト設定を見てみましょう。
※非常に分かり辛いところにあります。
[エンタープライズアプリケーション]>[プロビジョニング]>[プロビジョニングの編集]>[マッピング]>[Probision Azure Active Directory users]
表示される[Azure Active Directory 属性]の一覧からdisplayNameを選択すると、以下のような設定となっています。
![displayname.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214442/7f560aa2-5c41-cac7-cf6b-c6dbe0bee0da.png)
[このマッピングを適用する]の値が、デフォルトだと`常時`でセットされています。
この設定の場合、AzureADにてdisplayNameが変更されると自動プロビジョニングの動作としてSlack側へ値を更新するように命令を出します。

そうなると、先に書いたOrg設定の [表示名の変更をユーザーに許可する] をONにした時の裏動作である `自動プロビジョニングにてIdPからdisplayName属性値に更新があったとしても、その更新をSlack側では受け付けない` という設定とバッティングしてしまい、プロビジョニングエラーが発生するようになります。

**解決策：**
属性マッピングの設定にてUserのdisplayName属性を編集し、[このマッピングを適用する]を `常時` から `オブジェクトの作成中のみ` 変更します。
こうすることで仮にAzureAD側でdisplayName属性を変更しても、Slack 側に同期されなくなりエラーが解消されます。

### [TIPS#2] 旧字体問題
新しい方が入社されてAzureにアカウントが作成されたのですが、自動プロビジョニングでエラーコード400が返ってきてしまいアカウント作成がいつまで経っても完了しない事象となってしまいました。
Microsoft/Slack 双方のサポートとやり取りしてようやく分かったのですが、AzureAD側のGivenname属性値に旧字体を使った名前が格納されており、この値をSlack側に渡そうとするとSlack側のDBが旧字体に対応していないため処理できず、アカウント作成でエラーになってしまうとのことでした。

**解決策：**
TIPS#1の時と同じく、UserのGivenName/SurName属性の [このマッピングを適用する] の値を`オブジェクトの作成中のみ` 変更。
合わせて該当ユーザーのAzureADのGivenname属性値を一時的に新字体へ変更し、自動プロビジョニングを走らせました。
その後、OutlookなどOffice365サービスでの表記が旧字体となるようにAzureADの値は旧字体へ戻しています。

### [TIPS#3] 同一username問題
Slackのアカウントは、emailが重複してはいけないことはご存じの方も多いと思うのですが、もう1つ重複のチェックをしている属性値があります。
それは ユーザー名=UserName なのですが、これが重複してはいけない対象の範囲が非常に広いです。

■ UserNameの重複判定で引っかかるもの
①通常アカウントのユーザー名
②ゲストアカウントのユーザー名
③ユーザーグループ名
④チャンネル名

新しく自動プロビジョニングにて通常アカウントを作成しようとした際、①～④の中の何かと重複してしまうとエラーになります。
現在の自動プロビジョニングの設定では、UserNameの値にはメールエイリアスを入れているのですが、たまにゲストアカウントのメールエイリアスと被ってしまうことがありました。

例）
4月1日に、hogehoge@a-company.com というゲストアカウントを作成。
その方のユーザー名は`hogehoge`として登録される。
6月1日に、社員としてAzureADに hogehoge@heisya.co.jp というアカウントが作成される。
自動プロビジョニングでSlackにアカウントを作成しに行こうとすると、`hogehoge`が既に使用されていて作成エラーとなる。

**解決策：**
このトラブルシュートで厄介なところは、ユーザー名のみならずユーザーグループ名やチャンネル名との重複もNGとなる点です。
さらにさらに、重複はアクティブユーザーだけではなくOrGから解除したユーザーも対象となるので要注意です。
被疑個所と思われるところを全検索等で調査を行い、重複してしまっている値を修正することでエラーが解消されます。
Slackのヘルプリクエストに聞いてまるっと検索してもらうのが一番手っ取り早いかもしれません。

### [TIPS#4] AzureADの「サインインのブロック」機能問題
AzureADユーザーのオプション設定の中に「サインインのブロック」という機能があります。
この機能は文字通り対象のユーザーがAzureADに認証しに来た際にブロックする機能なのですが、実のところは「ブロック」しているのではなく、「アカウントが事実上無効化状態となりブロックされるという結果が得られる」という機能になります。

このサインインのブロックという設定をオンにするとユーザーが持つ属性値の AccountEnabled の値が False となり、その後のSlackへのプロビジョニング処理で Slack へ accountEnabled = False および IsSoftDeleted = True が同期されます。
その結果、Slackアカウントが組織から解除されてしまいました。

育休や産休などで休職状態になるユーザーはこのブロック機能を使ってサービスが利用できないようにすればいいかと思っていたのですが、自動プロビジョニングで解除状態になるのは少々困ります。
解除されるとそのアカウントが所属していたワークスペースすべてからはじき出されてしまい、チャンネルの所属状況もすべてリセットになります。これは現在の社内運用上はあまりよろしくありません。

**解決策：**
なし！
この機能を使わないか、解除されることを承知の上でプロビジョニングを回すかになります。


## おわりに
もう1つ [TIPS#5]AzureADアカウント削除関連 でネタがあるのですが、かなり記事が長くなってしまったのと、このTIPS単品で結構長めの説明が必要になるので、後日別の記事にして書き上げたいと思います。

社内政治に巻き込まれながらのSlack運用ではありますが、同チームメンバーに恵まれたこともありユーザーへの提供はスムーズにできていて、個人的には非常に良い形でサービス提供ができていると思っています。

昨今のセキュリティ事情もありますので、来年は監査やセキュリティに注力していきたいと思っています。