メインコンテンツへスキップ
見出し画像

ServiceNowで「このレコードが見えない」は本当にACL拒否? Impersonate UserとSecurity Debugで実際に確かめる


    「このレコードが見えないんですが」という相談を受けたとき、原因がACLなのか、それとも画面側の表示制御なのか、口頭の説明だけで判断していないでしょうか。ServiceNowにはロール0件の一般ユーザーに実際になりすまし、拒否される瞬間をそのまま再現する機能があります。今回はZurich PDIでロールを持たないデモユーザーになりすましました。Incidentのレコードが実際に「Record not found」と表示されるところと、Security Debugでその判定過程を読むところまで実機で確認しています。

    検証環境:Zurich PDI / OOTB / 2026-08-10 確認

    結論:見え方の違いで3つの原因を見分ける

    「レコードが見えない」という相談には、実は3つの異なる原因が混ざっています。それぞれ画面の見え方がはっきり違うので、直接URL(sys_id指定)で開いたときの反応を見れば、どれに当てはまるか見当がつきます。

    • ACLで拒否: 情報バナー「Record not found」だけが表示され、フォームの本文は一切描画されません

    • View / UI Policyで絞り込み: フォーム自体は開きますが、項目数がいつもより少なくなります。レコードは読めています

    • ドメイン分離: 別ドメインのデータが最初から見えている、あるいは見えていない状態です(このPDIでは検証範囲外)


    画像

    図の色は、今回このPDIで再現できたかどうかに対応しています。赤はACL拒否で今回の主役です。緑はレコード自体は読める側、グレーは今回のPDIでは検証できなかった範囲を示します。以下、実際になりすましながら1つずつ確かめます。

    ロール0件のユーザーで、実際に拒否される画面を見る

    なりすまし対象に選んだのは abel.tuter(Abel Tuter)という既存のデモユーザーです。事前に確認したところ、このユーザーはsys_user_has_roleに該当行が0件、所属グループも0件でした。特定のロールを外して用意したユーザーではありません。もともと何も付与されていない状態のまま使っています。

    ロールの有無は/sys_user_has_role_list.do?sysparm_query=user.user_name=abel.tuterのようなURLで一覧を開けば、一目で分かります。今回は「No records to display」という空の一覧で、ロール0件を確認しました。


    画像

    対象レコードはIncidentテーブルのINC0000001です。caller(申告者)はFred Luddy、opened_by(起票者)はJoe Employeeで、Abel Tuterはどちらでもなく、watch_list(ウォッチリスト)にも入っていません。管理者としてこのレコードを開くと、当然すべての項目が見えます。


    画像

    これをAbel Tuterになりすました状態で開き直すと、結果はまったく変わります。


    画像

    フォームの枠すら出ません。項目が空欄になるわけではありません。レコードの存在そのものが「見つからない」という扱いになります。管理者として見ていたときとの落差は、実際に切り替えてみるまで文章だけでは実感しづらい部分でした。

    なりすまし(Impersonate User)はどこから行うか

    ServiceNowには、指定したユーザーとしてセッションを一時的に切り替える「Impersonate User」という機能があります。右上のアバターアイコンをクリックすると出てくるメニューの中に項目があり、管理者であれば追加のプラグインなしで使えます。


    画像

    検索欄にユーザー名や表示名を入力すると候補が絞り込まれます。対象を選んで「Impersonate user」ボタンを押すと、その場でセッションが切り替わります。


    画像

    切り替わったことは画面の見た目でも分かります。画面上部に赤い帯線が入りました。ナビゲーションバーの項目も減り、右上のアバター画像はAbel Tuterのものに変わります。この状態でどのURLを開いても、実際にAbel Tuterがログインした場合と同じ判定が動く点は変わりません。管理者権限で「見えるはず」と推測するのではなく、対象ユーザーそのものの目で確かめられるのがこの機能の強みです。

    なりすましは誰でも使えるわけではない

    Impersonate Userを使うには、対象より広い権限(多くの場合admin、またはimpersonatorロール)が必要です。今回のように一般ユーザーの見え方を確かめたいときは、管理者側で操作して一般ユーザーに切り替える、という流れになります。逆方向、つまり一般ユーザーが管理者になりすますことはできません。

    拒否の中身:どのACLが効いているのか

    Incidentテーブルのread(読み取り)を制御するACLは、sys_security_aclに6件登録されていました(name=incident^operation=read^type=recordで抽出)。中身を1件ずつ読むと、どれもロールかスクリプトによる条件で、無条件に許可するものはありませんでした。


    画像

    Abel Tuterに当てはめると、ロールを要求する3件(itil / sn_incident_read / ml_report_userまたはml_admin)はロールを1つも持たないため不合格です。opened_by・caller_id・watch_listのいずれかが自分であることを条件にするスクリプトも、このレコードでは該当しません。承認者かどうかを判定するスクリプトも、Incidentの承認とは無関係なので不合格になります。唯一合格するのは、ログイン済みかどうかだけを見るセキュリティ属性の1件です。これはなりすまし中のAbel Tuterでも満たされます。

    6件のうち1件でも合格すれば読めるはずですが、実際には「Record not found」でした。この食い違いについては、後半のSecurity Debugのところで詳しく触れます。

    admin_overridesが管理者を素通りさせる

    これら6件のACLはすべてadmin_overridesがtrueでした。つまり管理者アカウントは、この6件の条件に関係なく素通りします。管理者のまま画面を見て「これなら見えるはずだ」と判断すると、一般ユーザーの実際の見え方とズレるのは、この設定が理由です。

    裏を返すと、admin_overridesがfalseのACLも存在します。そちらでは管理者であっても、条件判定を素通りできません。「管理者なら何でも見えるはず」という前提そのものが、テーブルによっては成り立たない場合があります。

    Security Debugでルールの合否を読む

    ACLがどう評価されたかを画面で追う機能が「Debug Security Rules」です。System Diagnosticsの配下にあるモジュールで、実行すると別タブでScript Debuggerが開き、セッション内のトランザクションごとにACLの評価結果が記録されます。

    デバッガを起動する順番を間違えると使えない

    この機能には1つ注意点があります。なりすました後の状態ではデバッガを起動できません。Abel Tuterになりすんだ状態で同じ操作を試すと、「Script Debugger requires debugging privilege.」というメッセージだけが表示されました。ログ画面そのものは開きません。デバッグ用の権限そのものがロールに紐づいているためです。先に管理者のままデバッガを起動しておき、そのあとでなりすます、という順番にする必要があります。逆の順番を最初に試して、ここでいったんつまずきました。

    管理者でデバッガを起動したあと、同じタブ上でAbel Tuterになりすまし、INC0000001をもう一度開き直すと、ログにトランザクションが記録されました。


    画像

    record/incident.number/readやrecord/incident.caller_id/readといったフィールド単位の評価行の下に、候補となる6件のルールが並びます。1件ずつ緑のチェック(合格)と赤のバツ(不合格)が色分けして表示される作りです。実際の画面では、1件目のルール(Deny Unless)が合格でした。続く3件が不合格(赤)、5件目が合格(緑)、6件目は評価されずに終わる、という並びです。「なんとなく権限が足りない」という感覚で終わらせずに済みます。どのルールが通り、どのルールが弾いたのかを具体的に確認できるところが、この画面の価値です。

    自分のレコードなら見える。ただし項目は絞られる

    同じAbel Tuterのなりすまし状態で、今度は自分がcallerになっているレコードINC0010020を開くとどうなるでしょうか。ACLの条件(caller_id/opened_by/watch_listのいずれかが自分)を満たすため、こちらは読めるはずです。


    画像

    予想どおり開けました。ただし、見出しに「View: Self Service」と表示され、フォームに並ぶ項目が大きく減っています。同じレコードを管理者として開いた場合と比べると、違いは明らかです。


    画像

    Category・Subcategory・Service・Configuration item・Assignment groupなどが管理者側には並びますが、Abel Tuter側にはありません。レコード自体はACLを通っているので「見える」判定です。それでも表示される項目は、ビューによって絞り込まれています。これが冒頭の3パターンでいう「View / UI Policyで絞り込み」の実例です。

    なぜビューが自動で切り替わるのか

    ロールを持たないユーザーがIncidentを開くと、既定のビュー設定によって「Self Service」という簡易ビューが自動的に選ばれます。項目を1つずつ隠したわけではなく、そもそも表示するビューそのものが違う、という理解の方が実態に近いです。どのビューが用意されているかは/sys_ui_view_list.doの一覧で確認できます。フォーム見出しに表示される「View: ○○」の文字列と突き合わせれば、いま開いているのがどのビューかを取り違えません。ACLで拒否されたときの「Record not found」1行だけの画面と、View切り替えで項目が減るだけの画面とでは、見た目がはっきり違います。


    画像

    3つ目の「ドメイン分離」については、このPDIでは「Domain Support」プラグインが有効化されていません。sys_domainという物理テーブル自体が存在しないため、今回は再現できませんでした。ドメイン分離の仕組み自体は別記事(末尾の関連記事)で扱っています。

    実機で気づいたこと

    Security Debugを覗いて一番意外だったのは、フィールド単位のACL評価と、レコードそのものが見えるかどうかの判定が、同じ画面の中でも別の階層にあるらしいという点です。

    record/incident.number/readのログを見ると、6件のルールのうち1件は合格していて、フィールド単位の評価結果としては「読める」という判定(RC = true)になっていました。ところが実際の画面ではINC0000001は「Record not found」で、本文がまったく描画されていません。フィールドを読めるかどうかの判定が通っていても、それだけではレコードが画面に出てくることを保証しないということです。

    最初は「6件のうち1件でも合格すればレコード全体が見えるはず」と考えていたので、この食い違いには戸惑いがあります。あとから振り返ると、Security Debugのログに出てくるCONTEXT = nullという表記が引っかかっていました。特定のsys_idに紐づいた判定ではありません。フォームの項目構成を決めるための、レコードに依存しない汎用的なチェックだったのではないかと考えています。実際に「このレコードを返すかどうか」を決めている判定はクエリの絞り込み段階にあり、Security DebugのSession Logという画面だけでは追いきれませんでした。

    もう1つ意外だったのが、6件のうち唯一合格していたルールの中身です。ロールもスクリプトも使わず、「ログイン済みかどうか」というセキュリティ属性1つだけで判定していました。ロールもスクリプトも要りません。細かい制御の下に基礎的な認証チェックが別枠で置かれている構成は、公式ドキュメントを読んだだけでは気づきにくい部分でした。

    Security Debugは、ACLの中身を読むための強力な入口です。ただしそこに出てくる合否が、そのまま「画面に出る・出ない」と1対1で対応するとは限りません。個々のルールの合否を疑う道具です。最終結果を丸ごと説明してくれる道具ではない、という感触を持ちました。

    実務では何に使えるか

    「このレコードが見えない」という問い合わせを受けたとき、次の順番で確認すると手戻りが少なくなります。

    1. まず本人(またはロール構成が近いテストユーザー)になりすまし、実際に同じURLを開いて再現するかを確認します

    2. 「Record not found」1行だけならACL、項目が減っているだけならView / UI Policyと当たりを付けます

    3. ACLが疑わしい場合は、先に管理者のままSecurity Debugを起動してからなりすまし直し、どのルールで引っかかっているかを読みます

    4. 対象ユーザーが持つロール・グループをsys_user_has_roleやsys_user_grmemberで確認し、ACLが要求する条件と突き合わせます

    管理者アカウントのまま画面を確認して「見えるはずだ」と判断するのは、admin_overridesが効いてしまうため参考になりません。実際に困っているユーザーに近い権限で確かめるところが出発点です。テストユーザーを都度作らなくても、既存のデモユーザーやロール構成の近いアカウントを一時的に借りるだけで、同じ切り分けができます。問い合わせのたびに毎回この4段階を踏むのは手間に見えますが、原因の見当を口頭の推測だけでつけるよりも、結果的に早く終わることが多いという実感があります。

    なりすまし・デバッグ表示は必ず解除する

    Impersonate UserもSecurity Debugもセッション単位の設定です。作業が終わったら、デバッガのタブを閉じ、アバターメニューから「End impersonation」を選んで管理者に戻します。


    画像

    管理者ホーム画面に戻り、ヘッダーの表示も元どおりになっていることを確認しました。今回の検証ではレコードの作成・更新・削除やACL・プロパティの恒久的な変更は行っていません。なりすましとデバッグ表示もこの手順で解除しています。

    よくある質問

    Q1. なりすましたユーザーの操作は、本人の履歴に残りますか

    はい。フォームのActivitiesやログには、操作した実際のユーザー(なりすまし元)が記録される仕組みになっています。今回は読み取りだけで更新は行っていませんが、検証以外の目的で更新操作を伴うなりすましを行う場合は、この点への注意が必要です。誰が・いつ・誰になりすましたかという記録自体も監査の対象になるため、業務データを扱うインスタンスでは特に慎重な運用が求められます。

    Q2. Security Debugをオンにしたまま忘れると何が起きますか

    デバッガのタブを開いたままにしていても、それ自体で他のユーザーの操作に影響が出るわけではありません。ただしログには機微な条件式やロール名が表示されるため、タブを開いたまま放置しない方が安全です。作業後はタブを閉じ、なりすましも解除しておきます。

    Q3. なりすましできるユーザーの一覧はどこで確認できますか

    Impersonate Userのダイアログには「RECENT IMPERSONATIONS」として直近になりすました相手が表示されます。それ以外は検索欄にユーザー名や表示名を入力して探す形です。全ユーザーの一覧を出す機能ではないため、対象のuser_nameをあらかじめsys_userで確認しておくと探しやすくなります。今回の候補に「ITIL User」「Problem Coordinator A」のような役割そのものを名前にしたアカウントが出てきたのも、テスト用途を想定した名付けだと考えると納得できました。検証用のユーザーをあらかじめ役割名で用意しておく設計は、他のテーブルで同じ確認をするときにも流用できる考え方です。役職名や部署名で検索できるように命名しておくと、次に誰かが同じ確認をするときにも迷わず選べます。

    さらに詳しく知りたい人へ

    用語

    • Impersonate User … 管理者などが別のユーザーとしてセッションを一時的に切り替える機能。解除するまで対象ユーザーとして画面が動く

    • Debug Security Rules(Security Debug) … System Diagnostics配下のモジュール。ACLの評価結果をSession Logとして別タブに表示する

    • sys_security_acl … テーブル・フィールド単位の読み書き権限を定義するテーブル。operation(read/write/create等)とtype(record/field)を持つ

    • admin_overrides … ACLのフィールドの1つ。trueの場合、管理者ロールを持つユーザーはこのACLの条件に関係なく通過する

    • View(sys_ui_view) … 同じレコードでも状況によって切り替わるフォームの表示パターン。Self Serviceビューなどがある

    自分の環境で確認するときのURL

    • /now/nav/ui/home … アバターメニューからImpersonate Userを開く起点

    • /sys_security_acl_list.do?sysparm_query=name=<テーブル名>^operation=read^type=record … 対象テーブルのread ACL一覧

    • /sys_user_has_role_list.do?sysparm_query=user.user_name=<ユーザー名> … 対象ユーザーの保有ロール確認

    参考リンク

    検証環境と未検証範囲

    検証はZurich PDI(OOTB)で2026-08-10に行いました。なりすまし対象のabel.tuterは既存のデモユーザーで、パスワードの変更や新規ユーザーの作成は行っていません。レコードの作成・更新・削除、ACLやプロパティの恒久的な変更もしていません。なりすまし・Security Debugの表示はいずれもセッション単位の設定です。作業後に管理者へ戻したことを画面で確認しています。

    ドメイン分離によるデータ絞り込みは、このPDIで「Domain Support」プラグインが未有効のため再現できておらず、検証範囲外です。Security Debugの個々のルール行がどの物理ACL(sys_id)に対応するかまでは、1件ずつクリックして追う検証はしていません。ITIL User(itilロール保有)など有ロールユーザーでの許可の実機再現も、今回はcaller一致による許可の確認にとどめ、ロール一致側は行っていません。本番環境やカスタマイズ済みの環境ではACLの構成やロール名が異なります。

     
     
    ServiceNowのPDI(Personal Developer Instance)を実機で観察して、Noteに記事を書いています 実装・運用・教育の現場視点で淡々と記録中です リクエストがあればその記事も書きます 個人の観察日記です

    あなたへのおすすめ