Okta FastPass+Oktaの認証ポリシーを用いて、特定のアプリに対するテナント制限を実装した話

はじめに

近年、個人端末の業務利用を起因とする 企業チャットやクラウドサービスにおける不正アクセス・情報流出の事例が増加しています。

piyolog.hatenadiary.jp

個人端末は、OSアップデートやセキュリティ対策の状況を企業側で一律に担保することが難しく、 万一アカウントや認証情報が漏えいした場合、なりすましや情報の閲覧・持ち出しといった被害に加え、 さらなる二次被害に発展するリスクがあります。

上記のようなセキュリティリスクを低減するため、Okta FastPass+Oktaの認証ポリシーを用いて

当社管理外のデバイスから当社テナントのGoogleWorkspace,Slackへのアクセスを制限する

このような取り組みを実施しました。
本記事では実際の導入プロセスや、設定上のポイント等を振り返ります。

本記事のポイント

  • Okta FastPass+認証ポリシーの機能を用いたテナント制限の実現方法を紹介
  • 実際の導入プロセスと設定・運用時のポイントを解説
  • Workatoによるdevice.idの自動付与フローを紹介 (概要レベル)
  • テナント制限適用後の挙動例を紹介

お読み頂く前に

この記事と同様の実装をする場合に必要なOktaライセンス

 Single Sign-On
 Universal Directory
 MFA

本記事に関連するOkta公式ドキュメント

 Okta Verify
 Okta FastPass
 Okta 認証ポリシー(アプリサインインポリシー)


アーキテクチャと処理フロー図

全体像はこんな感じです。

・端末許可IDの登録 ・アクセス制御

1️⃣ユーザーが端末にインストールされているOkta Verify経由でOktaにサインインすることで、デバイス情報がOktaに登録され、(device.enrollment.create)のイベントが発生。

2️⃣ 1️⃣のイベントをWorkatoでキャッチし、あらかじめ用意した社用端末管理リストの情報とイベントの情報を突合。その結果、PC・スマホそれぞれで指定の値が一致した場合のみ、device.idをそのイベントを発生させた Okta ユーザーのプロファイルのカスタム属性「端末許可ID」に書き込む。
(この一連の処理は Workato で自動化)

3️⃣ Okta FastPassでサインインすることで、OktaのSystem Logに device.id を出力させる

4️⃣ ユーザープロファイル「端末許可ID」の device.id(2️⃣) と、ユーザーが Okta 経由で GWS や Slack に接続した際にログへ出力される device.id(3️⃣) が一致する場合のみアクセスを許可する認証ポリシーを設定し、制限を行う。

といった流れになります。

【device.id】とは
Oktaのdevice.idとは、Oktaに登録されたデバイスを一意に識別するIDです。
Okta Verifyを介してOktaにサインインした際に発行されます。
Okta Admin Consoleのデバイス詳細の画面からは確認ができず、Okta APIやSystem Logを参照することで確認可能です。

詳しい仕組みは導入プロセスの中で説明していきます。


導入プロセス

導入プロセス① 【社用端末管理リストの作成】

「会社で許可された端末かどうか」の判定処理で利用するため、まずは社用端末管理リストを作成します。

当社ではMDMで社用端末を管理しているので、社用端末管理者に協力をお願いし、MDMからCSV出力した管理端末のデータをスプレッドシートに転記・整形して PC用・スマホ用に、それぞれ以下の情報を記載したリストを作成しました。

・PCリスト

A列 (使用者の名前) B列 (シリアル番号) C列 (表示名)
〇〇 XXXXXXX 〇〇-PC
▲▲ YYYYYYY ▲▲-PC

・スマホリスト

A列 (使用者の名前) B列 (モデル) C列 (表示名)
〇〇 iPhone17.5 LP-〇〇-iPhone
▲▲ iPhone14.6 LP-▲▲-iPhone

※「導入プロセス③」の方で説明しますが、
 実際に許可端末かどうかの判定処理に使うのは 赤色部分です


