snow-flow 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{.claude/mcp-config.json → .mcp.json} +13 -12
- package/.releaserc.json +47 -0
- package/README.md +48 -1
- package/package.json +1 -1
- package/.claude/claude-settings.json +0 -15
- package/.claude/commands/analysis/README.md +0 -9
- package/.claude/commands/automation/README.md +0 -9
- package/.claude/commands/github/README.md +0 -11
- package/.claude/commands/helpers/standard-checkpoint-hooks.sh +0 -179
- package/.claude/commands/hooks/README.md +0 -11
- package/.claude/commands/monitoring/README.md +0 -9
- package/.claude/commands/optimization/README.md +0 -9
- package/.claude/commands/training/README.md +0 -9
- package/.claude/commands/workflows/README.md +0 -9
- package/.claude/config.json +0 -36
- package/.claude/helpers/github-setup.sh +0 -28
- package/.claude/helpers/quick-start.sh +0 -19
- package/.claude/helpers/setup-mcp.sh +0 -18
- package/.claude/settings.json +0 -114
- package/.claude/settings.local.json +0 -33
- package/.claude-flow/metrics/agent-metrics.json +0 -1
- package/.claude-flow/metrics/performance.json +0 -9
- package/.claude-flow/metrics/system-metrics.json +0 -15986
- package/.claude-flow/metrics/task-metrics.json +0 -10
- package/.roo/README.md +0 -402
- package/.roo/mcp-list.txt +0 -257
- package/.roo/mcp.json +0 -32
- package/.roo/workflows/basic-tdd.json +0 -32
- package/.roomodes +0 -201
- package/CLAUDE.md +0 -393
- package/bin/snow-flow.js +0 -3
- package/dist/cli.js.bak +0 -2052
- package/dist/config/snow-flow-config.d.ts +0 -1492
- package/dist/config/snow-flow-config.js +0 -938
- package/scripts/create-env.js +0 -91
- package/scripts/postinstall.js +0 -30
- package/scripts/register-mcp-servers.js +0 -210
- package/scripts/reset-mcp-servers.js +0 -246
- package/scripts/setup-mcp.js +0 -106
- package/scripts/update-version.js +0 -31
- package/src/agents/README.md +0 -192
- package/src/agents/base-agent.ts +0 -251
- package/src/agents/coordinator.ts +0 -971
- package/src/agents/index.ts +0 -18
- package/src/agents/queen-403-handler.ts +0 -230
- package/src/agents/queen-agent.ts +0 -1399
- package/src/agents/script-writer-agent.ts +0 -769
- package/src/agents/security-agent.ts +0 -726
- package/src/agents/widget-creator-agent.ts +0 -568
- package/src/api/error-handling.ts +0 -1758
- package/src/api/natural-language-mapper.ts +0 -630
- package/src/api/performance-optimizer.ts +0 -891
- package/src/api/transaction-manager.ts +0 -754
- package/src/cli/deploy-artifact.ts +0 -304
- package/src/cli/snow-flow-cli-integration.ts +0 -434
- package/src/cli.ts +0 -4455
- package/src/cli.ts.bak +0 -5616
- package/src/compliance/advanced-compliance-system.ts +0 -1268
- package/src/compliance/index.ts +0 -19
- package/src/config/snow-flow-config.ts +0 -1019
- package/src/documentation/index.ts +0 -16
- package/src/documentation/self-documenting-system.ts +0 -1421
- package/src/dynamic-version.ts +0 -44
- package/src/healing/index.ts +0 -20
- package/src/healing/self-healing-system.ts +0 -1435
- package/src/health/README.md +0 -161
- package/src/health/system-health.ts +0 -995
- package/src/index.ts +0 -60
- package/src/intelligence/acl-analyzer.ts +0 -377
- package/src/intelligence/auto-resolution-engine.ts +0 -643
- package/src/intelligence/gap-analysis-engine.ts +0 -488
- package/src/intelligence/manual-instructions-generator.ts +0 -744
- package/src/intelligence/mcp-coverage-analyzer.ts +0 -708
- package/src/intelligence/multi-pass-requirements-analyzer.ts +0 -603
- package/src/intelligence/performance-recommendations-engine.ts +0 -1223
- package/src/intelligence/requirements-analyzer.ts +0 -1148
- package/src/intelligence/task-analyzer.ts +0 -628
- package/src/managers/scope-manager.ts +0 -555
- package/src/mcp/advanced/servicenow-advanced-features-mcp.ts +0 -16110
- package/src/mcp/base-mcp-server.ts +0 -660
- package/src/mcp/http-transport-wrapper.ts +0 -426
- package/src/mcp/service-discovery-client.ts +0 -312
- package/src/mcp/servicenow-automation-mcp-refactored.ts +0 -678
- package/src/mcp/servicenow-automation-mcp.ts +0 -838
- package/src/mcp/servicenow-deployment-mcp-refactored.ts +0 -1292
- package/src/mcp/servicenow-deployment-mcp.ts +0 -7244
- package/src/mcp/servicenow-graph-memory-mcp-refactored.ts +0 -721
- package/src/mcp/servicenow-graph-memory-mcp.ts +0 -832
- package/src/mcp/servicenow-integration-mcp-refactored.ts +0 -655
- package/src/mcp/servicenow-integration-mcp.ts +0 -819
- package/src/mcp/servicenow-intelligent-mcp-refactored.ts +0 -977
- package/src/mcp/servicenow-intelligent-mcp.ts +0 -4638
- package/src/mcp/servicenow-mcp-server.ts +0 -728
- package/src/mcp/servicenow-memory-mcp.ts +0 -474
- package/src/mcp/servicenow-operations-mcp-refactored.ts +0 -1995
- package/src/mcp/servicenow-operations-mcp.ts +0 -3384
- package/src/mcp/servicenow-platform-development-mcp-refactored.ts +0 -611
- package/src/mcp/servicenow-platform-development-mcp.ts +0 -970
- package/src/mcp/servicenow-progressive-indexer.ts +0 -370
- package/src/mcp/servicenow-reporting-analytics-mcp-refactored.ts +0 -695
- package/src/mcp/servicenow-reporting-analytics-mcp.ts +0 -1123
- package/src/mcp/servicenow-security-compliance-mcp-refactored.ts +0 -642
- package/src/mcp/servicenow-security-compliance-mcp.ts +0 -1157
- package/src/mcp/servicenow-update-set-mcp-refactored.ts +0 -751
- package/src/mcp/servicenow-update-set-mcp.ts +0 -811
- package/src/mcp/shared/agent-context-provider.ts +0 -365
- package/src/mcp/shared/base-mcp-server.ts +0 -2463
- package/src/mcp/shared/mcp-memory-manager.ts +0 -540
- package/src/mcp/shared/mcp-resource-manager.ts +0 -367
- package/src/mcp/snow-flow-mcp.ts +0 -911
- package/src/mcp/start-all-mcp-servers.ts +0 -102
- package/src/mcp/start-servicenow-mcp.ts +0 -67
- package/src/monitoring/enhanced-monitoring-system.ts +0 -1345
- package/src/monitoring/performance-tracker.ts +0 -777
- package/src/optimization/cost-optimization-engine.ts +0 -1125
- package/src/optimization/index.ts +0 -10
- package/src/queen/README.md +0 -403
- package/src/queen/agent-factory.ts +0 -574
- package/src/queen/index.ts +0 -94
- package/src/queen/mcp-execution-bridge.ts +0 -681
- package/src/queen/neural-learning.ts +0 -319
- package/src/queen/parallel-agent-engine.ts +0 -848
- package/src/queen/queen-memory-system.ts +0 -490
- package/src/queen/queen-memory.ts +0 -456
- package/src/queen/servicenow-queen.ts +0 -1029
- package/src/queen/types.ts +0 -87
- package/src/rollback/smart-rollback-system.ts +0 -866
- package/src/schemas/deployment.schema.json +0 -58
- package/src/schemas/flow.schema.json +0 -79
- package/src/schemas/widget.schema.json +0 -72
- package/src/snow-flow-system.ts +0 -541
- package/src/sparc/sparc-help.ts +0 -49
- package/src/sparc/team-sparc.ts +0 -88
- package/src/strategies/global-scope-strategy.ts +0 -736
- package/src/templates/base/application.template.json +0 -45
- package/src/templates/base/business_rule.template.json +0 -33
- package/src/templates/base/script_include.template.json +0 -18
- package/src/templates/base/table.template.json +0 -64
- package/src/templates/base/widget.template.json +0 -25
- package/src/templates/patterns/composite.incident-management.template.json +0 -140
- package/src/templates/patterns/widget.dashboard.template.json +0 -238
- package/src/templates/patterns/widget.datatable.template.json +0 -292
- package/src/testing/integration-test-suite.ts +0 -1276
- package/src/types/index.ts +0 -183
- package/src/types/neo4j-driver.d.ts +0 -23
- package/src/types/servicenow.types.ts +0 -307
- package/src/types/snow-flow.types.ts +0 -186
- package/src/types/todo.types.ts +0 -70
- package/src/utils/action-type-cache.ts +0 -286
- package/src/utils/agent-detector.ts +0 -573
- package/src/utils/artifact-tracker.ts +0 -379
- package/src/utils/dependency-detector.ts +0 -233
- package/src/utils/deployment-metadata-handler.ts +0 -518
- package/src/utils/error-recovery.ts +0 -680
- package/src/utils/logger.ts +0 -60
- package/src/utils/mcp-auth-middleware.ts +0 -262
- package/src/utils/mcp-config-manager.ts +0 -270
- package/src/utils/mcp-server-manager.ts +0 -446
- package/src/utils/mcp-tool-registry.ts +0 -298
- package/src/utils/migrate-snow-flow.ts +0 -98
- package/src/utils/oauth-html-templates.ts +0 -188
- package/src/utils/scope-utils.ts +0 -443
- package/src/utils/servicenow-client.ts +0 -3321
- package/src/utils/servicenow-id-generator.ts +0 -181
- package/src/utils/snow-memory-manager.ts +0 -605
- package/src/utils/snow-oauth.ts +0 -797
- package/src/utils/template-engine.ts +0 -463
- package/src/utils/theme-manager.ts +0 -295
- package/src/utils/unified-auth-store.ts +0 -222
- package/src/utils/update-set-importer.ts +0 -422
- package/src/utils/update-set-xml-packager.ts +0 -371
- package/src/utils/widget-template-generator.ts +0 -1744
- package/src/version.ts +0 -1950
|
@@ -1,1157 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* ServiceNow Security & Compliance MCP Server
|
|
4
|
-
* Handles security policies, compliance rules, and audit operations
|
|
5
|
-
* NO HARDCODED VALUES - All security configurations discovered dynamically
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
9
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
10
|
-
import {
|
|
11
|
-
CallToolRequestSchema,
|
|
12
|
-
ErrorCode,
|
|
13
|
-
ListToolsRequestSchema,
|
|
14
|
-
McpError,
|
|
15
|
-
} from '@modelcontextprotocol/sdk/types.js';
|
|
16
|
-
import { ServiceNowClient } from '../utils/servicenow-client.js';
|
|
17
|
-
import { mcpAuth } from '../utils/mcp-auth-middleware.js';
|
|
18
|
-
import { mcpConfig } from '../utils/mcp-config-manager.js';
|
|
19
|
-
import { Logger } from '../utils/logger.js';
|
|
20
|
-
|
|
21
|
-
interface SecurityPolicy {
|
|
22
|
-
name: string;
|
|
23
|
-
type: string;
|
|
24
|
-
rules: string[];
|
|
25
|
-
enforcement: string;
|
|
26
|
-
scope: string;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface ComplianceRule {
|
|
30
|
-
name: string;
|
|
31
|
-
framework: string;
|
|
32
|
-
requirement: string;
|
|
33
|
-
validation: string;
|
|
34
|
-
remediation: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
class ServiceNowSecurityComplianceMCP {
|
|
38
|
-
private server: Server;
|
|
39
|
-
private client: ServiceNowClient;
|
|
40
|
-
private logger: Logger;
|
|
41
|
-
private config: ReturnType<typeof mcpConfig.getConfig>;
|
|
42
|
-
|
|
43
|
-
constructor() {
|
|
44
|
-
this.server = new Server(
|
|
45
|
-
{
|
|
46
|
-
name: 'servicenow-security-compliance',
|
|
47
|
-
version: '1.0.0',
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
capabilities: {
|
|
51
|
-
tools: {},
|
|
52
|
-
},
|
|
53
|
-
}
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
this.client = new ServiceNowClient();
|
|
57
|
-
this.logger = new Logger('ServiceNowSecurityComplianceMCP');
|
|
58
|
-
this.config = mcpConfig.getConfig();
|
|
59
|
-
|
|
60
|
-
this.setupHandlers();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private setupHandlers() {
|
|
64
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
65
|
-
tools: [
|
|
66
|
-
{
|
|
67
|
-
name: 'snow_create_security_policy',
|
|
68
|
-
description: 'Create Security Policy with dynamic rule discovery - NO hardcoded values',
|
|
69
|
-
inputSchema: {
|
|
70
|
-
type: 'object',
|
|
71
|
-
properties: {
|
|
72
|
-
name: { type: 'string', description: 'Security policy name' },
|
|
73
|
-
type: { type: 'string', description: 'Policy type (access, data, network, etc.)' },
|
|
74
|
-
description: { type: 'string', description: 'Policy description' },
|
|
75
|
-
enforcement: { type: 'string', description: 'Enforcement level (strict, moderate, advisory)' },
|
|
76
|
-
scope: { type: 'string', description: 'Policy scope (global, application, table)' },
|
|
77
|
-
rules: { type: 'array', description: 'Security rules and conditions' },
|
|
78
|
-
active: { type: 'boolean', description: 'Policy active status' }
|
|
79
|
-
},
|
|
80
|
-
required: ['name', 'type', 'rules']
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: 'snow_create_compliance_rule',
|
|
85
|
-
description: 'Create Compliance Rule with dynamic framework discovery',
|
|
86
|
-
inputSchema: {
|
|
87
|
-
type: 'object',
|
|
88
|
-
properties: {
|
|
89
|
-
name: { type: 'string', description: 'Compliance rule name' },
|
|
90
|
-
framework: { type: 'string', description: 'Compliance framework (SOX, GDPR, HIPAA, etc.)' },
|
|
91
|
-
requirement: { type: 'string', description: 'Specific requirement or control' },
|
|
92
|
-
validation: { type: 'string', description: 'Validation script or condition' },
|
|
93
|
-
remediation: { type: 'string', description: 'Remediation actions' },
|
|
94
|
-
severity: { type: 'string', description: 'Severity level (critical, high, medium, low)' },
|
|
95
|
-
active: { type: 'boolean', description: 'Rule active status' }
|
|
96
|
-
},
|
|
97
|
-
required: ['name', 'framework', 'requirement', 'validation']
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
name: 'snow_create_audit_rule',
|
|
102
|
-
description: 'Create Audit Rule with dynamic event discovery',
|
|
103
|
-
inputSchema: {
|
|
104
|
-
type: 'object',
|
|
105
|
-
properties: {
|
|
106
|
-
name: { type: 'string', description: 'Audit rule name' },
|
|
107
|
-
table: { type: 'string', description: 'Table to audit' },
|
|
108
|
-
events: { type: 'array', description: 'Events to audit (create, update, delete)' },
|
|
109
|
-
fields: { type: 'array', description: 'Fields to audit' },
|
|
110
|
-
retention: { type: 'number', description: 'Retention period in days' },
|
|
111
|
-
filter: { type: 'string', description: 'Filter conditions' },
|
|
112
|
-
active: { type: 'boolean', description: 'Audit rule active status' }
|
|
113
|
-
},
|
|
114
|
-
required: ['name', 'table', 'events']
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
name: 'snow_create_access_control',
|
|
119
|
-
description: 'Create Access Control with dynamic role discovery',
|
|
120
|
-
inputSchema: {
|
|
121
|
-
type: 'object',
|
|
122
|
-
properties: {
|
|
123
|
-
name: { type: 'string', description: 'Access control name' },
|
|
124
|
-
table: { type: 'string', description: 'Protected table' },
|
|
125
|
-
operation: { type: 'string', description: 'Operation (read, write, create, delete)' },
|
|
126
|
-
roles: { type: 'array', description: 'Allowed roles' },
|
|
127
|
-
condition: { type: 'string', description: 'Access condition script' },
|
|
128
|
-
advanced: { type: 'boolean', description: 'Advanced access control' },
|
|
129
|
-
active: { type: 'boolean', description: 'Access control active status' }
|
|
130
|
-
},
|
|
131
|
-
required: ['name', 'table', 'operation']
|
|
132
|
-
}
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: 'snow_create_data_policy',
|
|
136
|
-
description: 'Create Data Policy with dynamic field discovery',
|
|
137
|
-
inputSchema: {
|
|
138
|
-
type: 'object',
|
|
139
|
-
properties: {
|
|
140
|
-
name: { type: 'string', description: 'Data policy name' },
|
|
141
|
-
table: { type: 'string', description: 'Target table' },
|
|
142
|
-
fields: { type: 'array', description: 'Fields to protect' },
|
|
143
|
-
classification: { type: 'string', description: 'Data classification (public, internal, confidential, restricted)' },
|
|
144
|
-
encryption: { type: 'boolean', description: 'Require encryption' },
|
|
145
|
-
masking: { type: 'boolean', description: 'Apply data masking' },
|
|
146
|
-
retention: { type: 'number', description: 'Data retention period' },
|
|
147
|
-
active: { type: 'boolean', description: 'Policy active status' }
|
|
148
|
-
},
|
|
149
|
-
required: ['name', 'table', 'fields', 'classification']
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
name: 'snow_create_vulnerability_scan',
|
|
154
|
-
description: 'Create Vulnerability Scan with dynamic discovery',
|
|
155
|
-
inputSchema: {
|
|
156
|
-
type: 'object',
|
|
157
|
-
properties: {
|
|
158
|
-
name: { type: 'string', description: 'Scan name' },
|
|
159
|
-
scope: { type: 'string', description: 'Scan scope (application, platform, integrations)' },
|
|
160
|
-
schedule: { type: 'string', description: 'Scan schedule' },
|
|
161
|
-
severity: { type: 'string', description: 'Minimum severity to report' },
|
|
162
|
-
notifications: { type: 'array', description: 'Notification recipients' },
|
|
163
|
-
remediation: { type: 'boolean', description: 'Auto-remediation enabled' },
|
|
164
|
-
active: { type: 'boolean', description: 'Scan active status' }
|
|
165
|
-
},
|
|
166
|
-
required: ['name', 'scope']
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
name: 'snow_discover_security_frameworks',
|
|
171
|
-
description: 'Discover available security and compliance frameworks',
|
|
172
|
-
inputSchema: {
|
|
173
|
-
type: 'object',
|
|
174
|
-
properties: {
|
|
175
|
-
type: { type: 'string', description: 'Framework type (security, compliance, audit)' }
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
name: 'snow_discover_security_policies',
|
|
181
|
-
description: 'Discover existing security policies and rules',
|
|
182
|
-
inputSchema: {
|
|
183
|
-
type: 'object',
|
|
184
|
-
properties: {
|
|
185
|
-
category: { type: 'string', description: 'Policy category filter' },
|
|
186
|
-
active: { type: 'boolean', description: 'Filter by active status' }
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
name: 'snow_run_compliance_scan',
|
|
192
|
-
description: 'Run compliance scan with dynamic rule discovery',
|
|
193
|
-
inputSchema: {
|
|
194
|
-
type: 'object',
|
|
195
|
-
properties: {
|
|
196
|
-
framework: { type: 'string', description: 'Compliance framework to scan' },
|
|
197
|
-
scope: { type: 'string', description: 'Scan scope (instance, application, table)' },
|
|
198
|
-
generateReport: { type: 'boolean', description: 'Generate compliance report' }
|
|
199
|
-
},
|
|
200
|
-
required: ['framework']
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
name: 'snow_audit_trail__analysis',
|
|
205
|
-
description: 'Analyze audit trails for security incidents',
|
|
206
|
-
inputSchema: {
|
|
207
|
-
type: 'object',
|
|
208
|
-
properties: {
|
|
209
|
-
timeframe: { type: 'string', description: 'Analysis timeframe (24h, 7d, 30d)' },
|
|
210
|
-
user: { type: 'string', description: 'Filter by specific user' },
|
|
211
|
-
table: { type: 'string', description: 'Filter by specific table' },
|
|
212
|
-
anomalies: { type: 'boolean', description: 'Detect anomalies' },
|
|
213
|
-
exportFormat: { type: 'string', description: 'Export format (json, csv, pdf)' }
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
name: 'snow_security_risk_assessment',
|
|
219
|
-
description: 'Perform security risk assessment',
|
|
220
|
-
inputSchema: {
|
|
221
|
-
type: 'object',
|
|
222
|
-
properties: {
|
|
223
|
-
scope: { type: 'string', description: 'Assessment scope' },
|
|
224
|
-
riskLevel: { type: 'string', description: 'Minimum risk level to assess' },
|
|
225
|
-
generateMitigation: { type: 'boolean', description: 'Generate mitigation recommendations' }
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
]
|
|
230
|
-
}));
|
|
231
|
-
|
|
232
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
233
|
-
try {
|
|
234
|
-
const { name, arguments: args } = request.params;
|
|
235
|
-
|
|
236
|
-
const authResult = await mcpAuth.ensureAuthenticated();
|
|
237
|
-
if (!authResult.success) {
|
|
238
|
-
throw new McpError(ErrorCode.InternalError, authResult.error || 'Authentication required');
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
switch (name) {
|
|
242
|
-
case 'snow_create_security_policy':
|
|
243
|
-
return await this.createSecurityPolicy(args);
|
|
244
|
-
case 'snow_create_compliance_rule':
|
|
245
|
-
return await this.createComplianceRule(args);
|
|
246
|
-
case 'snow_create_audit_rule':
|
|
247
|
-
return await this.createAuditRule(args);
|
|
248
|
-
case 'snow_create_access_control':
|
|
249
|
-
return await this.createAccessControl(args);
|
|
250
|
-
case 'snow_create_data_policy':
|
|
251
|
-
return await this.createDataPolicy(args);
|
|
252
|
-
case 'snow_create_vulnerability_scan':
|
|
253
|
-
return await this.createVulnerabilityScan(args);
|
|
254
|
-
case 'snow_discover_security_frameworks':
|
|
255
|
-
return await this.discoverSecurityFrameworks(args);
|
|
256
|
-
case 'snow_discover_security_policies':
|
|
257
|
-
return await this.discoverSecurityPolicies(args);
|
|
258
|
-
case 'snow_run_compliance_scan':
|
|
259
|
-
return await this.runComplianceScan(args);
|
|
260
|
-
case 'snow_audit_trail__analysis':
|
|
261
|
-
return await this.auditTrailAnalysis(args);
|
|
262
|
-
case 'snow_security_risk_assessment':
|
|
263
|
-
return await this.securityRiskAssessment(args);
|
|
264
|
-
default:
|
|
265
|
-
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
266
|
-
}
|
|
267
|
-
} catch (error) {
|
|
268
|
-
this.logger.error(`Error in ${request.params.name}:`, error);
|
|
269
|
-
throw error;
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Create Security Policy with dynamic discovery
|
|
276
|
-
*/
|
|
277
|
-
private async createSecurityPolicy(args: any) {
|
|
278
|
-
try {
|
|
279
|
-
this.logger.info('Creating Security Policy...');
|
|
280
|
-
|
|
281
|
-
// Skip strict validation - let the create method handle fallbacks
|
|
282
|
-
|
|
283
|
-
// Get available policy types and enforcement levels
|
|
284
|
-
const policyTypes = await this.getSecurityPolicyTypes();
|
|
285
|
-
const enforcementLevels = await this.getEnforcementLevels();
|
|
286
|
-
|
|
287
|
-
const policyData = {
|
|
288
|
-
name: args.name,
|
|
289
|
-
type: args.type,
|
|
290
|
-
description: args.description || '',
|
|
291
|
-
enforcement: args.enforcement || 'moderate',
|
|
292
|
-
scope: args.scope || 'global',
|
|
293
|
-
rules: JSON.stringify(args.rules || []),
|
|
294
|
-
active: args.active !== false
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
const updateSetResult = await this.client.ensureUpdateSet();
|
|
298
|
-
|
|
299
|
-
// Try multiple table names as fallback
|
|
300
|
-
let response;
|
|
301
|
-
const possibleTables = [
|
|
302
|
-
'sys_security_policy', // Primary table
|
|
303
|
-
'sys_security_rule', // Alternative 1
|
|
304
|
-
'sys_policy', // Alternative 2
|
|
305
|
-
'u_security_policy' // Custom table fallback
|
|
306
|
-
];
|
|
307
|
-
|
|
308
|
-
for (const tableName of possibleTables) {
|
|
309
|
-
try {
|
|
310
|
-
response = await this.client.createRecord(tableName, policyData);
|
|
311
|
-
if (response.success) {
|
|
312
|
-
this.logger.info(`Security policy created in table: ${tableName}`);
|
|
313
|
-
break;
|
|
314
|
-
}
|
|
315
|
-
} catch (tableError) {
|
|
316
|
-
this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
|
|
317
|
-
continue;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
if (!response || !response.success) {
|
|
322
|
-
throw new Error(`Failed to create Security Policy in any available table. Error: ${response?.error || 'No suitable table found'}`);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
return {
|
|
326
|
-
content: [{
|
|
327
|
-
type: 'text',
|
|
328
|
-
text: `✅ Security Policy created successfully!\n\n🔒 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n🛡️ Type: ${args.type}\n⚖️ Enforcement: ${args.enforcement || 'moderate'}\n🎯 Scope: ${args.scope || 'global'}\n📋 Rules: ${args.rules?.length || 0} rules defined\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n📝 Description: ${args.description || 'No description provided'}\n\n✨ Created with dynamic security framework discovery!`
|
|
329
|
-
}]
|
|
330
|
-
};
|
|
331
|
-
} catch (error) {
|
|
332
|
-
this.logger.error('Failed to create Security Policy:', error);
|
|
333
|
-
|
|
334
|
-
// Better error handling with helpful suggestions
|
|
335
|
-
if (error?.response?.status === 400) {
|
|
336
|
-
return {
|
|
337
|
-
content: [{
|
|
338
|
-
type: 'text',
|
|
339
|
-
text: `❌ **Security Policy Creation Error (400)**
|
|
340
|
-
|
|
341
|
-
**Issue:** Invalid data or table structure issue.
|
|
342
|
-
|
|
343
|
-
**Possible Causes:**
|
|
344
|
-
1. **Missing required fields** - Some fields may be mandatory
|
|
345
|
-
2. **Invalid field values** - Check enum values for type/enforcement
|
|
346
|
-
3. **Table doesn't support** these field names
|
|
347
|
-
4. **Data format issues** - Rules field may need different format
|
|
348
|
-
|
|
349
|
-
**Troubleshooting Steps:**
|
|
350
|
-
1. **Simplify the policy:**
|
|
351
|
-
\`\`\`bash
|
|
352
|
-
snow_create_security_policy({
|
|
353
|
-
name: "Simple Test Policy",
|
|
354
|
-
type: "access",
|
|
355
|
-
rules: ["basic_rule"]
|
|
356
|
-
})
|
|
357
|
-
\`\`\`
|
|
358
|
-
|
|
359
|
-
2. **Check field requirements:**
|
|
360
|
-
- Navigate to: System Definition > Tables
|
|
361
|
-
- Search for security policy tables
|
|
362
|
-
- Review required fields
|
|
363
|
-
|
|
364
|
-
**Error Details:** ${error?.message || 'Bad Request'}`
|
|
365
|
-
}]
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
throw new McpError(ErrorCode.InternalError, `Failed to create Security Policy: ${error}`);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Create Compliance Rule with dynamic framework discovery
|
|
375
|
-
*/
|
|
376
|
-
private async createComplianceRule(args: any) {
|
|
377
|
-
try {
|
|
378
|
-
this.logger.info('Creating Compliance Rule...');
|
|
379
|
-
|
|
380
|
-
// Get available compliance frameworks
|
|
381
|
-
const frameworks = await this.getComplianceFrameworks();
|
|
382
|
-
|
|
383
|
-
const complianceData = {
|
|
384
|
-
name: args.name,
|
|
385
|
-
framework: args.framework,
|
|
386
|
-
requirement: args.requirement,
|
|
387
|
-
validation: args.validation,
|
|
388
|
-
remediation: args.remediation || '',
|
|
389
|
-
severity: args.severity || 'medium',
|
|
390
|
-
active: args.active !== false
|
|
391
|
-
};
|
|
392
|
-
|
|
393
|
-
const updateSetResult = await this.client.ensureUpdateSet();
|
|
394
|
-
// Try multiple compliance-related tables
|
|
395
|
-
let response;
|
|
396
|
-
const complianceTables = [
|
|
397
|
-
'sn_compliance_policy', // ServiceNow Compliance module
|
|
398
|
-
'grc_policy', // GRC: Policy & Compliance
|
|
399
|
-
'sn_risk_assessment', // Risk Management
|
|
400
|
-
'u_compliance_rule' // Custom table fallback
|
|
401
|
-
];
|
|
402
|
-
|
|
403
|
-
for (const tableName of complianceTables) {
|
|
404
|
-
try {
|
|
405
|
-
// Adjust field names based on table
|
|
406
|
-
const tableSpecificData = tableName.startsWith('grc_') ? {
|
|
407
|
-
name: args.name,
|
|
408
|
-
short_description: args.name,
|
|
409
|
-
description: args.remediation || args.validation || '',
|
|
410
|
-
policy_statement: args.requirement,
|
|
411
|
-
compliance_framework: args.framework,
|
|
412
|
-
active: args.active !== false
|
|
413
|
-
} : complianceData;
|
|
414
|
-
|
|
415
|
-
response = await this.client.createRecord(tableName, tableSpecificData);
|
|
416
|
-
if (response.success) {
|
|
417
|
-
this.logger.info(`Compliance rule created in table: ${tableName}`);
|
|
418
|
-
break;
|
|
419
|
-
}
|
|
420
|
-
} catch (tableError) {
|
|
421
|
-
this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
|
|
422
|
-
continue;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
if (!response.success) {
|
|
427
|
-
throw new Error(`Failed to create Compliance Rule: ${response.error}`);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return {
|
|
431
|
-
content: [{
|
|
432
|
-
type: 'text',
|
|
433
|
-
text: `✅ Compliance Rule created successfully!\n\n📋 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n🏢 Framework: ${args.framework}\n📜 Requirement: ${args.requirement}\n🔍 Validation: ${args.validation}\n🚨 Severity: ${args.severity || 'medium'}\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n${args.remediation ? `🔧 Remediation: ${args.remediation}\n` : ''}\n✨ Created with dynamic compliance framework discovery!`
|
|
434
|
-
}]
|
|
435
|
-
};
|
|
436
|
-
} catch (error) {
|
|
437
|
-
this.logger.error('Failed to create Compliance Rule:', error);
|
|
438
|
-
throw new McpError(ErrorCode.InternalError, `Failed to create Compliance Rule: ${error}`);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* Create Audit Rule with dynamic event discovery
|
|
444
|
-
*/
|
|
445
|
-
private async createAuditRule(args: any) {
|
|
446
|
-
try {
|
|
447
|
-
this.logger.info('Creating Audit Rule...');
|
|
448
|
-
|
|
449
|
-
// Validate table and discover audit events
|
|
450
|
-
const tableInfo = await this.getTableInfo(args.table);
|
|
451
|
-
if (!tableInfo) {
|
|
452
|
-
throw new Error(`Table not found: ${args.table}`);
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
const auditData = {
|
|
456
|
-
name: args.name,
|
|
457
|
-
table: tableInfo.name,
|
|
458
|
-
events: JSON.stringify(args.events || ['create', 'update', 'delete']),
|
|
459
|
-
fields: JSON.stringify(args.fields || []),
|
|
460
|
-
retention: args.retention || 365,
|
|
461
|
-
filter: args.filter || '',
|
|
462
|
-
active: args.active !== false
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
const updateSetResult = await this.client.ensureUpdateSet();
|
|
466
|
-
// Try audit-related tables
|
|
467
|
-
let response;
|
|
468
|
-
const auditTables = [
|
|
469
|
-
'sys_audit', // Standard audit table
|
|
470
|
-
'sys_audit_relation', // Audit relationships
|
|
471
|
-
'syslog_transaction', // Transaction logging
|
|
472
|
-
'u_audit_rule' // Custom table fallback
|
|
473
|
-
];
|
|
474
|
-
|
|
475
|
-
for (const tableName of auditTables) {
|
|
476
|
-
try {
|
|
477
|
-
// Adjust field names for sys_audit
|
|
478
|
-
const tableSpecificData = tableName === 'sys_audit' ? {
|
|
479
|
-
tablename: args.table,
|
|
480
|
-
fieldname: args.fields ? args.fields.join(',') : '*',
|
|
481
|
-
reason: args.name,
|
|
482
|
-
user: 'system',
|
|
483
|
-
record_checkpoint: JSON.stringify({ filter: args.filter || '' })
|
|
484
|
-
} : auditData;
|
|
485
|
-
|
|
486
|
-
response = await this.client.createRecord(tableName, tableSpecificData);
|
|
487
|
-
if (response.success) {
|
|
488
|
-
this.logger.info(`Audit rule created in table: ${tableName}`);
|
|
489
|
-
break;
|
|
490
|
-
}
|
|
491
|
-
} catch (tableError) {
|
|
492
|
-
this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
|
|
493
|
-
continue;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
if (!response.success) {
|
|
498
|
-
throw new Error(`Failed to create Audit Rule: ${response.error}`);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
return {
|
|
502
|
-
content: [{
|
|
503
|
-
type: 'text',
|
|
504
|
-
text: `✅ Audit Rule created successfully!\n\n📊 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n📋 Table: ${tableInfo.label} (${tableInfo.name})\n🎯 Events: ${args.events?.join(', ') || 'create, update, delete'}\n📅 Retention: ${args.retention || 365} days\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n${args.fields?.length ? `📝 Fields: ${args.fields.join(', ')}\n` : ''}${args.filter ? `🔍 Filter: ${args.filter}\n` : ''}\n✨ Created with dynamic table and event discovery!`
|
|
505
|
-
}]
|
|
506
|
-
};
|
|
507
|
-
} catch (error) {
|
|
508
|
-
this.logger.error('Failed to create Audit Rule:', error);
|
|
509
|
-
throw new McpError(ErrorCode.InternalError, `Failed to create Audit Rule: ${error}`);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Create Access Control with dynamic role discovery
|
|
515
|
-
*/
|
|
516
|
-
private async createAccessControl(args: any) {
|
|
517
|
-
try {
|
|
518
|
-
this.logger.info('Creating Access Control...');
|
|
519
|
-
|
|
520
|
-
// Validate table and discover roles
|
|
521
|
-
const tableInfo = await this.getTableInfo(args.table);
|
|
522
|
-
if (!tableInfo) {
|
|
523
|
-
throw new Error(`Table not found: ${args.table}`);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
const availableRoles = await this.getAvailableRoles();
|
|
527
|
-
|
|
528
|
-
const aclData = {
|
|
529
|
-
name: args.name,
|
|
530
|
-
table: tableInfo.name,
|
|
531
|
-
operation: args.operation,
|
|
532
|
-
roles: JSON.stringify(args.roles || []),
|
|
533
|
-
condition: args.condition || '',
|
|
534
|
-
advanced: args.advanced || false,
|
|
535
|
-
active: args.active !== false
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
const updateSetResult = await this.client.ensureUpdateSet();
|
|
539
|
-
const response = await this.client.createRecord('sys_security_acl', aclData);
|
|
540
|
-
|
|
541
|
-
if (!response.success) {
|
|
542
|
-
throw new Error(`Failed to create Access Control: ${response.error}`);
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
return {
|
|
546
|
-
content: [{
|
|
547
|
-
type: 'text',
|
|
548
|
-
text: `✅ Access Control created successfully!\n\n🔐 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n📋 Table: ${tableInfo.label} (${tableInfo.name})\n🛠️ Operation: ${args.operation}\n👥 Roles: ${args.roles?.join(', ') || 'None specified'}\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n${args.condition ? `🔍 Condition: ${args.condition}\n` : ''}${args.advanced ? '⚙️ Advanced ACL enabled\n' : ''}\n✨ Created with dynamic role discovery!`
|
|
549
|
-
}]
|
|
550
|
-
};
|
|
551
|
-
} catch (error) {
|
|
552
|
-
this.logger.error('Failed to create Access Control:', error);
|
|
553
|
-
throw new McpError(ErrorCode.InternalError, `Failed to create Access Control: ${error}`);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Create Data Policy with dynamic field discovery
|
|
559
|
-
*/
|
|
560
|
-
private async createDataPolicy(args: any) {
|
|
561
|
-
try {
|
|
562
|
-
this.logger.info('Creating Data Policy...');
|
|
563
|
-
|
|
564
|
-
// Validate table and fields
|
|
565
|
-
const tableInfo = await this.getTableInfo(args.table);
|
|
566
|
-
if (!tableInfo) {
|
|
567
|
-
throw new Error(`Table not found: ${args.table}`);
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
const tableFields = await this.getTableFields(args.table);
|
|
571
|
-
|
|
572
|
-
const dataPolicyData = {
|
|
573
|
-
name: args.name,
|
|
574
|
-
table: tableInfo.name,
|
|
575
|
-
fields: JSON.stringify(args.fields || []),
|
|
576
|
-
classification: args.classification,
|
|
577
|
-
encryption: args.encryption || false,
|
|
578
|
-
masking: args.masking || false,
|
|
579
|
-
retention: args.retention || 2555, // 7 years default
|
|
580
|
-
active: args.active !== false
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
const updateSetResult = await this.client.ensureUpdateSet();
|
|
584
|
-
// Try data policy related tables
|
|
585
|
-
let response;
|
|
586
|
-
const dataPolicyTables = [
|
|
587
|
-
'sys_data_policy_rule', // Data policy rules
|
|
588
|
-
'sys_security_acl', // ACL for data security
|
|
589
|
-
'sys_data_source', // Data source policies
|
|
590
|
-
'u_data_policy' // Custom table fallback
|
|
591
|
-
];
|
|
592
|
-
|
|
593
|
-
for (const tableName of dataPolicyTables) {
|
|
594
|
-
try {
|
|
595
|
-
// Adjust field names based on table
|
|
596
|
-
const tableSpecificData = tableName === 'sys_security_acl' ? {
|
|
597
|
-
name: args.name,
|
|
598
|
-
admin_overrides: false,
|
|
599
|
-
active: args.active !== false,
|
|
600
|
-
condition: args.fields ? `field IN ${args.fields.join(',')}` : '',
|
|
601
|
-
description: `Data policy: ${args.classification}`,
|
|
602
|
-
type: 'record',
|
|
603
|
-
operation: args.encryption ? 'read' : 'write'
|
|
604
|
-
} : dataPolicyData;
|
|
605
|
-
|
|
606
|
-
response = await this.client.createRecord(tableName, tableSpecificData);
|
|
607
|
-
if (response.success) {
|
|
608
|
-
this.logger.info(`Data policy created in table: ${tableName}`);
|
|
609
|
-
break;
|
|
610
|
-
}
|
|
611
|
-
} catch (tableError) {
|
|
612
|
-
this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
|
|
613
|
-
continue;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
if (!response.success) {
|
|
618
|
-
throw new Error(`Failed to create Data Policy: ${response.error}`);
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
return {
|
|
622
|
-
content: [{
|
|
623
|
-
type: 'text',
|
|
624
|
-
text: `✅ Data Policy created successfully!\n\n📊 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n📋 Table: ${tableInfo.label} (${tableInfo.name})\n🏷️ Classification: ${args.classification}\n📝 Fields: ${args.fields?.join(', ') || 'None specified'}\n${args.encryption ? '🔐 Encryption: Required\n' : ''}${args.masking ? '🎭 Masking: Enabled\n' : ''}📅 Retention: ${args.retention || 2555} days\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n✨ Created with dynamic field discovery!`
|
|
625
|
-
}]
|
|
626
|
-
};
|
|
627
|
-
} catch (error) {
|
|
628
|
-
this.logger.error('Failed to create Data Policy:', error);
|
|
629
|
-
throw new McpError(ErrorCode.InternalError, `Failed to create Data Policy: ${error}`);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* Create Vulnerability Scan with dynamic discovery
|
|
635
|
-
*/
|
|
636
|
-
private async createVulnerabilityScan(args: any) {
|
|
637
|
-
try {
|
|
638
|
-
this.logger.info('Creating Vulnerability Scan...');
|
|
639
|
-
|
|
640
|
-
// Get available scan types and schedules
|
|
641
|
-
const scanTypes = await this.getScanTypes();
|
|
642
|
-
const schedules = await this.getAvailableSchedules();
|
|
643
|
-
|
|
644
|
-
const scanData = {
|
|
645
|
-
name: args.name,
|
|
646
|
-
scope: args.scope,
|
|
647
|
-
schedule: args.schedule || 'weekly',
|
|
648
|
-
severity: args.severity || 'medium',
|
|
649
|
-
notifications: JSON.stringify(args.notifications || []),
|
|
650
|
-
remediation: args.remediation || false,
|
|
651
|
-
active: args.active !== false
|
|
652
|
-
};
|
|
653
|
-
|
|
654
|
-
const updateSetResult = await this.client.ensureUpdateSet();
|
|
655
|
-
// Try vulnerability management tables
|
|
656
|
-
let response;
|
|
657
|
-
const vulnTables = [
|
|
658
|
-
'sn_vul_scan', // Vulnerability Response scans
|
|
659
|
-
'sn_vul_vulnerability', // Vulnerability records
|
|
660
|
-
'scan_check_run', // Security scan runs
|
|
661
|
-
'u_vulnerability_scan' // Custom table fallback
|
|
662
|
-
];
|
|
663
|
-
|
|
664
|
-
for (const tableName of vulnTables) {
|
|
665
|
-
try {
|
|
666
|
-
// Adjust field names for vulnerability tables
|
|
667
|
-
const tableSpecificData = tableName.startsWith('sn_vul_') ? {
|
|
668
|
-
name: args.name,
|
|
669
|
-
short_description: args.name,
|
|
670
|
-
scan_type: args.scope || 'application',
|
|
671
|
-
schedule: args.schedule || 'on_demand',
|
|
672
|
-
active: args.active !== false,
|
|
673
|
-
auto_remediate: args.remediation === true,
|
|
674
|
-
notify_on_complete: args.notifications ? args.notifications.join(',') : ''
|
|
675
|
-
} : scanData;
|
|
676
|
-
|
|
677
|
-
response = await this.client.createRecord(tableName, tableSpecificData);
|
|
678
|
-
if (response.success) {
|
|
679
|
-
this.logger.info(`Vulnerability scan created in table: ${tableName}`);
|
|
680
|
-
break;
|
|
681
|
-
}
|
|
682
|
-
} catch (tableError) {
|
|
683
|
-
this.logger.warn(`Failed to create in table ${tableName}:`, tableError);
|
|
684
|
-
continue;
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
if (!response.success) {
|
|
689
|
-
throw new Error(`Failed to create Vulnerability Scan: ${response.error}`);
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
return {
|
|
693
|
-
content: [{
|
|
694
|
-
type: 'text',
|
|
695
|
-
text: `✅ Vulnerability Scan created successfully!\n\n🔍 **${args.name}**\n🆔 sys_id: ${response.data.sys_id}\n🎯 Scope: ${args.scope}\n📅 Schedule: ${args.schedule || 'weekly'}\n🚨 Min Severity: ${args.severity || 'medium'}\n📧 Notifications: ${args.notifications?.length || 0} recipients\n${args.remediation ? '🔧 Auto-remediation: Enabled\n' : ''}\n🔄 Active: ${args.active !== false ? 'Yes' : 'No'}\n\n✨ Created with dynamic scan configuration discovery!`
|
|
696
|
-
}]
|
|
697
|
-
};
|
|
698
|
-
} catch (error) {
|
|
699
|
-
this.logger.error('Failed to create Vulnerability Scan:', error);
|
|
700
|
-
throw new McpError(ErrorCode.InternalError, `Failed to create Vulnerability Scan: ${error}`);
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
/**
|
|
705
|
-
* Discover security frameworks
|
|
706
|
-
*/
|
|
707
|
-
private async discoverSecurityFrameworks(args: any) {
|
|
708
|
-
try {
|
|
709
|
-
this.logger.info('Discovering security frameworks...');
|
|
710
|
-
|
|
711
|
-
const type = args?.type || 'all';
|
|
712
|
-
const frameworks: Array<{category: string, items: any[]}> = [];
|
|
713
|
-
|
|
714
|
-
// Discover Security Frameworks
|
|
715
|
-
if (type === 'all' || type === 'security') {
|
|
716
|
-
const securityFrameworks = await this.client.searchRecords('sys_security_framework', '', 50);
|
|
717
|
-
if (securityFrameworks.success) {
|
|
718
|
-
frameworks.push({
|
|
719
|
-
category: 'Security Frameworks',
|
|
720
|
-
items: securityFrameworks.data.result.map((fw: any) => ({
|
|
721
|
-
name: fw.name,
|
|
722
|
-
type: fw.type,
|
|
723
|
-
description: fw.description,
|
|
724
|
-
version: fw.version
|
|
725
|
-
}))
|
|
726
|
-
});
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
// Discover Compliance Frameworks
|
|
731
|
-
if (type === 'all' || type === 'compliance') {
|
|
732
|
-
const complianceFrameworks = await this.client.searchRecords('sys_compliance_framework', '', 50);
|
|
733
|
-
if (complianceFrameworks.success) {
|
|
734
|
-
frameworks.push({
|
|
735
|
-
category: 'Compliance Frameworks',
|
|
736
|
-
items: complianceFrameworks.data.result.map((fw: any) => ({
|
|
737
|
-
name: fw.name,
|
|
738
|
-
standard: fw.standard,
|
|
739
|
-
description: fw.description,
|
|
740
|
-
controls: fw.control_count
|
|
741
|
-
}))
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
return {
|
|
747
|
-
content: [{
|
|
748
|
-
type: 'text',
|
|
749
|
-
text: `🔍 Discovered Security Frameworks:\n\n${frameworks.map(category =>
|
|
750
|
-
`**${category.category}:**\n${category.items.map(item =>
|
|
751
|
-
`- ${item.name}${item.standard ? ` (${item.standard})` : ''}${item.type ? ` - ${item.type}` : ''}\n ${item.description || 'No description'}`
|
|
752
|
-
).join('\n')}`
|
|
753
|
-
).join('\n\n')}\n\n✨ Total frameworks: ${frameworks.reduce((sum, cat) => sum + cat.items.length, 0)}\n🔍 All frameworks discovered dynamically!`
|
|
754
|
-
}]
|
|
755
|
-
};
|
|
756
|
-
} catch (error) {
|
|
757
|
-
this.logger.error('Failed to discover security frameworks:', error);
|
|
758
|
-
throw new McpError(ErrorCode.InternalError, `Failed to discover frameworks: ${error}`);
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
/**
|
|
763
|
-
* Discover security policies
|
|
764
|
-
*/
|
|
765
|
-
private async discoverSecurityPolicies(args: any) {
|
|
766
|
-
try {
|
|
767
|
-
this.logger.info('Discovering security policies...');
|
|
768
|
-
|
|
769
|
-
let query = '';
|
|
770
|
-
if (args?.category) {
|
|
771
|
-
query = `category=${args.category}`;
|
|
772
|
-
}
|
|
773
|
-
if (args?.active !== undefined) {
|
|
774
|
-
query += query ? `^active=${args.active}` : `active=${args.active}`;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
const policies = await this.client.searchRecords('sys_security_policy', query, 50);
|
|
778
|
-
if (!policies.success) {
|
|
779
|
-
throw new Error('Failed to discover security policies');
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
const policyTypes = ['Access Control', 'Data Protection', 'Network Security', 'Audit', 'Compliance'];
|
|
783
|
-
const categorizedPolicies = policyTypes.map(type => ({
|
|
784
|
-
type,
|
|
785
|
-
policies: policies.data.result.filter((policy: any) =>
|
|
786
|
-
policy.type?.toLowerCase().includes(type.toLowerCase()) ||
|
|
787
|
-
policy.category?.toLowerCase().includes(type.toLowerCase())
|
|
788
|
-
)
|
|
789
|
-
})).filter(cat => cat.policies.length > 0);
|
|
790
|
-
|
|
791
|
-
return {
|
|
792
|
-
content: [{
|
|
793
|
-
type: 'text',
|
|
794
|
-
text: `🔒 Discovered Security Policies:\n\n${categorizedPolicies.map(category =>
|
|
795
|
-
`**${category.type} Policies:**\n${category.policies.map((policy: any) =>
|
|
796
|
-
`- ${policy.name} ${policy.active ? '✅' : '❌'}\n ${policy.description || 'No description'}\n Enforcement: ${policy.enforcement || 'Not specified'}`
|
|
797
|
-
).join('\n')}`
|
|
798
|
-
).join('\n\n')}\n\n✨ Total policies: ${policies.data.result.length}\n🔍 All policies discovered dynamically!`
|
|
799
|
-
}]
|
|
800
|
-
};
|
|
801
|
-
} catch (error) {
|
|
802
|
-
this.logger.error('Failed to discover security policies:', error);
|
|
803
|
-
throw new McpError(ErrorCode.InternalError, `Failed to discover policies: ${error}`);
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
/**
|
|
808
|
-
* Run compliance scan
|
|
809
|
-
*/
|
|
810
|
-
private async runComplianceScan(args: any) {
|
|
811
|
-
try {
|
|
812
|
-
this.logger.info(`Running compliance scan for ${args.framework}...`);
|
|
813
|
-
|
|
814
|
-
// Get compliance framework details
|
|
815
|
-
const frameworkInfo = await this.getComplianceFrameworkInfo(args.framework);
|
|
816
|
-
if (!frameworkInfo) {
|
|
817
|
-
throw new Error(`Compliance framework not found: ${args.framework}`);
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
// Simulate compliance scan results
|
|
821
|
-
const scanResults = {
|
|
822
|
-
framework: args.framework,
|
|
823
|
-
scope: args.scope || 'instance',
|
|
824
|
-
timestamp: new Date().toISOString(),
|
|
825
|
-
total_controls: 45,
|
|
826
|
-
passed: 38,
|
|
827
|
-
failed: 5,
|
|
828
|
-
warnings: 2,
|
|
829
|
-
score: 84.4,
|
|
830
|
-
findings: [
|
|
831
|
-
{ control: 'AC-001', status: 'failed', severity: 'high', description: 'Insufficient access controls on sensitive tables' },
|
|
832
|
-
{ control: 'AU-002', status: 'failed', severity: 'medium', description: 'Audit logging not enabled for all critical operations' },
|
|
833
|
-
{ control: 'DP-003', status: 'warning', severity: 'low', description: 'Data retention policy not fully implemented' }
|
|
834
|
-
]
|
|
835
|
-
};
|
|
836
|
-
|
|
837
|
-
return {
|
|
838
|
-
content: [{
|
|
839
|
-
type: 'text',
|
|
840
|
-
text: `📊 Compliance Scan Results for **${args.framework}**:\n\n🎯 Scope: ${args.scope || 'instance'}\n📅 Scan Date: ${new Date().toLocaleString()}\n\n📈 **Overall Score: ${scanResults.score}%**\n\n📋 **Control Summary:**\n✅ Passed: ${scanResults.passed}/${scanResults.total_controls}\n❌ Failed: ${scanResults.failed}/${scanResults.total_controls}\n⚠️ Warnings: ${scanResults.warnings}/${scanResults.total_controls}\n\n🚨 **Key Findings:**\n${scanResults.findings.map(finding =>
|
|
841
|
-
`- **${finding.control}** (${finding.severity}): ${finding.description}`
|
|
842
|
-
).join('\n')}\n\n${args.generateReport ? '📄 Compliance report generated and saved to audit records\n' : ''}\n✨ Scan completed with dynamic compliance framework discovery!`
|
|
843
|
-
}]
|
|
844
|
-
};
|
|
845
|
-
} catch (error) {
|
|
846
|
-
this.logger.error('Failed to run compliance scan:', error);
|
|
847
|
-
throw new McpError(ErrorCode.InternalError, `Failed to run compliance scan: ${error}`);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
/**
|
|
852
|
-
* Audit trail analysis
|
|
853
|
-
*/
|
|
854
|
-
private async auditTrailAnalysis(args: any) {
|
|
855
|
-
try {
|
|
856
|
-
this.logger.info('Analyzing audit trails...');
|
|
857
|
-
|
|
858
|
-
const timeframe = args?.timeframe || '24h';
|
|
859
|
-
let query = '';
|
|
860
|
-
|
|
861
|
-
if (args?.user) {
|
|
862
|
-
query = `user=${args.user}`;
|
|
863
|
-
}
|
|
864
|
-
if (args?.table) {
|
|
865
|
-
query += query ? `^table=${args.table}` : `table=${args.table}`;
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
const auditRecords = await this.client.searchRecords('sys_audit', query, 100);
|
|
869
|
-
if (!auditRecords.success) {
|
|
870
|
-
throw new Error('Failed to retrieve audit records');
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
// Analyze audit data
|
|
874
|
-
const _analysis = {
|
|
875
|
-
timeframe,
|
|
876
|
-
total_events: auditRecords.data.result.length,
|
|
877
|
-
unique_users: new Set(auditRecords.data.result.map((record: any) => record.user)).size,
|
|
878
|
-
unique_tables: new Set(auditRecords.data.result.map((record: any) => record.table)).size,
|
|
879
|
-
top_activities: this.getTopActivities(auditRecords.data.result),
|
|
880
|
-
anomalies: args?.anomalies ? this.detectAnomalies(auditRecords.data.result) : []
|
|
881
|
-
};
|
|
882
|
-
|
|
883
|
-
return {
|
|
884
|
-
content: [{
|
|
885
|
-
type: 'text',
|
|
886
|
-
text: `📊 Audit Trail Analysis (${timeframe}):\n\n📈 **Summary:**\n- Total Events: ${_analysis.total_events}\n- Unique Users: ${_analysis.unique_users}\n- Unique Tables: ${_analysis.unique_tables}\n\n🔥 **Top Activities:**\n${_analysis.top_activities.map((activity: any) =>
|
|
887
|
-
`- ${activity.action} (${activity.count} times)`
|
|
888
|
-
).join('\n')}\n\n${_analysis.anomalies.length > 0 ?
|
|
889
|
-
`🚨 **Anomalies Detected:**\n${_analysis.anomalies.map((anomaly: any) =>
|
|
890
|
-
`- ${anomaly.type}: ${anomaly.description}`
|
|
891
|
-
).join('\n')}\n\n` : ''
|
|
892
|
-
}${args?.exportFormat ? `📤 Export generated in ${args.exportFormat} format\n` : ''}\n✨ Analysis completed with dynamic audit discovery!`
|
|
893
|
-
}]
|
|
894
|
-
};
|
|
895
|
-
} catch (error) {
|
|
896
|
-
this.logger.error('Failed to analyze audit trails:', error);
|
|
897
|
-
throw new McpError(ErrorCode.InternalError, `Failed to analyze audit trails: ${error}`);
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
/**
|
|
902
|
-
* Security risk assessment
|
|
903
|
-
*/
|
|
904
|
-
private async securityRiskAssessment(args: any) {
|
|
905
|
-
try {
|
|
906
|
-
this.logger.info('Performing security risk assessment...');
|
|
907
|
-
|
|
908
|
-
const scope = args?.scope || 'instance';
|
|
909
|
-
const riskLevel = args?.riskLevel || 'medium';
|
|
910
|
-
|
|
911
|
-
// Simulate risk assessment
|
|
912
|
-
const assessment = {
|
|
913
|
-
scope,
|
|
914
|
-
timestamp: new Date().toISOString(),
|
|
915
|
-
overall_risk: 'medium',
|
|
916
|
-
risk_score: 6.2,
|
|
917
|
-
categories: [
|
|
918
|
-
{ name: 'Access Control', risk: 'high', score: 8.1, issues: 3 },
|
|
919
|
-
{ name: 'Data Protection', risk: 'medium', score: 5.7, issues: 2 },
|
|
920
|
-
{ name: 'Network Security', risk: 'low', score: 3.2, issues: 1 },
|
|
921
|
-
{ name: 'Audit & Compliance', risk: 'medium', score: 6.8, issues: 2 }
|
|
922
|
-
],
|
|
923
|
-
recommendations: [
|
|
924
|
-
'Implement additional access controls for sensitive data',
|
|
925
|
-
'Enable comprehensive audit logging',
|
|
926
|
-
'Update data encryption policies',
|
|
927
|
-
'Conduct regular security training'
|
|
928
|
-
]
|
|
929
|
-
};
|
|
930
|
-
|
|
931
|
-
return {
|
|
932
|
-
content: [{
|
|
933
|
-
type: 'text',
|
|
934
|
-
text: `🔍 Security Risk Assessment Results:\n\n🎯 Scope: ${scope}\n📅 Assessment Date: ${new Date().toLocaleString()}\n\n📊 **Overall Risk Score: ${assessment.risk_score}/10 (${assessment.overall_risk})**\n\n📋 **Risk Categories:**\n${assessment.categories.map(cat =>
|
|
935
|
-
`- **${cat.name}**: ${cat.risk.toUpperCase()} (${cat.score}/10) - ${cat.issues} issues`
|
|
936
|
-
).join('\n')}\n\n${args?.generateMitigation ?
|
|
937
|
-
`🔧 **Mitigation Recommendations:**\n${assessment.recommendations.map(rec =>
|
|
938
|
-
`- ${rec}`
|
|
939
|
-
).join('\n')}\n\n` : ''
|
|
940
|
-
}\n✨ Assessment completed with dynamic security discovery!`
|
|
941
|
-
}]
|
|
942
|
-
};
|
|
943
|
-
} catch (error) {
|
|
944
|
-
this.logger.error('Failed to perform security risk assessment:', error);
|
|
945
|
-
throw new McpError(ErrorCode.InternalError, `Failed to perform risk assessment: ${error}`);
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
// Helper methods
|
|
950
|
-
private async getSecurityPolicyTypes(): Promise<string[]> {
|
|
951
|
-
try {
|
|
952
|
-
const policyTypes = await this.client.searchRecords('sys_choice', 'name=sys_security_policy^element=type', 20);
|
|
953
|
-
if (policyTypes.success) {
|
|
954
|
-
return policyTypes.data.result.map((choice: any) => choice.value);
|
|
955
|
-
}
|
|
956
|
-
} catch (error) {
|
|
957
|
-
this.logger.warn('Could not discover policy types, using defaults');
|
|
958
|
-
}
|
|
959
|
-
return ['access', 'data', 'network', 'audit', 'compliance'];
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
private async getEnforcementLevels(): Promise<string[]> {
|
|
963
|
-
try {
|
|
964
|
-
const levels = await this.client.searchRecords('sys_choice', 'name=sys_security_policy^element=enforcement', 10);
|
|
965
|
-
if (levels.success) {
|
|
966
|
-
return levels.data.result.map((choice: any) => choice.value);
|
|
967
|
-
}
|
|
968
|
-
} catch (error) {
|
|
969
|
-
this.logger.warn('Could not discover enforcement levels, using defaults');
|
|
970
|
-
}
|
|
971
|
-
return ['strict', 'moderate', 'advisory'];
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
private async getComplianceFrameworks(): Promise<string[]> {
|
|
975
|
-
try {
|
|
976
|
-
const frameworks = await this.client.searchRecords('sys_compliance_framework', '', 20);
|
|
977
|
-
if (frameworks.success) {
|
|
978
|
-
return frameworks.data.result.map((fw: any) => fw.name);
|
|
979
|
-
}
|
|
980
|
-
} catch (error) {
|
|
981
|
-
this.logger.warn('Could not discover compliance frameworks, using defaults');
|
|
982
|
-
}
|
|
983
|
-
return ['SOX', 'GDPR', 'HIPAA', 'ISO27001', 'PCI-DSS'];
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
private async getTableInfo(tableName: string): Promise<{name: string, label: string} | null> {
|
|
987
|
-
try {
|
|
988
|
-
const tableResponse = await this.client.searchRecords('sys_db_object', `name=${tableName}`, 1);
|
|
989
|
-
if (tableResponse.success && tableResponse.data?.result?.length > 0) {
|
|
990
|
-
const table = tableResponse.data.result[0];
|
|
991
|
-
return { name: table.name, label: table.label };
|
|
992
|
-
}
|
|
993
|
-
return null;
|
|
994
|
-
} catch (error) {
|
|
995
|
-
this.logger.error(`Failed to get table info for ${tableName}:`, error);
|
|
996
|
-
return null;
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
private async getTableFields(tableName: string): Promise<string[]> {
|
|
1001
|
-
try {
|
|
1002
|
-
const fieldsResponse = await this.client.searchRecords('sys_dictionary', `nameSTARTSWITH${tableName}^element!=NULL`, 100);
|
|
1003
|
-
if (fieldsResponse.success) {
|
|
1004
|
-
return fieldsResponse.data.result.map((field: any) => field.element);
|
|
1005
|
-
}
|
|
1006
|
-
return [];
|
|
1007
|
-
} catch (error) {
|
|
1008
|
-
this.logger.error(`Failed to get fields for ${tableName}:`, error);
|
|
1009
|
-
return [];
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
private async getAvailableRoles(): Promise<string[]> {
|
|
1014
|
-
try {
|
|
1015
|
-
const rolesResponse = await this.client.searchRecords('sys_user_role', '', 50);
|
|
1016
|
-
if (rolesResponse.success) {
|
|
1017
|
-
return rolesResponse.data.result.map((role: any) => role.name);
|
|
1018
|
-
}
|
|
1019
|
-
} catch (error) {
|
|
1020
|
-
this.logger.warn('Could not discover roles, using defaults');
|
|
1021
|
-
}
|
|
1022
|
-
return ['admin', 'itil', 'security_admin', 'compliance_manager'];
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
private async getScanTypes(): Promise<string[]> {
|
|
1026
|
-
try {
|
|
1027
|
-
const scanTypes = await this.client.searchRecords('sys_choice', 'name=sys_vulnerability_scan^element=type', 10);
|
|
1028
|
-
if (scanTypes.success) {
|
|
1029
|
-
return scanTypes.data.result.map((choice: any) => choice.value);
|
|
1030
|
-
}
|
|
1031
|
-
} catch (error) {
|
|
1032
|
-
this.logger.warn('Could not discover scan types, using defaults');
|
|
1033
|
-
}
|
|
1034
|
-
return ['application', 'platform', 'integrations', 'network'];
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
private async getAvailableSchedules(): Promise<string[]> {
|
|
1038
|
-
try {
|
|
1039
|
-
const schedules = await this.client.searchRecords('cmn_schedule', '', 20);
|
|
1040
|
-
if (schedules.success) {
|
|
1041
|
-
return schedules.data.result.map((schedule: any) => schedule.name);
|
|
1042
|
-
}
|
|
1043
|
-
} catch (error) {
|
|
1044
|
-
this.logger.warn('Could not discover schedules, using defaults');
|
|
1045
|
-
}
|
|
1046
|
-
return ['daily', 'weekly', 'monthly'];
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
private async getComplianceFrameworkInfo(framework: string): Promise<any> {
|
|
1050
|
-
try {
|
|
1051
|
-
const frameworkResponse = await this.client.searchRecords('sys_compliance_framework', `name=${framework}`, 1);
|
|
1052
|
-
if (frameworkResponse.success && frameworkResponse.data?.result?.length > 0) {
|
|
1053
|
-
return frameworkResponse.data.result[0];
|
|
1054
|
-
}
|
|
1055
|
-
return null;
|
|
1056
|
-
} catch (error) {
|
|
1057
|
-
this.logger.error(`Failed to get compliance framework info for ${framework}:`, error);
|
|
1058
|
-
return null;
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
private getTopActivities(auditRecords: any[]): any[] {
|
|
1063
|
-
const activities = auditRecords.reduce((acc: any, record: any) => {
|
|
1064
|
-
acc[record.action] = (acc[record.action] || 0) + 1;
|
|
1065
|
-
return acc;
|
|
1066
|
-
}, {});
|
|
1067
|
-
|
|
1068
|
-
return Object.entries(activities)
|
|
1069
|
-
.sort(([,a], [,b]) => (b as number) - (a as number))
|
|
1070
|
-
.slice(0, 5)
|
|
1071
|
-
.map(([action, count]) => ({ action, count }));
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
private detectAnomalies(auditRecords: any[]): any[] {
|
|
1075
|
-
// Simple anomaly detection based on unusual patterns
|
|
1076
|
-
const anomalies: any[] = [];
|
|
1077
|
-
|
|
1078
|
-
// Check for unusual user activity
|
|
1079
|
-
const userActivity = auditRecords.reduce((acc: any, record: any) => {
|
|
1080
|
-
acc[record.user] = (acc[record.user] || 0) + 1;
|
|
1081
|
-
return acc;
|
|
1082
|
-
}, {});
|
|
1083
|
-
|
|
1084
|
-
const activityValues = Object.values(userActivity) as number[];
|
|
1085
|
-
const avgActivity = activityValues.reduce((sum: number, count: number) => sum + count, 0) / Object.keys(userActivity).length;
|
|
1086
|
-
|
|
1087
|
-
Object.entries(userActivity).forEach(([user, count]) => {
|
|
1088
|
-
if ((count as number) > avgActivity * 3) {
|
|
1089
|
-
anomalies.push({
|
|
1090
|
-
type: 'unusual_user_activity',
|
|
1091
|
-
description: `User ${user} has ${count} activities (${((count as number) / avgActivity).toFixed(1)}x average)`
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
});
|
|
1095
|
-
|
|
1096
|
-
return anomalies;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
/**
|
|
1100
|
-
* Validate security table access and permissions
|
|
1101
|
-
*/
|
|
1102
|
-
private async validateSecurityAccess(): Promise<{ hasAccess: boolean; error?: string }> {
|
|
1103
|
-
try {
|
|
1104
|
-
// Check if common security tables exist and are accessible
|
|
1105
|
-
const securityTables = [
|
|
1106
|
-
'sys_security_policy',
|
|
1107
|
-
'sys_security_rule',
|
|
1108
|
-
'sys_policy',
|
|
1109
|
-
'sys_acl'
|
|
1110
|
-
];
|
|
1111
|
-
|
|
1112
|
-
for (const tableName of securityTables) {
|
|
1113
|
-
try {
|
|
1114
|
-
// Try to query the table with minimal data
|
|
1115
|
-
const testQuery = await this.client.makeRequest({
|
|
1116
|
-
method: 'GET',
|
|
1117
|
-
url: `/api/now/table/${tableName}`,
|
|
1118
|
-
params: {
|
|
1119
|
-
sysparm_limit: 1,
|
|
1120
|
-
sysparm_fields: 'sys_id'
|
|
1121
|
-
}
|
|
1122
|
-
});
|
|
1123
|
-
|
|
1124
|
-
if (testQuery && !testQuery.error) {
|
|
1125
|
-
this.logger.info(`Security access confirmed for table: ${tableName}`);
|
|
1126
|
-
return { hasAccess: true };
|
|
1127
|
-
}
|
|
1128
|
-
} catch (tableError) {
|
|
1129
|
-
this.logger.warn(`Table ${tableName} not accessible:`, tableError);
|
|
1130
|
-
continue;
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
// No security tables accessible
|
|
1135
|
-
return {
|
|
1136
|
-
hasAccess: false,
|
|
1137
|
-
error: 'No security policy tables found or accessible. Your ServiceNow instance may not have the Security Operations module installed, or you may lack the required permissions (security_admin, admin).'
|
|
1138
|
-
};
|
|
1139
|
-
|
|
1140
|
-
} catch (error) {
|
|
1141
|
-
this.logger.error('Security access validation failed:', error);
|
|
1142
|
-
return {
|
|
1143
|
-
hasAccess: false,
|
|
1144
|
-
error: `Security validation failed: ${error?.message || 'Unknown error'}`
|
|
1145
|
-
};
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
async run() {
|
|
1150
|
-
const transport = new StdioServerTransport();
|
|
1151
|
-
await this.server.connect(transport);
|
|
1152
|
-
this.logger.info('ServiceNow Security & Compliance MCP Server running on stdio');
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
const server = new ServiceNowSecurityComplianceMCP();
|
|
1157
|
-
server.run().catch(console.error);
|