data-classification について
ServiceNowの管理者やセキュリティチーム向けに、機密フィールドの検出、データマスキングの設定、分類ラベルの適用を支援するスキルです。PII/PHIスキャンとコンプライアンスレポートにも対応します。
主な機能
- 01機密データフィールドの検出
- 02PII/PHIのスキャン
- 03動的またはロールベースのマスキング設定
- 04テーブルとフィールドの分類
- 05分類・GDPRレポートの生成
活用シーン
- 01ServiceNowインスタンスのセキュリティ評価
- 02GDPR、HIPAA、PCI-DSS監査の準備
- 03非本番環境向けデータマスキングの設定
- 04データガバナンスポリシーの策定
MCP 対応
SN-Discover-Table-Schema、SN-Query-Table、SN-Execute-Background-ScriptなどのMCPツールでスキーマを調査し、データをスキャンして分類情報を管理します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ happy-technologies-llc/ happy-platform-skills --skill data-classificationインストール後、Claude Code で/data-classificationを入力して読み込まれたか確認します。
詳細
データ分類
概要
データ分類は、セキュリティ、コンプライアンス、ガバナンスにとって重要です。このスキルでは、次の内容を扱います。
- ServiceNow 全体で機密データフィールドを検出し、特定する
- PII/PHI を保護するためのデータマスキング戦略を実施する
- パターンとヒューリスティックを用いて PII/PHI を自動検出する
- テーブルとフィールドに分類ラベルを適用する
- GDPR、HIPAA、PCI-DSS、その他の規制に準拠する
使用する場面:
- ServiceNow インスタンスの初期セキュリティ評価
- コンプライアンス監査(GDPR、HIPAA、SOX、PCI-DSS)の準備
- データプライバシー制御の実施
- 非本番環境向けのデータマスキングの設定
- データガバナンスポリシーの作成
前提条件
- ロール:
admin、security_admin、data_privacy_admin - アクセス権: sys_dictionary、sys_db_object、フィールドレベルのメタデータ
- プラグイン: Data Classification(任意)、Encryption(保存データの暗号化用)
- 知識: 規制要件(GDPR、HIPAA、PCI-DSS)
データ分類フレームワーク
分類レベル
| レベル | ラベル | 説明 | 例 |
|---|---|---|---|
| 1 | 公開 | 制限なし | KB 記事、会社情報 |
| 2 | 社内 | 従業員のみアクセス可能 | ポリシー、組織図 |
| 3 | 機密 | 知る必要がある人のみ | 財務データ、人事情報 |
| 4 | 制限付き | 厳格な管理 | PII、PHI、認証情報 |
| 5 | 秘密 | 最大限の保護 | 暗号化キー、SSN |
機密データのカテゴリ
| カテゴリ | 説明 | 規制 |
|---|---|---|
| PII | 個人を特定できる情報 | GDPR、CCPA |
| PHI | 保護対象の医療情報 | HIPAA |
| PCI | ペイメントカード業界のデータ | PCI-DSS |
| 財務情報 | 銀行/財務記録 | SOX、GLBA |
| 認証情報 | パスワード、トークン、キー | すべて |
手順
フェーズ 1:機密フィールドの検出
1.1 PII フィールドの自動検出
一般的な PII フィールドのパターンをスキャンします:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var piiPatterns = [
// Name patterns
{ pattern: /^(first|last|middle|full)_?name$/i, category: 'PII', type: 'Name' },
{ pattern: /^name$/i, category: 'PII', type: 'Name' },
// Contact patterns
{ pattern: /email/i, category: 'PII', type: 'Email' },
{ pattern: /phone|mobile|fax|tel/i, category: 'PII', type: 'Phone' },
{ pattern: /address|street|city|state|zip|postal|country/i, category: 'PII', type: 'Address' },
// Identity patterns
{ pattern: /ssn|social.*security|sin|national.*id/i, category: 'PII', type: 'National ID' },
{ pattern: /passport/i, category: 'PII', type: 'Passport' },
{ pattern: /driver.*license|licence/i, category: 'PII', type: 'License' },
{ pattern: /dob|birth.*date|date.*birth/i, category: 'PII', type: 'DOB' },
// Financial patterns
{ pattern: /credit.*card|card.*number|pan|cc_/i, category: 'PCI', type: 'Credit Card' },
{ pattern: /cvv|cvc|security.*code/i, category: 'PCI', type: 'Card Security' },
{ pattern: /bank.*account|account.*number|routing/i, category: 'Financial', type: 'Bank Account' },
{ pattern: /salary|wage|compensation|income/i, category: 'Financial', type: 'Compensation' },
// Health patterns
{ pattern: /medical|health|diagnosis|treatment|condition/i, category: 'PHI', type: 'Medical' },
{ pattern: /insurance.*id|policy.*number|member.*id/i, category: 'PHI', type: 'Insurance' },
{ pattern: /prescription|medication|drug/i, category: 'PHI', type: 'Medication' },
// Authentication patterns
{ pattern: /password|passwd|pwd/i, category: 'Credentials', type: 'Password' },
{ pattern: /secret|token|api.*key/i, category: 'Credentials', type: 'Secret' },
{ pattern: /private.*key|cert|certificate/i, category: 'Credentials', type: 'Certificate' }
];
var findings = [];
var dict = new GlideRecord('sys_dictionary');
dict.addQuery('internal_type', '!=', 'collection');
dict.addNullQuery('element').addOrCondition('element', '!=', '');
dict.query();
while (dict.next()) {
var fieldName = dict.element.toString();
var tableName = dict.name.toString();
if (!fieldName || fieldName.startsWith('sys_')) continue;
for (var i = 0; i < piiPatterns.length; i++) {
if (piiPatterns[i].pattern.test(fieldName)) {
findings.push({
table: tableName,
field: fieldName,
category: piiPatterns[i].category,
type: piiPatterns[i].type,
label: dict.column_label.toString()
});
break;
}
}
}
gs.info('PII FIELD DISCOVERY RESULTS: ' + findings.length + ' potential PII fields found');
gs.info(JSON.stringify(findings, null, 2));
description: "Scan instance for potential PII fields"
1.2 機密データが含まれるテーブルスキーマの検出
特定のテーブルを詳しく調査します:
Tool: SN-Discover-Table-Schema
Parameters:
table_name: sys_user
include_inherited: true
フィールドの詳細をクエリします:
Tool: SN-Query-Table
Parameters:
table_name: sys_dictionary
query: name=sys_user^elementISNOTEMPTY
fields: element,column_label,internal_type,max_length,read_only
limit: 100
1.3 実データが含まれるフィールドの検索
機密フィールドの値のサンプル(マスキング済み):
Tool: SN-Execute-Background-Script
Parameters:
script: |
var sensitiveFields = [
{ table: 'sys_user', field: 'email', mask: true },
{ table: 'sys_user', field: 'phone', mask: true },
{ table: 'sys_user', field: 'mobile_phone', mask: true },
{ table: 'customer_contact', field: 'email', mask: true }
];
var results = [];
for (var i = 0; i < sensitiveFields.length; i++) {
var config = sensitiveFields[i];
var gr = new GlideRecord(config.table);
gr.addNotNullQuery(config.field);
gr.setLimit(5);
gr.query();
var samples = [];
while (gr.next()) {
var value = gr[config.field].toString();
if (config.mask && value) {
// Mask all but first/last 2 characters
if (value.length > 4) {
value = value.substring(0, 2) + '***' + value.substring(value.length - 2);
} else {
value = '***';
}
}
samples.push(value);
}
if (samples.length > 0) {
results.push({
table: config.table,
field: config.field,
populated: true,
sample_count: samples.length,
samples: samples
});
}
}
gs.info('SENSITIVE FIELD SAMPLE (MASKED):');
gs.info(JSON.stringify(results, null, 2));
description: "Sample sensitive field data (masked)"
フェーズ 2:データマスキング戦略
2.1 動的データマスキング
マスク表示用のビジネスルールを作成します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Example: Create a script include for data masking
var scriptContent =
"var DataMasker = Class.create();\n" +
"DataMasker.prototype = {\n" +
" initialize: function() {},\n" +
" \n" +
" maskEmail: function(email) {\n" +
" if (!email) return '';\n" +
" var parts = email.split('@');\n" +
" if (parts.length != 2) return '***@***';\n" +
" var user = parts[0];\n" +
" var domain = parts[1];\n" +
" if (user.length > 2) {\n" +
" user = user.charAt(0) + '***' + user.charAt(user.length-1);\n" +
" }\n" +
" return user + '@' + domain;\n" +
" },\n" +
" \n" +
" maskPhone: function(phone) {\n" +
" if (!phone) return '';\n" +
" var digits = phone.replace(/\\D/g, '');\n" +
" if (digits.length >= 10) {\n" +
" return '***-***-' + digits.slice(-4);\n" +
" }\n" +
" return '***';\n" +
" },\n" +
" \n" +
" maskSSN: function(ssn) {\n" +
" if (!ssn) return '';\n" +
" var digits = ssn.replace(/\\D/g, '');\n" +
" if (digits.length >= 4) {\n" +
" return '***-**-' + digits.slice(-4);\n" +
" }\n" +
" return '***-**-****';\n" +
" },\n" +
" \n" +
" maskCreditCard: function(cc) {\n" +
" if (!cc) return '';\n" +
" var digits = cc.replace(/\\D/g, '');\n" +
" if (digits.length >= 4) {\n" +
" return '****-****-****-' + digits.slice(-4);\n" +
" }\n" +
" return '****-****-****-****';\n" +
" },\n" +
" \n" +
" type: 'DataMasker'\n" +
"};";
gs.info('Data Masker Script Include:\n' + scriptContent);
description: "Generate data masking script include"
2.2 フィールドレベルの暗号化
暗号化機能を確認します:
Tool: SN-Query-Table
Parameters:
table_name: sys_properties
query: nameLIKEencrypt
fields: name,value,description
limit: 20
フィールドの暗号化を有効にします:
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Check if encryption is configured
var encryptProp = gs.getProperty('glide.security.encryption.module');
gs.info('Encryption Module: ' + encryptProp);
// To encrypt a field, update sys_dictionary
// Set 'encrypt_on_write' = true for the field
var dict = new GlideRecord('sys_dictionary');
dict.addQuery('name', 'u_custom_table');
dict.addQuery('element', 'ssn_field');
dict.query();
if (dict.next()) {
gs.info('Current encryption setting: ' + dict.encrypt_context);
// dict.encrypt_context = 'system';
// dict.update();
}
description: "Check and configure field encryption"
2.3 ロールベースのデータマスキング
マスキング用の表示ビジネスルールを作成します:
Tool: SN-Create-Record
Parameters:
table_name: sys_script
data:
name: "Mask Sensitive Data Display"
table: sys_user
when: display
order: 100
active: true
script: |
(function executeRule(current, previous /*null when async*/) {
// Only mask for non-privileged users
if (gs.hasRole('security_admin') || gs.hasRole('hr_admin')) {
return; // Full access
}
// Mask email for general users
if (current.email && !gs.hasRole('itil')) {
var email = current.email.toString();
var parts = email.split('@');
if (parts.length == 2) {
current.email.setDisplayValue(parts[0].charAt(0) + '***@' + parts[1]);
}
}
// Mask phone for general users
if (current.phone && !gs.hasRole('hr_user')) {
var phone = current.phone.toString().replace(/\D/g, '');
if (phone.length >= 4) {
current.phone.setDisplayValue('***-***-' + phone.slice(-4));
}
}
})(current, previous);
description: "Masks sensitive user data based on viewer's roles"
フェーズ 3:PII/PHI の検出
3.1 包括的な PII スキャン
インスタンス全体の PII スキャンを実行します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var piiReport = {
scan_date: new GlideDateTime().toString(),
tables_scanned: 0,
fields_checked: 0,
pii_fields_found: [],
phi_fields_found: [],
pci_fields_found: [],
recommendations: []
};
// PII field name patterns
var piiPatterns = [
/email/i, /phone/i, /mobile/i, /address/i, /zip/i, /postal/i,
/first.*name/i, /last.*name/i, /birth/i, /dob/i, /ssn/i,
/social.*security/i, /passport/i, /driver/i, /license/i
];
var phiPatterns = [
/medical/i, /health/i, /diagnos/i, /treatment/i, /condition/i,
/prescription/i, /medication/i, /insurance/i, /patient/i
];
var pciPatterns = [
/credit.*card/i, /card.*number/i, /cvv/i, /cvc/i, /pan/i,
/expir/i, /bank.*account/i, /routing/i
];
// Get all custom tables
var tables = new GlideRecord('sys_db_object');
tables.addQuery('name', 'STARTSWITH', 'u_');
tables.addOrCondition('name', 'IN', 'sys_user,customer_contact,customer_account,hr_core_profile');
tables.query();
while (tables.next()) {
piiReport.tables_scanned++;
var tableName = tables.name.toString();
var dict = new GlideRecord('sys_dictionary');
dict.addQuery('name', tableName);
dict.addNotNullQuery('element');
dict.query();
while (dict.next()) {
piiReport.fields_checked++;
var fieldName = dict.element.toString();
var fieldLabel = dict.column_label.toString();
// Check against patterns
for (var i = 0; i < piiPatterns.length; i++) {
if (piiPatterns[i].test(fieldName) || piiPatterns[i].test(fieldLabel)) {
piiReport.pii_fields_found.push({
table: tableName,
field: fieldName,
label: fieldLabel
});
break;
}
}
for (var j = 0; j < phiPatterns.length; j++) {
if (phiPatterns[j].test(fieldName) || phiPatterns[j].test(fieldLabel)) {
piiReport.phi_fields_found.push({
table: tableName,
field: fieldName,
label: fieldLabel
});
break;
}
}
for (var k = 0; k < pciPatterns.length; k++) {
if (pciPatterns[k].test(fieldName) || pciPatterns[k].test(fieldLabel)) {
piiReport.pci_fields_found.push({
table: tableName,
field: fieldName,
label: fieldLabel
});
break;
}
}
}
}
// Generate recommendations
if (piiReport.pii_fields_found.length > 0) {
piiReport.recommendations.push('Review PII fields for GDPR/CCPA compliance');
piiReport.recommendations.push('Implement data masking for non-production environments');
piiReport.recommendations.push('Create ACLs to restrict PII field access');
}
if (piiReport.phi_fields_found.length > 0) {
piiReport.recommendations.push('Ensure HIPAA BAA is in place with ServiceNow');
piiReport.recommendations.push('Enable audit logging on all PHI tables');
piiReport.recommendations.push('Implement PHI encryption at rest');
}
if (piiReport.pci_fields_found.length > 0) {
piiReport.recommendations.push('PCI data should NOT be stored in ServiceNow');
piiReport.recommendations.push('Consider tokenization for payment data');
piiReport.recommendations.push('Review PCI-DSS compliance requirements');
}
gs.info('PII/PHI/PCI DISCOVERY REPORT:\n' + JSON.stringify(piiReport, null, 2));
description: "Comprehensive PII/PHI/PCI discovery scan"
3.2 データコンテンツのスキャン
実データをスキャンして機密パターンを検出します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Regex patterns for detecting sensitive data in content
var patterns = {
email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
phone: /(\+1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}/g,
ssn: /\d{3}[-\s]?\d{2}[-\s]?\d{4}/g,
creditCard: /\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}/g,
ipv4: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g
};
// Tables and fields to scan for embedded PII
var scanTargets = [
{ table: 'incident', field: 'description' },
{ table: 'incident', field: 'comments' },
{ table: 'sc_req_item', field: 'special_instructions' },
{ table: 'kb_knowledge', field: 'text' }
];
var findings = [];
for (var i = 0; i < scanTargets.length; i++) {
var target = scanTargets[i];
var gr = new GlideRecord(target.table);
gr.setLimit(100); // Limit for performance
gr.query();
while (gr.next()) {
var content = gr[target.field].toString();
for (var patternName in patterns) {
var matches = content.match(patterns[patternName]);
if (matches && matches.length > 0) {
findings.push({
table: target.table,
field: target.field,
record: gr.getDisplayValue(),
sys_id: gr.sys_id.toString(),
pattern: patternName,
count: matches.length
});
}
}
}
}
if (findings.length > 0) {
gs.warn('EMBEDDED PII DETECTED: ' + findings.length + ' records contain potential PII');
gs.info(JSON.stringify(findings.slice(0, 20), null, 2)); // First 20
} else {
gs.info('No embedded PII detected in scanned content');
}
description: "Scan record content for embedded PII patterns"
フェーズ 4:分類ラベル
4.1 分類ラベルの作成
分類ラベルを定義します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Check if data classification table exists
if (GlideTableDescriptor.isValid('sys_data_classification')) {
var labels = [
{ name: 'Public', level: 1, description: 'Information that can be freely shared' },
{ name: 'Internal', level: 2, description: 'For internal use only' },
{ name: 'Confidential', level: 3, description: 'Sensitive business information' },
{ name: 'Restricted', level: 4, description: 'PII, PHI, or regulated data' },
{ name: 'Secret', level: 5, description: 'Maximum protection required' }
];
for (var i = 0; i < labels.length; i++) {
var gr = new GlideRecord('sys_data_classification');
gr.addQuery('name', labels[i].name);
gr.query();
if (!gr.hasNext()) {
gr.initialize();
gr.name = labels[i].name;
gr.level = labels[i].level;
gr.description = labels[i].description;
gr.insert();
gs.info('Created classification: ' + labels[i].name);
} else {
gs.info('Classification exists: ' + labels[i].name);
}
}
} else {
// Use custom table or properties
gs.info('Data Classification plugin not installed');
gs.info('Consider using sys_properties or custom table for labels');
}
description: "Create data classification labels"
4.2 テーブルへの分類の適用
テーブルの分類を保存します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
// Use sys_properties to store table classifications
var tableClassifications = {
'sys_user': 'Restricted',
'customer_contact': 'Restricted',
'incident': 'Internal',
'kb_knowledge': 'Public',
'hr_core_profile': 'Secret',
'ast_contract': 'Confidential'
};
for (var table in tableClassifications) {
var propName = 'data.classification.' + table;
var propValue = tableClassifications[table];
var prop = new GlideRecord('sys_properties');
prop.addQuery('name', propName);
prop.query();
if (prop.next()) {
prop.value = propValue;
prop.update();
gs.info('Updated: ' + propName + ' = ' + propValue);
} else {
prop.initialize();
prop.name = propName;
prop.value = propValue;
prop.description = 'Data classification for ' + table + ' table';
prop.type = 'string';
prop.insert();
gs.info('Created: ' + propName + ' = ' + propValue);
}
}
description: "Apply data classifications to tables"
4.3 フィールドレベルの分類
機密フィールドに分類を適用します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var fieldClassifications = [
{ table: 'sys_user', field: 'email', classification: 'Restricted', reason: 'PII - Contact' },
{ table: 'sys_user', field: 'phone', classification: 'Restricted', reason: 'PII - Contact' },
{ table: 'sys_user', field: 'home_phone', classification: 'Restricted', reason: 'PII - Contact' },
{ table: 'sys_user', field: 'mobile_phone', classification: 'Restricted', reason: 'PII - Contact' },
{ table: 'hr_core_profile', field: 'ssn', classification: 'Secret', reason: 'PII - National ID' },
{ table: 'hr_core_profile', field: 'date_of_birth', classification: 'Restricted', reason: 'PII - DOB' },
{ table: 'customer_contact', field: 'email', classification: 'Restricted', reason: 'PII - Contact' }
];
for (var i = 0; i < fieldClassifications.length; i++) {
var fc = fieldClassifications[i];
var propName = 'data.classification.' + fc.table + '.' + fc.field;
var prop = new GlideRecord('sys_properties');
prop.addQuery('name', propName);
prop.query();
if (prop.next()) {
prop.value = fc.classification;
prop.update();
} else {
prop.initialize();
prop.name = propName;
prop.value = fc.classification;
prop.description = fc.reason;
prop.type = 'string';
prop.insert();
}
gs.info('Classified: ' + fc.table + '.' + fc.field + ' as ' + fc.classification);
}
description: "Apply field-level data classifications"
フェーズ 5:コンプライアンスレポート
5.1 分類レポートの生成
データ分類インベントリを作成します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var report = {
generated: new GlideDateTime().toString(),
summary: {
total_tables: 0,
classified_tables: 0,
total_fields: 0,
classified_fields: 0
},
by_level: {
'Public': { tables: [], fields: [] },
'Internal': { tables: [], fields: [] },
'Confidential': { tables: [], fields: [] },
'Restricted': { tables: [], fields: [] },
'Secret': { tables: [], fields: [] }
},
unclassified: {
sensitive_tables: [],
sensitive_fields: []
}
};
// Get table classifications
var props = new GlideRecord('sys_properties');
props.addQuery('name', 'STARTSWITH', 'data.classification.');
props.query();
while (props.next()) {
var propName = props.name.toString();
var classification = props.value.toString();
var parts = propName.replace('data.classification.', '').split('.');
if (parts.length === 1) {
// Table classification
report.summary.classified_tables++;
if (report.by_level[classification]) {
report.by_level[classification].tables.push(parts[0]);
}
} else if (parts.length === 2) {
// Field classification
report.summary.classified_fields++;
if (report.by_level[classification]) {
report.by_level[classification].fields.push(parts[0] + '.' + parts[1]);
}
}
}
// Count total tables
var tables = new GlideAggregate('sys_db_object');
tables.addAggregate('COUNT');
tables.query();
if (tables.next()) {
report.summary.total_tables = parseInt(tables.getAggregate('COUNT'));
}
// Count total fields
var fields = new GlideAggregate('sys_dictionary');
fields.addNotNullQuery('element');
fields.addAggregate('COUNT');
fields.query();
if (fields.next()) {
report.summary.total_fields = parseInt(fields.getAggregate('COUNT'));
}
gs.info('DATA CLASSIFICATION REPORT:\n' + JSON.stringify(report, null, 2));
description: "Generate data classification report"
5.2 GDPR データマップ
GDPR 準拠のデータマップを生成します:
Tool: SN-Execute-Background-Script
Parameters:
script: |
var gdprMap = {
generated: new GlideDateTime().toString(),
data_controller: 'Your Organization Name',
personal_data_inventory: [],
lawful_basis: {},
retention_periods: {},
third_party_sharing: []
};
// Find all PII fields
var piiFields = [
{ table: 'sys_user', fields: ['first_name', 'last_name', 'email', 'phone', 'mobile_phone', 'home_phone', 'location'] },
{ table: 'customer_contact', fields: ['first_name', 'last_name', 'email', 'phone', 'mobile_phone'] },
{ table: 'hr_core_profile', fields: ['first_name', 'last_name', 'date_of_birth', 'ssn', 'address', 'city', 'state', 'zip'] }
];
for (var i = 0; i < piiFields.length; i++) {
var tableInfo = piiFields[i];
// Count records
var gr = new GlideAggregate(tableInfo.table);
gr.addAggregate('COUNT');
gr.query();
var recordCount = 0;
if (gr.next()) {
recordCount = parseInt(gr.getAggregate('COUNT'));
}
gdprMap.personal_data_inventory.push({
table: tableInfo.table,
fields: tableInfo.fields,
record_count: recordCount,
data_subjects: 'Employees/Customers',
purpose: 'Business operations',
lawful_basis: 'Legitimate interest / Contract performance'
});
}
// Define retention periods
gdprMap.retention_periods = {
'sys_user': 'Duration of employment + 7 years',
'customer_contact': 'Duration of relationship + 5 years',
'incident': '3 years after closure',
'hr_core_profile': 'Duration of employment + 7 years'
};
gs.info('GDPR DATA MAP:\n' + JSON.stringify(gdprMap, null, 2));
description: "Generate GDPR data map"
ツールの使用概要
| 操作 | MCP ツール | REST エンドポイント |
|---|---|---|
| スキーマの検出 | SN-Discover-Table-Schema | GET /sys_dictionary |
| フィールドのクエリ | SN-Query-Table | GET /sys_dictionary |
| スキャンの実行 | SN-Execute-Background-Script | sys_trigger 経由 |
| 分類の作成 | SN-Create-Record | POST /sys_properties |
| 分類の更新 | SN-Update-Record | PATCH /sys_properties |
| テーブル情報の取得 | SN-Get-Table-Schema | GET /sys_dictionary |
ベストプラクティス
- まずはインベントリ作成: 管理策を実装する前に、データの検出を完了します
- リスクベースのアプローチ: 最もリスクの高いデータ(PII、PHI、PCI)を優先します
- 多層防御: ACL、暗号化、マスキング、監査を組み合わせます
- 定期スキャン: PII 検出スキャンを定期的に実施するようスケジュールします
- すべてを文書化: 監査に備えてデータ分類記録を維持します
- 非本番環境でのマスキング: 非本番環境では、本番データを必ずマスキングします
- 最小権限: 分類済みデータへのアクセスは、必要な場合にのみ許可します
トラブルシューティング
データのマスキングが適用されない
症状: ユーザーにマスキングされていないデータが表示される
原因: 表示ビジネスルールが実行されていない
解決策: ビジネスルールの順序と条件を確認し、ロールのチェックを検証します
PII スキャンでフィールドが検出されない
症状: PII と判明しているフィールドが検出されない
原因: フィールド名がパターンに一致しない
解決策: 組織固有の命名規則に対応するカスタムパターンを追加します
分類が保持されない
症状: 分類がリセットされる、または失われる
原因: プロパティが正しいスコープに作成されていない
解決策: sys_properties のスコープと更新セットへの取り込みを確認します
暗号化によるパフォーマンスの低下
症状: 暗号化されたフィールドへのクエリが遅い
原因: 暗号化によりインデックスが使用できない
解決策: 本当に機密性の高いフィールドのみを暗号化し、検索には参照フィールドを使用します
関連スキル
security/acl-management- 分類済みデータへのアクセスを制限するsecurity/audit-compliance- 機密データへのアクセスを監査するsecurity/incident-response- データ侵害に対応するgrc/risk-identification- 機密データの取り扱いに関連するリスクを特定する