acl-management について
ServiceNow の管理者やセキュリティ担当者向けに、ACL の確認、作成、変更、トラブルシューティングの手順を示します。テーブル、フィールド、レコード単位のアクセス制御に加え、ロール要件とデバッグ方法を扱います。
主な機能
- 01ACL とロール要件の検索
- 02テーブル・フィールド・レコード単位の ACL 作成
- 03既存 ACL の安全な変更
- 04ユーザー権限問題の調査
- 05ACL 評価と競合の分析
- 06リスクのあるロール組み合わせの確認
活用シーン
- 01新しいテーブルやアプリのアクセス制御設定
- 02ユーザーのアクセス拒否問題の調査
- 03フィールド単位または行単位の権限設定
- 04既存の権限と ACL 設定のレビュー
MCP 対応
ServiceNow の MCP ツールで ACL を検索し、ルールやロールを作成・更新して、デバッグ用スクリプトを実行します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ happy-technologies-llc/ happy-platform-skills --skill acl-managementインストール後、Claude Code で/acl-managementを入力して読み込まれたか確認します。
詳細
ACL 管理
概要
アクセス制御リスト(ACL)は、ServiceNow のセキュリティの基盤です。このスキルでは、次の内容を扱います。
- ACL の構造と継承階層の理解
- テーブル、フィールド、レコードに対する新しい ACL の作成
- 既存の ACL ルールの安全な変更
- 権限に関する問題のトラブルシューティング
- ACL のデバッグ手法とツール
- ロールベースのアクセス制御に関するベストプラクティス
次のような場合に使用します:
- 新しいテーブルやアプリケーションのセキュリティを設定する場合
- 「アクセスが拒否されました」という問題のトラブルシューティングを行う場合
- フィールドレベルのセキュリティを実装する場合
- 既存の権限を監査・確認する場合
- 行レベルのセキュリティ(クエリ条件)を実装する場合
前提条件
- ロール:
security_adminまたはadmin - アクセス: sys_security_acl、sys_security_acl_role テーブル
- 知識: ServiceNow のロールとユーザーグループに関する理解
- プラグイン: コアプラットフォーム(ACL は組み込み機能です)
ACL の基礎
ACL の階層
┌─────────────────┐
│ Table ACL (*) │ ← Broadest
│ incident.* │
└────────┬────────┘
│
┌────────▼────────┐
│ Table.Field │ ← Field-specific
│ incident.state │
└────────┬────────┘
│
┌────────▼────────┐
│ Table.None │ ← Row-level
│ (with script) │
└─────────────────┘ ← Most specific
ACL の操作
| 操作 | 目的 | 一般的な用途 |
|---|---|---|
read | レコード/フィールドの表示 | リスト、フォームの表示 |
write | レコード/フィールドの変更 | フォームの編集 |
create | 新しいレコードの挿入 | 新規レコードの作成 |
delete | レコードの削除 | レコードの削除 |
execute | スクリプト/アクションの実行 | UI アクション、プロセッサー |
ACL の評価順序
- 最も具体的なものが優先されます: フィールド ACL > テーブル ACL
- 最初に一致したものが適用されます: 一致する最初の ACL で評価が終了します
- デフォルトでは拒否されます: 一致する ACL がない場合、アクセスは拒否されます
- admin によるバイパス: admin ロールはほとんどの ACL をバイパスします
手順
フェーズ 1:既存の ACL を理解する
1.1 テーブルの ACL を検索する
特定のテーブルのすべての ACL を検索します:
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl
query: nameLIKEincident
fields: name,operation,type,condition,script,active
limit: 50
操作タイプ別に ACL を検索します:
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl
query: name=incident^operation=write
fields: name,operation,admin_overrides,condition,script,active
limit: 20
1.2 ACL の構造を確認する
ACL テーブルのスキーマを取得します:
Tool: SN-Get-Table-Schema
Parameters:
table_name: sys_security_acl
主な ACL フィールド:
| フィールド | タイプ | 目的 |
|---|---|---|
name | 文字列 | Table.field または Table.* |
operation | 選択肢 | read、write、create、delete、execute |
type | 選択肢 | record、client_callable_script_include |
condition | 条件 | 行レベルのセキュリティ用のフィルター条件 |
script | スクリプト | 高度な条件ロジック |
admin_overrides | ブール値 | admin によるバイパスを許可 |
active | ブール値 | ACL が適用されます |
advanced | ブール値 | スクリプト条件を使用します |
1.3 ACL に必要なロールを確認する
ACL に必要なロールを検索します:
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl_role
query: acl.name=incident.*^acl.operation=write
fields: acl.name,acl.operation,role.name
limit: 20
フェーズ 2:新しい ACL を作成する
2.1 テーブルレベルの ACL を作成する
カスタムテーブル用の読み取り ACL を作成します:
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl
data:
name: "u_custom_table.*"
operation: read
type: record
admin_overrides: true
active: true
description: "Read access to custom table"
ロール要件を追加します:
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl_role
data:
acl: [acl_sys_id]
role: [role_sys_id]
2.2 フィールドレベルの ACL を作成する
機密フィールドを保護します:
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl
data:
name: "u_custom_table.ssn_number"
operation: read
type: record
admin_overrides: true
active: true
description: "Restrict SSN field to authorized users only"
複数のロール要件を追加します:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_role
query: nameINhr_admin,security_admin
fields: sys_id,name
limit: 10
各ロールについて、次を実行します:
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl_role
data:
acl: [field_acl_sys_id]
role: [hr_admin_role_sys_id]
2.3 行レベルの ACL を作成する(条件ベース)
ユーザーが自分のレコードのみを表示できるようにします:
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl
data:
name: "u_custom_table"
operation: read
type: record
condition: "opened_by=javascript:gs.getUserID()"
admin_overrides: true
active: true
description: "Users can only read their own records"
2.4 スクリプトベースの ACL を作成する
スクリプトが必要な複雑なロジック:
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl
data:
name: "u_custom_table"
operation: write
type: record
advanced: true
script: |
// Allow write if user is the owner OR is in the assigned group
var userId = gs.getUserID();
var userGroups = gs.getUser().getMyGroups();
if (current.owner == userId) {
answer = true;
} else if (userGroups.indexOf(current.assignment_group.toString()) >= 0) {
answer = true;
} else {
answer = false;
}
admin_overrides: true
active: true
description: "Allow write for owner or group members"
フェーズ 3:ACL を安全に変更する
3.1 大幅な変更の前に無効化する
ACL を一時的に無効化します:
Tool: SN-Update-Record
Parameters:
table_name: sys_security_acl
sys_id: [acl_sys_id]
data:
active: false
変更を行います:
Tool: SN-Update-Record
Parameters:
table_name: sys_security_acl
sys_id: [acl_sys_id]
data:
condition: "state!=6^ORassigned_to=javascript:gs.getUserID()"
description: "Updated condition - users can access non-closed or own records"
テスト後に再度有効化します:
Tool: SN-Update-Record
Parameters:
table_name: sys_security_acl
sys_id: [acl_sys_id]
data:
active: true
3.2 ロール要件を追加/削除する
新しいロール要件を追加します:
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl_role
data:
acl: [acl_sys_id]
role: [new_role_sys_id]
ロール要件を削除します:
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl_role
query: acl=[acl_sys_id]^role=[role_sys_id]
fields: sys_id
# Then delete the record using SN-Update-Record or background script
フェーズ 4:権限に関する問題のトラブルシューティング
4.1 アクセスを妨げている ACL を特定する
ACL デバッグを有効にします(セッション単位):
Tool: SN-Execute-Background-Script
Parameters:
script: |
// This enables debug output for the session
// Run manually: Navigate to User menu > Impersonate > Check security
gs.info('To debug ACLs:');
gs.info('1. Navigate to System Security > Debugging');
gs.info('2. Or add ?sysparm_security_debug=true to URL');
gs.info('3. Or impersonate user and check security diagnostics');
description: "ACL debugging instructions"
ユーザーのロールを確認します:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_has_role
query: user=[user_sys_id]^role.name!=snc_internal
fields: role.name,granted_by,inherited
limit: 50
ユーザーのグループを確認します:
Tool: SN-Query-Table
Parameters:
table_name: sys_user_grmember
query: user=[user_sys_id]
fields: group.name,group.sys_id
limit: 50
4.2 ACL の評価を追跡する
どの ACL が適用されるかを確認します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var table = 'incident';
var operation = 'write';
var fieldName = 'state'; // or '*' for table-level
var acl = new GlideRecord('sys_security_acl');
acl.addQuery('name', 'CONTAINS', table);
acl.addQuery('operation', operation);
acl.addQuery('active', true);
acl.orderBy('name');
acl.query();
gs.info('ACLs for ' + table + '.' + fieldName + ' (' + operation + '):');
while (acl.next()) {
var roles = [];
var roleGr = new GlideRecord('sys_security_acl_role');
roleGr.addQuery('acl', acl.sys_id);
roleGr.query();
while (roleGr.next()) {
roles.push(roleGr.role.name.toString());
}
gs.info(acl.name + ' - Roles: [' + roles.join(', ') + '] - Condition: ' + acl.condition);
}
description: "Trace ACL evaluation for table/operation"
4.3 ユーザーのアクセスをテストする
ユーザーが必要なロールを持っているか確認します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var userId = '[user_sys_id]';
var requiredRoles = ['itil', 'incident_manager'];
var user = new GlideRecord('sys_user');
user.get(userId);
gs.info('Checking roles for: ' + user.user_name);
for (var i = 0; i < requiredRoles.length; i++) {
var hasRole = new GlideRecord('sys_user_has_role');
hasRole.addQuery('user', userId);
hasRole.addQuery('role.name', requiredRoles[i]);
hasRole.query();
if (hasRole.hasNext()) {
gs.info(' HAS: ' + requiredRoles[i]);
} else {
gs.warn(' MISSING: ' + requiredRoles[i]);
}
}
description: "Check user role membership"
4.4 よくある権限の問題
問題:ユーザーはテーブルを表示できますが、特定のレコードを表示できません
# Check for row-level ACL conditions
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl
query: name=[table_name]^operation=read^conditionISNOTEMPTY
fields: name,condition,script
問題:ユーザーは読み取りできますが、書き込みできません
# Compare read vs write ACLs
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl
query: nameLIKE[table_name]^operationINread,write
fields: name,operation,condition
limit: 20
問題:フィールドが予期せず読み取り専用になります
# Check field-level ACLs
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl
query: name=[table_name].[field_name]^operation=write
fields: name,operation,condition,active
フェーズ 5:ACL デバッグツール
5.1 セキュリティ診断ツール
レコードのセキュリティ診断を実行します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var table = 'incident';
var sysId = '[record_sys_id]';
var userId = '[user_sys_id]';
// Impersonate and check access
var gr = new GlideRecord(table);
gr.get(sysId);
var canRead = gr.canRead();
var canWrite = gr.canWrite();
var canDelete = gr.canDelete();
gs.info('Security Diagnostic for ' + table + '/' + sysId);
gs.info(' Can Read: ' + canRead);
gs.info(' Can Write: ' + canWrite);
gs.info(' Can Delete: ' + canDelete);
// Check field-level access
var elements = ['state', 'priority', 'assigned_to'];
for (var i = 0; i < elements.length; i++) {
var field = elements[i];
gs.info(' Field ' + field + ' - canRead: ' + gr[field].canRead() +
', canWrite: ' + gr[field].canWrite());
}
description: "Run security diagnostic on record"
5.2 ACL ルールアナライザー
競合するすべての ACL を分析します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var table = 'incident';
var analysis = {
table_acls: [],
field_acls: [],
potential_conflicts: []
};
var acl = new GlideRecord('sys_security_acl');
acl.addQuery('name', 'STARTSWITH', table);
acl.addQuery('active', true);
acl.orderBy('name');
acl.query();
while (acl.next()) {
var aclInfo = {
name: acl.name.toString(),
operation: acl.operation.toString(),
has_condition: acl.condition.toString() !== '',
has_script: acl.advanced.toString() === 'true'
};
if (acl.name.toString().indexOf('.') === -1 ||
acl.name.toString().endsWith('.*')) {
analysis.table_acls.push(aclInfo);
} else {
analysis.field_acls.push(aclInfo);
}
}
// Check for potential issues
if (analysis.table_acls.length === 0) {
analysis.potential_conflicts.push('No table-level ACLs - may be too open or rely on inheritance');
}
gs.info('ACL Analysis for ' + table + ':\n' + JSON.stringify(analysis, null, 2));
description: "Analyze ACLs for conflicts and issues"
5.3 ロール昇格の確認
危険なロールの組み合わせを持つ可能性のあるユーザーを検索します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var dangerousCombos = [
['admin', 'maint'],
['security_admin', 'personalize_dictionary'],
['admin', 'soap']
];
var findings = [];
for (var i = 0; i < dangerousCombos.length; i++) {
var combo = dangerousCombos[i];
var users = new GlideRecord('sys_user');
users.addQuery('active', true);
users.query();
while (users.next()) {
var hasAll = true;
for (var j = 0; j < combo.length; j++) {
var roleCheck = new GlideRecord('sys_user_has_role');
roleCheck.addQuery('user', users.sys_id);
roleCheck.addQuery('role.name', combo[j]);
roleCheck.query();
if (!roleCheck.hasNext()) {
hasAll = false;
break;
}
}
if (hasAll) {
findings.push({
user: users.user_name.toString(),
roles: combo
});
}
}
}
if (findings.length > 0) {
gs.warn('Users with dangerous role combinations:');
gs.info(JSON.stringify(findings, null, 2));
} else {
gs.info('No dangerous role combinations found');
}
description: "Find users with dangerous role combinations"
ベストプラクティス
設計原則
- 最小権限の原則: 必要最小限のアクセス権を付与します
- ロールベースのアクセス: 個々のユーザーではなく、ロールを使用します
- 可能な場合は継承: テーブルレベルのACLを基準として使用します
- すべてを文書化: すべてのACLに説明を追加します
- 十分にテスト: 複数のユーザーロールで確認します
よくあるパターン
パターン 1:所有者とグループによるアクセス
// Condition for owner or group member access
opened_by=javascript:gs.getUserID()^ORassignment_group.memberSOME=javascript:gs.getUserID()
パターン 2:階層型アクセス
// Managers can see their team's records
var mgr = new GlideRecord('sys_user');
mgr.addQuery('manager', gs.getUserID());
mgr.query();
var users = [gs.getUserID()];
while (mgr.next()) users.push(mgr.sys_id.toString());
answer = gs.getUser().getID() in users.join(',').split(',');
パターン 3:時間ベースのアクセス
// Only allow access during business hours
var now = new GlideDateTime();
var hour = now.getLocalTime().getHourOfDay();
answer = (hour >= 8 && hour < 18);
ツールの使用方法の概要
| 操作 | MCP ツール | REST エンドポイント |
|---|---|---|
| ACL のクエリ | SN-Query-Table | GET /sys_security_acl |
| ACL の作成 | SN-Create-Record | POST /sys_security_acl |
| ACL の更新 | SN-Update-Record | PATCH /sys_security_acl |
| ロールの追加 | SN-Create-Record | POST /sys_security_acl_role |
| ACL のデバッグ | SN-Execute-Background-Script | Via sys_trigger |
| スキーマの確認 | SN-Get-Table-Schema | GET /sys_dictionary |
トラブルシューティング
ACL が評価されない
症状: ACL を変更しても効果がありません 原因: ACL キャッシュがクリアされていないか、ACL が非アクティブです 解決策:
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Clear ACL cache
GlideAccessControl.reset();
gs.info('ACL cache cleared');
description: "Clear ACL cache"
管理者がレコードにアクセスできない
症状: 管理者ロールがレコードへのアクセスを拒否されます 原因: ACL の admin_overrides=false が設定されています 解決策:
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl
query: name=[table]^admin_overrides=false
fields: name,operation,admin_overrides
スクリプト ACL が常に失敗する
症状: スクリプトベースの ACL がアクセスを許可しません 原因: スクリプトエラーまたは answer 変数が正しくありません 解決策:
- スクリプトで
answer = trueまたはanswer = falseが設定されていることを確認します - syslog でスクリプトエラーを確認します
advanced = trueが設定されていることを確認します
ロールでアクセスが許可されない
症状: ユーザーがロールを持っていてもアクセスを拒否されます 原因: ACL が複数のロールを要求している(AND)か、条件を満たしていません 解決策:
Tool: SN-Query-Table
Parameters:
table_name: sys_security_acl_role
query: acl=[acl_sys_id]
fields: role.name
デフォルトでは、一覧にあるすべてのロールが必要です(AND ロジック)。
例
例 1:カスタムテーブルを保護する
# Step 1: Create table-level read ACL
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl
data:
name: "u_employee_data.*"
operation: read
type: record
admin_overrides: true
active: true
description: "Base read access to employee data"
# Step 2: Add role requirement
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl_role
data:
acl: [step1_sys_id]
role: [hr_user_role_sys_id]
# Step 3: Create write ACL (more restrictive)
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl
data:
name: "u_employee_data.*"
operation: write
type: record
admin_overrides: true
active: true
description: "Write access to employee data - HR admins only"
# Step 4: Add admin role requirement
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl_role
data:
acl: [step3_sys_id]
role: [hr_admin_role_sys_id]
例 2:フィールドレベルで SSN を保護する
# Protect SSN field - only security cleared users
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl
data:
name: "u_employee_data.ssn"
operation: read
type: record
admin_overrides: false
active: true
description: "SSN access restricted - security clearance required"
# Add special role
Tool: SN-Create-Record
Parameters:
table_name: sys_security_acl_role
data:
acl: [ssn_acl_sys_id]
role: [security_cleared_role_sys_id]
関連スキル
security/audit-compliance- ACL の変更を監査するsecurity/incident-response- アクセス違反に対応するsecurity/data-classification- 保護が必要な対象を特定するadmin/user-provisioning- ユーザーロールを管理する