導入プロセス②【Oktaユーザーのプロファイルに「端末許可ID」のカスタム属性をセット】

  • Okta Admin Consoleにて、「Profile Editor」のメニューから、Oktaのデフォルトユーザーに対して「端末許可ID」というカスタム属性を追加します。

 このカスタム属性には、後述する「導入プロセス③」の Workato 処理によって、許可されたデバイスに紐づく device.id が格納されます。
 1つの Okta ユーザーに対して、社用PCや社用スマホなど複数デバイスのアクセスを許可するケースに備え、複数の device.id を格納できるよう、データのタイプは「string array」に設定します。

導入プロセス③ 【Workatoで端末許可IDを自動付与】

Okta Verify経由でOktaへ初回サインインが行われた際に、Oktaにデバイス識別子が登録されます。(device.enrollment.create)

⚠️
画像はスマホのデバイス識別子の例。

PCの場合はシリアル番号の情報も登録される。
※スマホは仕様上シリアル番号は登録されない。

上記device.enrollment.createのイベントをトリガーとしたWorkatoレシピを作成し、以下の処理を自動的に実行させます。
(すでに全社的に導入・活用していたため今回はWorkatoで実装しましたが、Okta Workflowsを用いて実装することも可能だと思います。)


項番 処理概要
1. Oktaのイベントをチェックし、
デバイス登録イベント(device.enrollment.create)が発生した場合をトリガーとする
2. イベント情報から対象が、PC or スマホ どちらなのかを判定
3. 💻対象がPCの場合
 Oktaに登録されたデバイス識別子の「シリアル番号」をチェックし、
 社用端末管理リストの「シリアル番号」列に該当があるかを判定。
 判定結果がTrueの場合のみ、device.enrollment.createを発生させたOktaユーザーのプロファイル「端末許可ID」にdevice.idを追加する。

📱対象がスマホの場合
 Oktaに登録されたデバイス識別子の「表示名」を確認し、
 社用端末管理リストの「表示名」列に該当があるかを判定。
 判定結果がTrueなら、さらにOktaに登録されたデバイス識別子の「モデル」を確認し、
 社用端末管理リストの「モデル」列に該当があるかを判定。
 判定結果がTrueの場合のみ、device.enrollment.createを発生させたOktaユーザーのプロファイル「端末許可ID」にdevice.idを追加する。
4. 処理結果などをSlackに通知

💡ポイント①
こちらに記載した通り、スマホに関してはOktaのデバイス識別子にシリアル番号が登録されないため、PCのようにシリアル番号を判定条件として利用することができません。
そのため本実装では、以下の情報が AND 条件で一致した場合を True とし、一定の精度で「会社で許可された端末であるか」を判定しています。

・ モデル情報(例:iPhone17.5)
・ 表示名(例:LP-〇〇-iPhone)

なお、表示名については当社のMDMにより命名規則を強制し、ユーザーが任意に変更できないようロックしています。
💡ポイント②
Workatoでトリガーとしているのがdevice.enrollment.createのイベントですので、
既に端末でOkta Verifyを利用しているユーザーについては、そのままではデバイス登録イベントが発生しないため、例として以下対応が必要になるかと思います。
(もっといい方法もあるかも....)

案1
Oktaのデバイス情報を一度一括削除し、ユーザーにてOkta Verifyから再度サインインしてもらうことでdevice.enrollment.createのイベントを再発生してもらう
※ユーザー影響があるので事前周知が必要

案2
各ユーザーに紐づくデバイスの device.id をOkta API等で取得し、ユーザープロファイルへ直接登録する

当社では対象ユーザー数がそれほど多くなかったこと、またユーザー作業を最小限に抑えつつ問い合わせの増加を避けたかったため、「案2」の方法を採用しました。

導入プロセス④ 【Okta FastPassのサインイン方式の展開】

テナント制限導入前までは、各ユーザーのOktaへのサインイン方式は特に制限していませんでした。 しかし、ユーザープロファイルに登録した「端末許可ID」と、OktaのSystem Logに含まれる device.id を認証ポリシーで照合するにあたり、 Okta FastPassを利用しない場合、device.id がログに出力されない仕様であることが判明しました。 そのため、本構成を成立させるには Okta FastPassによる認証が必須条件となりました。

もともとOktaのサインインをパスワードレス認証に移行することも検討していたため、良い機会となりました。

  • 主にやったこと
項番 やったこと
1. ユーザーがスムーズにOkta FastPassを使用できるよう、
・端末の生体認証登録方法(Windows Hello、FaceID、Touch IDなど)
・Okta FastPassでのサインイン方法
に関するドキュメントを用意し、事前周知.
2. Okta FastPassの有効化

