ServiceNowのデータ操作権限を制御する仕組みであるAccess Control List(ACL)について、概要と、評価のプロセスを説明します。ACL理解しているよ!という方は、まずは理解度確認問題に挑戦してみてください。
Access Control List(ACL)とは
ACLの概要(図解)
ACLの概要を図解すると下図のようになります。
ポイントは次の通りです
- ACLルールにはTable-leveとFiele-levelがあり、両方を満たすとあるデータに対する操作が許可される
- Table-level、Field-levelそれぞれで最も具体的なルールが適用される(ルールがない場合は許可)
- 各ACLには3つの評価基準があり、全てを満たした場合にそのACLルールがパスされる
- 同じ具体度=優先度に複数のACLルールがある場合は、いずれか1つをパスすればよい
以下、各ポイントの詳細を説明していきます。
ACLの制御対象の主な操作
ACLで権限制御を行える主な操作は次の4つで、いわゆるCRUD(クラッド)に対応しています。ACLで操作を拒否された場合の動きは、Table-levelかField-levelか、リスト上で見た場合かフォーム上で見た場合かによって異なるため、下表に整理しました。
Level | Operation(操作) | 拒否された場合どうなるか? |
Table | Create(作成) | リスト上: New(新規)ボタンが表示されない フォーム上: New(新規)ボタンが表示されないため基本的にフォームも開けない |
Read(閲覧・書き込み) | リスト上: 権限の問題でレコードが閲覧できない旨のメッセージが表示される フォーム上: リスト上に表示されないため基本的にフォームも開けない | |
Write(更新・書き込み) | リスト上: 全ての項目が読み取り専用となる(Read権限があれば表示はされる) フォーム上: 全ての項目が読み取り専用となる(Read権限があれば表示はされる) | |
Delete(削除) | リスト上: 一括Delete(削除)がグレーアウトされ不可になる フォーム上: Delete(削除)ボタンが表示されない | |
Field | Create(作成) | リスト上: 特に変化無し フォーム上: 新規作成画面において当該項目が読み取り専用となる(Read権限があれば表示はされる) |
Read(閲覧・書き込み) | リスト上: 当該項目が非表示となる(その項目があったはずの場所は詰めて表示される) フォーム上: 当該項目が非表示となる(その項目があったはずの場所は詰めて表示される) | |
Write(更新・書き込み) | リスト上: 当該項目が読み取り専用となる(Read権限があれば表示はされる) フォーム上: 当該項目が読み取り専用となる(Read権限があれば表示はされる) | |
Delete(削除) | リスト上: 特に変化無し(Table-levelのDelete権限があれば削除可能) フォーム上: 特に変化無し(Table-levelのDelete権限があれば削除可能) |
なお、一般的に更新・書き込みはUpdateと表現されることが多いですが、ServiceNowではWriteです。
また、他にもACLで権限を制御できる操作はありますが、あまり使うことはないのでこの記事では説明を省略します。
Table-level ACLルールとField-level ACLルール
ACLには、テーブル全体または特定レコードに対する権限制御を行うTable-level ACLルールと、特定フィールドに対する権限制御を行うField-level ACLルールが存在します。基本的にあるデータ(あるテーブルのあるレコードのあるフィールド)に対して操作を行うためには、Table-levelとField-level両方のACLルールをパスする必要があります。
Table-level ACLルールの評価プロセス
Table-leve ACLルールが評価される際には、まずは該当テーブルの該当操作に対するACLルールが存在するかをチェックし、存在すればそのルールが適用されます。存在しない場合は、親テーブルの該当操作に対するACLルールが存在するかをチェックし、存在すればそのルールが適用されます。これを繰り返し、Base(基底)テーブルのACLまで遡ります。そして、Base(基底)テーブルまで遡っても該当操作に対するACLルールが存在しない場合は、*(全テーブル)の当該操作に対するACLルールが適用されます。
*(全テーブル)の各操作に対するACLルールは標準で用意されていて、システムプロパティ”glide.sm.default_mode”が”allow”の場合は任意のユーザが操作可能、”deny”の場合はadminロールを持つユーザのみが操作可能という設定になっています。
Field-leve ACLルールの評価プロセス
Field-level ACLルールについても、Table-level ACLと同じようなプロセスで評価されますが、もう少し複雑です。まずは当該テーブルの当該フィールドの当該操作に対するACLルールが存在するかをチェックし、存在すればそのルールが適用されます。存在しない場合は、親テーブルの当該フィールドの当該操作に対するACLルールをチェックします。同様にして*(全テーブル)の当該フィールドの当該操作に対するACLルールまで遡ります。それでも存在しない場合は、次に当該テーブルの*(全フィールド)の当該操作に対するACLルールが存在するかをチェックします。その後、親テーブル、親の親テーブル、…*(全テーブル)の*(全フィールド)の当該操作に対するACLルールまで遡ります。
そして、*(全テーブル)の*(全フィールド)まで遡ってもACLルールが存在しない場合は、その操作は許可されます。
理解が曖昧になりやすいポイントとしては、当該テーブルの*(全フィールド)に対するACLと、親テーブルの当該フィールドに対するACLのどちらが優先されるか、という部分でしょう。答えは後者です。
全フィールドレベルはカスタムテーブルなどでは設定しなければ存在しません。*(全フィールド)の当該操作に対するACLルールが存在しない場合は、その操作は許可されます。
各ACLルールをパスするための条件
1つ1つのACLルールには、3つの評価基準が存在します。全てを満たした場合のみそのACLルールをパスできます。なお、Script(スクリプト)はAdvanced項目にチェックが入っている場合のみ評価されます。
各評価基準を満たす条件は下表の通りです。
評価基準 | 評価順序 | 条件 |
Role(ロール) | 1番目 | 設定されているいずれかのロールを持っている |
Condition(条件) | 2番目 | 設定されている条件を満たしている |
Script(スクリプト) | 3番目 | スクリプトにおいて最後に評価された文、もしくはanswer変数がtrueである なお、最後に評価された文とanswer変数の値が異なる場合は、answer変数が優先となります。また、true/falseをreturnする必要はありません。(returnすることで、結果的に最後に評価された文となりますが) |
同じ具体度=優先度に複数のACLルールが存在する場合は、いずれか1つを通ればよい
Table-levelもField-levelも、同じ具体度=優先度に複数のACLルールが存在する場合は、いずれか1つをパスすればOKです。
ACLの設定方法
前提: Elevate role(ロールの昇格)
まず前提として、ACLを設定するためには、security_adminロールへの昇格が必要です。
ロールの昇格についてはこちらの記事で説明しているので、併せて参照ください。
Table-level, Field-level ACLの設定方法
ACLの設定は、Table-levelでもField-leveでも同じように行います。
- メニュー > System Security > Access Control (ACL)よりACLルールのリストを開く
- New(新規)ボタンよりACLルールの設定フォームを開く
- 設定を行い、”Submit”を押下する
画面に従い設定を行います。
最も重要で、かつ難しいName(名前)項目について補足しておきます。Nameには制御対象オブジェクトを<制御対象テーブル>.<制御対象フィールド>の形式で指定します。<制御対象フィールド>の部分を”None”にするとTable-level ACLとなり、何かを設定するとField-level ACLとなります。よく使う具体例を下表に示します。
制御対象オブジェクト | nameの設定 |
Aテーブル | a_table |
全テーブル | * |
AテーブルのXフィールド | a_table.x_field |
Aテーブルの全項目 | a_table.* |
また、”Admin overrides”項目にチェックを入れると、adminロールを持つユーザは当該ACLをバイパス、つまりACLの評価基準を満たさずとも無条件でそのACLルールをパスするようになります。
Table-level ACLを用いて特定のレコード(行)レベルで権限制御を行う方法
Table-level ACLは設定方法によって、テーブル全体に対する制御だけでなく、特定のレコード(行)レベルでの制御を行うこともできます。
特定のレコード(行)レベルで制御を行う場合は、下図のようにConditionやScriptを用いて、特定のフィールドを絡めた条件を設定します。
理解度確認問題
ACLは完璧に理解するのがとても難しいので、最後に理解度確認問題を載せておきます。
問題
前提条件
- テーブルAと、テーブルAを継承(拡張)したテーブルBが存在する
- テーブルAとテーブルBはフィールドX、フィールドYを持つ
- テーブルAとテーブルBに対して設定されているACLは下表で全てとする
No | 対象オブジェクト | 操作 |
1 | テーブルA | Read |
2 | テーブルA.* | Read |
3 | テーブルA.フィールドX | Read |
4 | テーブルB.* | Read |
問題
- テーブルAのフィールドXを読み取るためにパスすべきACLはどれ?
- テーブルAのフィールドYを読み取るためにパスすべきACLはどれ?
- テーブルBのフィールドXを読み取るためにパスすべきACLはどれ?
- テーブルBのフィールドYを読み取るためにパスすべきACLはどれ?
解説
間違えたものがあった場合は、この記事の該当箇所を読み返してみてください。
- No1, No3
Table-level ACLルールとしてNo1が、Field-level ACLルールとしてNo3が適用されます。同じテーブルAのField-leve ACLルールの中でもNo2よりNo3の方がより具体的=優先度が高いため、No2は適用されません。 - No1, No2
Table-level ACLルールとしてNo1が、Field-level ACLルールとしてNo2が適用されます。テーブルAのフィールドYに対するACLルールが存在しないため、テーブルAの全フィールドに対するACLルールであるNo2が適用されます。 - No1, No3
Table-level ACLルールとしてNo1が、Field-level ACLルールとしてNo3が適用されます。テーブルBに対するACLルールが存在しないため、親テーブルのテーブルAに対するACLルールであるNo1が適用されます。また、テーブルBのフィールドXに対するACLルールが存在しない場合、テーブルBの全フィールドに対するACLルールではなく、テーブルAのフィールドXに対するACLルールの方が優先されます。 - No1, No4
Table-level ACLルールとしてNo1が、Field-level ACLルールとしてNo4が適用されます。テーブルAのフィールドXに対するACLルールが存在しないため、テーブルBの全フィールドが適用されます。
以上です。全て正解できたでしょうか。
ACL設計ノウハウ
ACL設計に関するノウハウは次の記事にまとめました。
コメント