audit-compliance について
ServiceNow 管理者やセキュリティチーム向けのスキルです。監査データの検索、ユーザー活動の調査、コンプライアンスレポート作成、異常検知の手順を、テーブルや MCP ツールの例とともに紹介します。
主な機能
- 01監査・削除レコードの検索
- 02ユーザーとセッション活動の追跡
- 03コンプライアンスレポートの手順
- 04異常や権限変更の検知
- 05監査ダッシュボードとアラートの指針
活用シーン
- 01SOX、HIPAA、PCI-DSS の統制確認
- 02不審なアカウント活動の調査
- 03ロールやアクセスルール変更の追跡
MCP 対応
SN-Query-Table や SN-Execute-Background-Script などの ServiceNow MCP ツールを使い、監査データの確認、レポート作成、アラート作成を行う方法を説明します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ happy-technologies-llc/ happy-platform-skills --skill audit-complianceインストール後、Claude Code で/audit-complianceを入力して読み込まれたか確認します。
詳細
監査とコンプライアンス
概要
このスキルでは、ServiceNow の包括的な監査およびコンプライアンス機能について説明します。
- sys_audit テーブルをクエリして、構成やデータの変更を確認する
- プラットフォーム全体でユーザーのアクティビティを追跡する
- 規制要件に対応するコンプライアンスレポートを生成する
- セキュリティ上の脅威を示す異常なパターンを検出する
- 監査ダッシュボードとアラートを構築する
使用する場面:
- 定期的なコンプライアンス監査(SOX、HIPAA、PCI-DSS、GDPR)
- セキュリティ調査
- ユーザーアクティビティのフォレンジック調査
- 変更の追跡と説明責任
- 異常の検出とアラート
前提条件
- ロール:
security_admin、audit_admin、またはadmin - アクセス権: sys_audit、syslog、sys_audit_delete テーブル
- 知識: 組織に適用されるコンプライアンスフレームワークの理解
- 関連スキル: 検出された異常への対応については
security/incident-response
主な監査テーブル
| テーブル | 用途 | 保持期間 |
|---|---|---|
sys_audit | フィールドレベルでの変更追跡 | 設定可能 |
sys_audit_delete | 削除されたレコードの追跡 | 設定可能 |
syslog | システムおよびスクリプトのログ記録 | 7~90 日 |
sysevent | システムイベントとトリガー | 設定可能 |
syslog_transaction | トランザクションレベルのログ記録 | 7 日 |
手順
フェーズ 1:監査証跡のクエリ
1.1 重要なテーブルへの最近の変更をクエリする
ユーザーアカウントへの変更を特定する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: tablename=sys_user^sys_created_onONLast 24 hours
fields: documentkey,fieldname,oldvalue,newvalue,user,sys_created_on
limit: 200
ロールの割り当てを追跡する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: tablename=sys_user_has_role^sys_created_onONLast 7 days
fields: documentkey,fieldname,oldvalue,newvalue,user,sys_created_on
limit: 100
ACL の変更を監視する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: tablename=sys_security_acl^sys_created_onONLast 30 days
fields: documentkey,fieldname,oldvalue,newvalue,user,sys_created_on
limit: 100
1.2 エンコードされた監査クエリ
エンコードされたクエリを使用する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: tablename=sys_user^fieldnameINuser_name,roles,active,locked_out^newvalueLIKEadmin^sys_created_on>=javascript:gs.daysAgoStart(7)^NQtablename=sys_user^fieldnameINuser_name,roles,active,locked_out^oldvalueLIKEadmin^sys_created_on>=javascript:gs.daysAgoStart(7)
limit: 50
パスワードの変更を検索する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: fieldnameLIKEpassword^sys_created_on>=javascript:gs.hoursAgo(24)
limit: 100
フェーズ 2:ユーザーアクティビティの追跡
2.1 ログインアクティビティの分析
ログインイベントをクエリする:
Tool: SN-Query-Table
Parameters:
table_name: syslog
query: messageLIKElogin^sys_created_onONLast 24 hours
fields: level,message,source,sys_created_on
limit: 500
ログイン失敗の試行:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: tablename=sys_user^fieldname=failed_attempts^sys_created_onONLast 24 hours
fields: documentkey,oldvalue,newvalue,user,sys_created_on
limit: 100
2.2 ユーザーセッションの分析
アクティブなセッションをクエリする:
Tool: SN-Query-Table
Parameters:
table_name: v_user_session
query: statusISNOTEMPTY
fields: user,status,last_activity,client_ip,browser
limit: 100
同時セッションを特定する(アカウント共有の可能性):
Tool: SN-Execute-Background-Script
Parameters:
script: |
var users = {};
var gr = new GlideRecord('v_user_session');
gr.addQuery('status', 'active');
gr.query();
while (gr.next()) {
var userId = gr.user.toString();
if (!users[userId]) users[userId] = [];
users[userId].push({
ip: gr.client_ip.toString(),
browser: gr.browser.toString()
});
}
for (var uid in users) {
if (users[uid].length > 1) {
var userGr = new GlideRecord('sys_user');
userGr.get(uid);
gs.info('CONCURRENT SESSIONS: ' + userGr.user_name +
' has ' + users[uid].length + ' active sessions from: ' +
JSON.stringify(users[uid]));
}
}
description: "Audit: Identify users with concurrent sessions"
2.3 特権ユーザーの監視
管理者ユーザーのアクティビティを追跡する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: userLIKEadmin^sys_created_onONLast 7 days^tablenameNOT INsyslog,sys_cache,sys_email
fields: tablename,fieldname,oldvalue,newvalue,user,sys_created_on
limit: 500
なりすましの利用を監視する:
Tool: SN-Query-Table
Parameters:
table_name: syslog
query: messageLIKEimpersonat^sys_created_onONLast 30 days
fields: level,message,source,sys_created_on
limit: 100
フェーズ 3:コンプライアンスレポートの生成
3.1 SOX コンプライアンスレポート
ユーザーアクセスレビューのデータを生成する:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var report = [];
// Get all active users with sensitive roles
var sensitiveRoles = ['admin', 'security_admin', 'itil', 'catalog_admin'];
var userRoles = new GlideRecord('sys_user_has_role');
userRoles.addQuery('role.name', 'IN', sensitiveRoles.join(','));
userRoles.addQuery('user.active', true);
userRoles.orderBy('user');
userRoles.query();
while (userRoles.next()) {
report.push({
user_name: userRoles.user.user_name.toString(),
user_email: userRoles.user.email.toString(),
role: userRoles.role.name.toString(),
granted_date: userRoles.sys_created_on.toString(),
granted_by: userRoles.sys_created_by.toString(),
last_login: userRoles.user.last_login_time.toString(),
manager: userRoles.user.manager.name.toString()
});
}
gs.info('SOX User Access Report: ' + JSON.stringify(report, null, 2));
description: "Compliance: Generate SOX user access report"
3.2 データアクセス監査レポート
機密テーブルへのアクセスを追跡する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: tablenameINsys_user,customer_account,hr_core_profile,ast_license^sys_created_onONLast 30 days
fields: tablename,documentkey,fieldname,user,sys_created_on
limit: 1000
3.3 構成変更レポート
構成変更の概要を生成する:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var configTables = [
'sys_script', 'sys_script_include', 'sys_ui_policy',
'sys_ui_action', 'sys_security_acl', 'sys_properties',
'sys_scheduled_job', 'wf_workflow', 'wf_activity'
];
var changes = {};
var audit = new GlideRecord('sys_audit');
audit.addQuery('tablename', 'IN', configTables.join(','));
audit.addQuery('sys_created_on', '>=', gs.daysAgo(30));
audit.query();
while (audit.next()) {
var table = audit.tablename.toString();
if (!changes[table]) changes[table] = { insert: 0, update: 0, delete: 0 };
if (audit.reason.toString().indexOf('INSERT') >= 0) changes[table].insert++;
else if (audit.reason.toString().indexOf('DELETE') >= 0) changes[table].delete++;
else changes[table].update++;
}
gs.info('CONFIGURATION CHANGE REPORT (Last 30 Days):');
for (var tbl in changes) {
gs.info(tbl + ': ' + JSON.stringify(changes[tbl]));
}
description: "Compliance: Generate configuration change report"
フェーズ 4:異常検出パターン
4.1 ブルートフォース攻撃の検出
ブルートフォース攻撃の可能性を特定する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: tablename=sys_user^fieldname=failed_attempts^newvalueGT3^sys_created_onONLast 1 hours
fields: documentkey,oldvalue,newvalue,user,sys_created_on
limit: 50
ブルートフォース攻撃パターンのアラートを作成する:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var threshold = 5;
var timeWindow = 3600000; // 1 hour in ms
var now = new GlideDateTime();
var hourAgo = new GlideDateTime();
hourAgo.subtract(timeWindow);
var audit = new GlideRecord('sys_audit');
audit.addQuery('tablename', 'sys_user');
audit.addQuery('fieldname', 'failed_attempts');
audit.addQuery('sys_created_on', '>=', hourAgo);
audit.orderBy('documentkey');
audit.query();
var userAttempts = {};
while (audit.next()) {
var userId = audit.documentkey.toString();
var newVal = parseInt(audit.newvalue.toString()) || 0;
if (newVal > threshold) {
userAttempts[userId] = newVal;
}
}
// Create security incidents for each
for (var uid in userAttempts) {
var userGr = new GlideRecord('sys_user');
userGr.get(uid);
gs.warn('ANOMALY DETECTED: Brute force attempt on user: ' +
userGr.user_name + ' (' + userAttempts[uid] + ' failed attempts)');
// Optional: Create security incident
// var si = new GlideRecord('sn_si_incident');
// si.initialize();
// si.short_description = 'Potential brute force attack: ' + userGr.user_name;
// si.insert();
}
description: "Anomaly: Detect brute force login attempts"
4.2 時間外アクティビティの検出
営業時間外の管理者アクティビティを検索する:
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Business hours: 8 AM - 6 PM, Monday-Friday
var businessStart = 8;
var businessEnd = 18;
var audit = new GlideRecord('sys_audit');
audit.addQuery('sys_created_on', '>=', gs.daysAgo(7));
audit.addEncodedQuery('userLIKEadmin^ORuserLIKEsystem');
audit.query();
var offHoursActivity = [];
while (audit.next()) {
var created = new GlideDateTime(audit.sys_created_on.toString());
var hour = created.getLocalTime().getHourOfDay();
var dayOfWeek = created.getDayOfWeek();
// Check if outside business hours (1=Sunday, 7=Saturday)
if (dayOfWeek == 1 || dayOfWeek == 7 || hour < businessStart || hour >= businessEnd) {
offHoursActivity.push({
user: audit.user.toString(),
table: audit.tablename.toString(),
field: audit.fieldname.toString(),
time: created.toString()
});
}
}
if (offHoursActivity.length > 0) {
gs.warn('OFF-HOURS ACTIVITY DETECTED: ' + offHoursActivity.length + ' actions');
gs.info(JSON.stringify(offHoursActivity.slice(0, 20), null, 2));
}
description: "Anomaly: Detect off-hours admin activity"
4.3 大量データアクセスの検出
通常とは異なるデータアクセスパターンを特定する:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var threshold = 100; // More than 100 records accessed in 10 minutes
var sensitiveTables = ['sys_user', 'customer_account', 'hr_core_profile', 'ast_contract'];
var audit = new GlideRecord('sys_audit');
audit.addQuery('tablename', 'IN', sensitiveTables.join(','));
audit.addQuery('sys_created_on', '>=', gs.minutesAgo(10));
audit.query();
var userAccess = {};
while (audit.next()) {
var user = audit.user.toString();
var table = audit.tablename.toString();
var key = user + '::' + table;
if (!userAccess[key]) userAccess[key] = { user: user, table: table, count: 0 };
userAccess[key].count++;
}
for (var k in userAccess) {
if (userAccess[k].count > threshold) {
gs.warn('BULK ACCESS DETECTED: ' + userAccess[k].user +
' accessed ' + userAccess[k].count + ' records in ' +
userAccess[k].table);
}
}
description: "Anomaly: Detect bulk data access patterns"
4.4 権限昇格の検出
不正なロール変更を監視する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: tablename=sys_user_has_role^sys_created_onONLast 24 hours
fields: documentkey,oldvalue,newvalue,user,reason,sys_created_on
limit: 100
機密性の高いロールの付与をアラートする:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var sensitiveRoles = ['admin', 'security_admin', 'maint', 'personalize_dictionary'];
var audit = new GlideRecord('sys_audit');
audit.addQuery('tablename', 'sys_user_has_role');
audit.addQuery('reason', 'LIKE', 'INSERT');
audit.addQuery('sys_created_on', '>=', gs.daysAgo(1));
audit.query();
while (audit.next()) {
// Get the role record
var roleRec = new GlideRecord('sys_user_has_role');
if (roleRec.get(audit.documentkey)) {
var roleName = roleRec.role.name.toString();
if (sensitiveRoles.indexOf(roleName) >= 0) {
var userName = roleRec.user.user_name.toString();
var grantedBy = audit.user.toString();
gs.warn('PRIVILEGE ESCALATION: ' + userName +
' granted ' + roleName + ' role by ' + grantedBy);
}
}
}
description: "Anomaly: Detect sensitive role grants"
フェーズ 5:削除されたレコードの追跡
削除されたレコードをクエリする:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit_delete
query: sys_created_onONLast 7 days
fields: tablename,documentkey,display_name,deleted_by,sys_created_on
limit: 100
削除された機密レコードを追跡する:
Tool: SN-Query-Table
Parameters:
table_name: sys_audit_delete
query: tablenameINsys_user,sys_user_has_role,sys_security_acl^sys_created_onONLast 30 days
fields: tablename,documentkey,display_name,deleted_by,sys_created_on
limit: 100
コンプライアンスフレームワークとの対応関係
SOX 管理策
| 管理策 | 監査クエリ |
|---|---|
| ユーザーアクセスレビュー | sys_user_has_role の変更をクエリする |
| 職務の分離 | 相反するロールの割り当てをクエリする |
| 変更管理 | sys_update_set と sys_update_xml をクエリする |
| 監査証跡の完全性 | sys_audit の保持期間を確認する |
HIPAA 要件
| 要件 | 実装 |
|---|---|
| アクセス制御 | ACL の監査とロールの追跡 |
| 監査管理策 | sys_audit と syslog の保持 |
| 完全性管理策 | PHI テーブルの変更追跡 |
| 伝送セキュリティ | SSL/TLS の検証 |
PCI-DSS 要件
| 要件 | 監査方法 |
|---|---|
| 10.1 - 監査証跡 | すべてのテーブルで sys_audit を有効化する |
| 10.2 - イベントのログ記録 | syslog でシステムイベントを記録する |
| 10.3 - 監査内容 | documentkey、user、timestamp を記録する |
| 10.7 - ログの保持 | sys_audit の保持期間を設定する |
ツール使用の概要
| 操作 | MCP ツール | REST エンドポイント |
|---|---|---|
| 監査のクエリ | SN-Query-Table | GET /sys_audit |
| 自然言語検索 | SN-Natural-Language-Search | N/A |
| 複雑な分析 | SN-Execute-Background-Script | POST /sys_trigger |
| スキーマの検出 | SN-Discover-Table-Schema | GET /sys_dictionary |
| アラートの作成 | SN-Create-Record | POST /sn_si_incident |
ベストプラクティス
- 保持ポリシー: sys_audit に適切な保持期間を設定します(コンプライアンスのため、最低 1 年)。
- テーブル監査: sys_dictionary.audit=true を使用して、すべての機密テーブルで監査を有効にします。
- リアルタイムアラート: 重要な変更(ロールの付与、ACL の変更)に対するビジネスルールを作成します。
- 定期レポート: コンプライアンスレポートの生成を週次または月次で自動化します。
- ベースライン動作: 異常検知を行う前に、通常のアクティビティパターンを確立します。
- ログの完全性: 厳格な ACL で監査テーブルを保護します(ほとんどのユーザーには読み取り専用)。
トラブルシューティング
監査レコードが見つからない
症状: 予期した変更が sys_audit に表示されない 原因: テーブルまたはフィールドで監査が有効になっていない 解決策:
Tool: SN-Query-Table
Parameters:
table_name: sys_dictionary
query: name=[table_name]^element=[field_name]
fields: name,element,audit
監査を有効にするには、ディクショナリレコードで audit=true を設定します。
クエリのパフォーマンスに関する問題
症状: 監査クエリがタイムアウトする 原因: 適切なインデックスがない大規模な監査テーブル 解決策:
- 日付範囲フィルターを使用します(必ず sys_created_on を含めてください)。
- 結果セットを適切に制限します。
- 過去のクエリでは、アーカイブ済みの監査データの使用を検討します。
コンプライアンスレポートの欠落
症状: コンプライアンスレポートのデータが不足している 原因: 保持ポリシーによって過去のレコードが削除された 解決策:
- sys_properties で監査データの保持設定を確認します。
- 次回のクリーンアップ前に保持期間を延長します。
- 長期的なコンプライアンスのため、外部アーカイブを検討します。
例
例 1:週次セキュリティ監査レポート
Tool: SN-Execute-Background-Script
Parameters:
script: |
var report = {
generated: new GlideDateTime().toString(),
period: 'Last 7 days',
summary: {
total_changes: 0,
user_changes: 0,
role_changes: 0,
acl_changes: 0,
failed_logins: 0
},
anomalies: []
};
// Count total changes
var audit = new GlideAggregate('sys_audit');
audit.addQuery('sys_created_on', '>=', gs.daysAgo(7));
audit.addAggregate('COUNT');
audit.query();
if (audit.next()) {
report.summary.total_changes = parseInt(audit.getAggregate('COUNT'));
}
// Count by category
var categories = {
'sys_user': 'user_changes',
'sys_user_has_role': 'role_changes',
'sys_security_acl': 'acl_changes'
};
for (var table in categories) {
audit = new GlideAggregate('sys_audit');
audit.addQuery('tablename', table);
audit.addQuery('sys_created_on', '>=', gs.daysAgo(7));
audit.addAggregate('COUNT');
audit.query();
if (audit.next()) {
report.summary[categories[table]] = parseInt(audit.getAggregate('COUNT'));
}
}
gs.info('WEEKLY SECURITY AUDIT REPORT:\n' + JSON.stringify(report, null, 2));
description: "Generate weekly security audit report"
例 2:ユーザーアクティビティのタイムライン
Tool: SN-Query-Table
Parameters:
table_name: sys_audit
query: user=john.doe^sys_created_onONLast 30 days
fields: tablename,fieldname,oldvalue,newvalue,sys_created_on
limit: 500
orderBy: sys_created_on
orderByDesc: true
関連スキル
security/incident-response- 検出されたセキュリティインシデントへの対応security/acl-management- アクセス制御の設定security/data-classification- 機密データの特定admin/update-set-management- 設定変更の追跡