・Okta Admin Console にて、「セキュリティ」>「Authenticator」へアクセス
・【Okta Verify】のアクションより「編集」を選択。


・【検証オプション】 のところで
 「Okta FastPass(すべてのプラットフォーム)」にチェック
・【Okta FastPass】のところで、
 [Okta FastPassを使用してサインインする] ボタンを表示 にチェック

・「保存」を押す。
3. Okta FastPass有効化後のユーザーサポート(問い合わせ対応など)

導入プロセス⑤ 【認証ポリシーの設定】

「テナント制限」という認証ポリシーを、以下ルールで作成しました。
ここでは設定上ポイントとなるところだけ抜粋して記載します。

ルール1 (会社で許可された端末のみ許可する)

項目 設定値 備考
優先度 1 このルールを最優先にします
IF ユーザーの​ユーザータイプ 任意のユーザータイプ 💡認証ポリシーを検証したい場合は、特定のユーザータイプのみにセットすることで適用範囲を限定できます
AND ユーザーの​グループメンバーシップ 任意のグループ 💡認証ポリシーを検証したい場合は、特定のグループのみにセットすることで適用範囲を限定できます
AND ユーザー 任意のユーザー 💡認証ポリシーを検証したい場合は、特定のユーザーのみにセットすることで適用範囲を限定できます
AND デバイスの​状態 登録済み Okta Vefiryでサインインすることにより、デバイス識別子が登録されているデバイスを対象とします
AND デバイス管理 管理対象外
AND 次の​カスタム式を​trueと​する user.profile.OktaDeviceid.contains(device.id) これが、ユーザープロファイルに登録した「端末許可ID」と、OktaのSystem Logに含まれる device.id を認証ポリシーで照合するためのカスタム式になります
THEN アクセス 認証の​成功後に​許可 許可ルールとして設定します
AND 認証方法 特定の​認証方法を​許可する
Okta Verify - FastPass
ここでは[Okta Verify - FastPass]のみを許可しましょう。
ユーザーが違うサインイン方式でアクセスすることでSystem Logにdevice.idが出力されず、アクセスできないなどの不要な問い合わせを避けるため強制します。

ルール2 (ルール1に該当しないものは拒否する [キャッチオールルール] )

項目 設定値 備考
優先度 2
IF ユーザーの​ユーザータイプ 任意のユーザータイプ
AND ユーザーの​グループメンバーシップ 任意のグループ
AND ユーザー 任意のユーザー
AND デバイスの​状態 すべて
THEN アクセス 拒否 全拒否ルールは影響が大きいため、事前検証では検証用アプリでテストするか、いったん許可設定にした上で、OktaのSystem Logから キャッチオールルールに該当しているかを確認する方法でも問題ないかと思います。


実装後の挙動

挙動パターン

パターンとしてはこんな感じになります。


・端末許可IDの登録

端末 OktaのSystem Logに表示されたデバイス情報が、社内端末管理リストの記載と一致している?

PC:シリアル番号
スマホ:[モデル]AND[表示名]
device.idがユーザープロファイルに格納されるか
PC ⭕️ ⭕️
PC
スマホ ⭕️ ⭕️
スマホ [モデル][表示名]のうち
どちらかが一致しない
スマホ

・アクセス制限

device.idがユーザープロファイルに記載されている? ユーザープロファイルに記載されたdevice.idに紐づく端末からアクセスしている? アクセス可否
⭕️ ⭕️ 可能
⭕️ 不可
不可

実際の挙動例

全部の挙動例を載せると長くなってしまうので、ここでは全部⭕️なPCでの挙動を紹介します。

💡補足
・ここでは社用端末管理リストに情報が載っているユーザーの例を掲載します。
・使用したデバイスはPC(Mac)です
・Okta VerifyをPCにインストールしていますが、まだサインインはしたことがない状態です

①社用端末管理リストに以下情報が載っています。

②Okta Verify経由で初回サインインを行うことで、Okta上にデバイス情報が登録されます。

③同時にworkatoレシピが動作し、①と②のシリアル番号が一致しているので、Oktaユーザーのプロファイル「端末許可ID」にdevice.idが格納されます。

 併せてSlackに結果が通知されます。

④この状態で、③のdevice.idに紐づくPCからOktaダッシュボードにサインインしたあと、GWSにアクセスしてみます。

⑤認証ポリシーの「AND 認証方法」のところでサインイン方式をOkta FastPassのみに限定しているので、Okta FastPassの認証画面が自動で開き、続けてOkta Verify上でTouchIDやパスコードの入力が求められます。

⑥問題なくGWSへアクセスできました。

この時、Okta FastPassでサインインしたことでOktaユーザー側のログには「device.id」が出力されています。
このdevice.idが、認証ポリシーの「AND 次の​カスタム式を​trueと​する」に記載されたカスタム式の判定にて、ユーザープロファイル「端末許可ID」の値と一致しているので、「Evaluation of sign-on policy Allow」として接続が許可されています。

なお、認証ポリシーの条件を満たさない場合は、
キャッチオールルール(拒否ルール)が適用され、
以下のような画面に遷移します。

   

運用上のポイント

社用端末管理リストの運用

新規入社、または既存メンバーに新規端末を貸与後、ユーザーがOkta VerifyにてOktaへ初回ログインする前に、そのユーザーの端末情報を入力しておく必要があります。 もし入力漏れや不備があった場合は、Workatoレシピがユーザープロファイルへのdevice.id登録を拒否してしまうので、許可したい端末のdevice.idを特定し、手動でdevice.idを入れ込む必要があります。

おまけ程度で、突貫で作成したOkta APIでデバイス情報の一覧を取得し、csvにするscriptを貼っておきます。 このcsvデータにはdevice.idも出力されているので、デバイス名などで検索することでdevice.idが特定できるかと思います。


BASE_URL="https://XXXXX.okta.com/api/v1/devices?limit=200"
TOKEN="[Oktaで発行したトークンID]"

tmpdir=$(mktemp -d)
page=1
url="$BASE_URL"

echo "[]" > "$tmpdir/all.json"

while [ -n "$url" ]; do
  echo "Fetching page $page: $url" >&2

  curl -sS -D "$tmpdir/headers.txt" \
    -H "Authorization: SSWS $TOKEN" \
    -H "Accept: application/json" \
    "$url" > "$tmpdir/body.json"

  jq -s '.[0] + .[1]' "$tmpdir/all.json" "$tmpdir/body.json" > "$tmpdir/merged.json"
  mv "$tmpdir/merged.json" "$tmpdir/all.json"

  url=$(grep -i '^link:' "$tmpdir/headers.txt" \
    | tr ',' '\n' \
    | grep -i 'rel="next"' \
    | sed -n 's/.*<\([^>]*\)>.*/\1/p')

  page=$((page+1))
done

ts=$(date +%Y%m%d_%H%M%S)

# ▼CSV化
FIELDS='[
  .id,
  .status,
  .profile.displayName,
  .profile.platform,
  .profile.model,
  .profile.serialNumber,
  .profile.udid,
  .profile.osVersion,
  .created,
  .lastUpdated
]'

HEADER='id,status,displayName,platform,model,serialNumber,udid,osVersion,created,lastUpdated'

out="./okta_devices_list_${ts}.csv"

{
  echo "$HEADER"
  jq -r ".[] | $FIELDS | @csv" "$tmpdir/all.json"
} > "$out"

echo "Done. Saved: $out"


最後に

本記事に記載した方法とは別に、 デバイスの管理証明を構成することで、デバイスを管理対象としてOktaに登録することが可能で、こちらとOktaの認証ポリシーと組み合わせて管理対象デバイスのみにアクセスを許可する方法も可能かと思います。

当社でも当初は上記方法でテナント制限することを検討していましたが、現在利用しているMDMの機能では証明書の配布および管理が難しく、断念しました。

そのため、どうやったら上記以外の方法でテナント制限が実現できるかをOktaの営業さんやエンジニアさんのサポートを受けながら色々組み合わせ、検証を重ねることで何とか実装できました。

今回はGWS/Slackのみ制限を実施しましたが、今後他Okta管理のSaaSにも制限を拡大していく予定です。

あまりこの手の記事が多くなかったため、本記事が誰かのナレッジとして少しでも役立てば幸いです。