@cdot65/prisma-airs-cli 1.0.0
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/README.md +42 -0
- package/dist/airs/management.d.ts +58 -0
- package/dist/airs/management.d.ts.map +1 -0
- package/dist/airs/management.js +287 -0
- package/dist/airs/management.js.map +1 -0
- package/dist/airs/modelsecurity.d.ts +74 -0
- package/dist/airs/modelsecurity.d.ts.map +1 -0
- package/dist/airs/modelsecurity.js +337 -0
- package/dist/airs/modelsecurity.js.map +1 -0
- package/dist/airs/promptsets.d.ts +50 -0
- package/dist/airs/promptsets.d.ts.map +1 -0
- package/dist/airs/promptsets.js +133 -0
- package/dist/airs/promptsets.js.map +1 -0
- package/dist/airs/redteam.d.ts +45 -0
- package/dist/airs/redteam.d.ts.map +1 -0
- package/dist/airs/redteam.js +219 -0
- package/dist/airs/redteam.js.map +1 -0
- package/dist/airs/runtime.d.ts +27 -0
- package/dist/airs/runtime.d.ts.map +1 -0
- package/dist/airs/runtime.js +158 -0
- package/dist/airs/runtime.js.map +1 -0
- package/dist/airs/scanner.d.ts +22 -0
- package/dist/airs/scanner.d.ts.map +1 -0
- package/dist/airs/scanner.js +62 -0
- package/dist/airs/scanner.js.map +1 -0
- package/dist/airs/types.d.ts +683 -0
- package/dist/airs/types.d.ts.map +1 -0
- package/dist/airs/types.js +6 -0
- package/dist/airs/types.js.map +1 -0
- package/dist/audit/evaluator.d.ts +17 -0
- package/dist/audit/evaluator.d.ts.map +1 -0
- package/dist/audit/evaluator.js +82 -0
- package/dist/audit/evaluator.js.map +1 -0
- package/dist/audit/report.d.ts +38 -0
- package/dist/audit/report.d.ts.map +1 -0
- package/dist/audit/report.js +141 -0
- package/dist/audit/report.js.map +1 -0
- package/dist/audit/runner.d.ts +18 -0
- package/dist/audit/runner.d.ts.map +1 -0
- package/dist/audit/runner.js +60 -0
- package/dist/audit/runner.js.map +1 -0
- package/dist/audit/types.d.ts +53 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +5 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cli/bulk-scan-state.d.ts +15 -0
- package/dist/cli/bulk-scan-state.d.ts.map +1 -0
- package/dist/cli/bulk-scan-state.js +20 -0
- package/dist/cli/bulk-scan-state.js.map +1 -0
- package/dist/cli/commands/audit.d.ts +4 -0
- package/dist/cli/commands/audit.d.ts.map +1 -0
- package/dist/cli/commands/audit.js +113 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +4 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +231 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/list.d.ts +4 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +23 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/modelsecurity.d.ts +4 -0
- package/dist/cli/commands/modelsecurity.d.ts.map +1 -0
- package/dist/cli/commands/modelsecurity.js +499 -0
- package/dist/cli/commands/modelsecurity.js.map +1 -0
- package/dist/cli/commands/redteam.d.ts +4 -0
- package/dist/cli/commands/redteam.d.ts.map +1 -0
- package/dist/cli/commands/redteam.js +630 -0
- package/dist/cli/commands/redteam.js.map +1 -0
- package/dist/cli/commands/report.d.ts +4 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +116 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/resume.d.ts +4 -0
- package/dist/cli/commands/resume.d.ts.map +1 -0
- package/dist/cli/commands/resume.js +138 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/runtime.d.ts +3 -0
- package/dist/cli/commands/runtime.d.ts.map +1 -0
- package/dist/cli/commands/runtime.js +582 -0
- package/dist/cli/commands/runtime.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +46 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/parse-input.d.ts +9 -0
- package/dist/cli/parse-input.d.ts.map +1 -0
- package/dist/cli/parse-input.js +109 -0
- package/dist/cli/parse-input.js.map +1 -0
- package/dist/cli/prompts.d.ts +9 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +90 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/cli/renderer/audit.d.ts +8 -0
- package/dist/cli/renderer/audit.d.ts.map +1 -0
- package/dist/cli/renderer/audit.js +44 -0
- package/dist/cli/renderer/audit.js.map +1 -0
- package/dist/cli/renderer/common.d.ts +3 -0
- package/dist/cli/renderer/common.d.ts.map +1 -0
- package/dist/cli/renderer/common.js +6 -0
- package/dist/cli/renderer/common.js.map +1 -0
- package/dist/cli/renderer/generate.d.ts +29 -0
- package/dist/cli/renderer/generate.d.ts.map +1 -0
- package/dist/cli/renderer/generate.js +132 -0
- package/dist/cli/renderer/generate.js.map +1 -0
- package/dist/cli/renderer/index.d.ts +7 -0
- package/dist/cli/renderer/index.d.ts.map +1 -0
- package/dist/cli/renderer/index.js +7 -0
- package/dist/cli/renderer/index.js.map +1 -0
- package/dist/cli/renderer/modelsecurity.d.ts +34 -0
- package/dist/cli/renderer/modelsecurity.d.ts.map +1 -0
- package/dist/cli/renderer/modelsecurity.js +285 -0
- package/dist/cli/renderer/modelsecurity.js.map +1 -0
- package/dist/cli/renderer/redteam.d.ts +152 -0
- package/dist/cli/renderer/redteam.d.ts.map +1 -0
- package/dist/cli/renderer/redteam.js +294 -0
- package/dist/cli/renderer/redteam.js.map +1 -0
- package/dist/cli/renderer/runtime.d.ts +87 -0
- package/dist/cli/renderer/runtime.d.ts.map +1 -0
- package/dist/cli/renderer/runtime.js +230 -0
- package/dist/cli/renderer/runtime.js.map +1 -0
- package/dist/config/loader.d.ts +3 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +65 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +78 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +44 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/constraints.d.ts +18 -0
- package/dist/core/constraints.d.ts.map +1 -0
- package/dist/core/constraints.js +75 -0
- package/dist/core/constraints.js.map +1 -0
- package/dist/core/loop.d.ts +54 -0
- package/dist/core/loop.d.ts.map +1 -0
- package/dist/core/loop.js +462 -0
- package/dist/core/loop.js.map +1 -0
- package/dist/core/metrics.d.ts +13 -0
- package/dist/core/metrics.d.ts.map +1 -0
- package/dist/core/metrics.js +73 -0
- package/dist/core/metrics.js.map +1 -0
- package/dist/core/types.d.ts +175 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/prompts/analyze-results.d.ts +3 -0
- package/dist/llm/prompts/analyze-results.d.ts.map +1 -0
- package/dist/llm/prompts/analyze-results.js +52 -0
- package/dist/llm/prompts/analyze-results.js.map +1 -0
- package/dist/llm/prompts/generate-companion.d.ts +3 -0
- package/dist/llm/prompts/generate-companion.d.ts.map +1 -0
- package/dist/llm/prompts/generate-companion.js +42 -0
- package/dist/llm/prompts/generate-companion.js.map +1 -0
- package/dist/llm/prompts/generate-tests.d.ts +3 -0
- package/dist/llm/prompts/generate-tests.d.ts.map +1 -0
- package/dist/llm/prompts/generate-tests.js +46 -0
- package/dist/llm/prompts/generate-tests.js.map +1 -0
- package/dist/llm/prompts/generate-topic.d.ts +4 -0
- package/dist/llm/prompts/generate-topic.d.ts.map +1 -0
- package/dist/llm/prompts/generate-topic.js +41 -0
- package/dist/llm/prompts/generate-topic.js.map +1 -0
- package/dist/llm/prompts/improve-topic.d.ts +3 -0
- package/dist/llm/prompts/improve-topic.d.ts.map +1 -0
- package/dist/llm/prompts/improve-topic.js +77 -0
- package/dist/llm/prompts/improve-topic.js.map +1 -0
- package/dist/llm/prompts/simplify-topic.d.ts +3 -0
- package/dist/llm/prompts/simplify-topic.d.ts.map +1 -0
- package/dist/llm/prompts/simplify-topic.js +50 -0
- package/dist/llm/prompts/simplify-topic.js.map +1 -0
- package/dist/llm/provider.d.ts +21 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/provider.js +76 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/schemas.d.ts +97 -0
- package/dist/llm/schemas.d.ts.map +1 -0
- package/dist/llm/schemas.js +24 -0
- package/dist/llm/schemas.js.map +1 -0
- package/dist/llm/service.d.ts +30 -0
- package/dist/llm/service.d.ts.map +1 -0
- package/dist/llm/service.js +273 -0
- package/dist/llm/service.js.map +1 -0
- package/dist/memory/diff.d.ts +4 -0
- package/dist/memory/diff.d.ts.map +1 -0
- package/dist/memory/diff.js +24 -0
- package/dist/memory/diff.js.map +1 -0
- package/dist/memory/extractor.d.ts +15 -0
- package/dist/memory/extractor.d.ts.map +1 -0
- package/dist/memory/extractor.js +133 -0
- package/dist/memory/extractor.js.map +1 -0
- package/dist/memory/injector.d.ts +22 -0
- package/dist/memory/injector.d.ts.map +1 -0
- package/dist/memory/injector.js +90 -0
- package/dist/memory/injector.js.map +1 -0
- package/dist/memory/prompts/extract-learnings.d.ts +3 -0
- package/dist/memory/prompts/extract-learnings.d.ts.map +1 -0
- package/dist/memory/prompts/extract-learnings.js +40 -0
- package/dist/memory/prompts/extract-learnings.js.map +1 -0
- package/dist/memory/schemas.d.ts +63 -0
- package/dist/memory/schemas.d.ts.map +1 -0
- package/dist/memory/schemas.js +13 -0
- package/dist/memory/schemas.js.map +1 -0
- package/dist/memory/store.d.ts +28 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +103 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/memory/types.d.ts +55 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +6 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/persistence/store.d.ts +21 -0
- package/dist/persistence/store.d.ts.map +1 -0
- package/dist/persistence/store.js +77 -0
- package/dist/persistence/store.js.map +1 -0
- package/dist/persistence/types.d.ts +23 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +2 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/report/html.d.ts +6 -0
- package/dist/report/html.d.ts.map +1 -0
- package/dist/report/html.js +200 -0
- package/dist/report/html.js.map +1 -0
- package/dist/report/json.d.ts +11 -0
- package/dist/report/json.d.ts.map +1 -0
- package/dist/report/json.js +74 -0
- package/dist/report/json.js.map +1 -0
- package/dist/report/types.d.ts +58 -0
- package/dist/report/types.d.ts.map +1 -0
- package/dist/report/types.js +5 -0
- package/dist/report/types.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { RedTeamClient } from '@cdot65/prisma-airs-sdk';
|
|
2
|
+
const TERMINAL_STATUSES = new Set(['COMPLETED', 'PARTIALLY_COMPLETE', 'FAILED', 'ABORTED']);
|
|
3
|
+
/** Normalize an SDK job response into a RedTeamJob. */
|
|
4
|
+
function normalizeJob(raw) {
|
|
5
|
+
const target = raw.target;
|
|
6
|
+
return {
|
|
7
|
+
uuid: raw.uuid,
|
|
8
|
+
name: raw.name,
|
|
9
|
+
status: raw.status,
|
|
10
|
+
jobType: raw.job_type,
|
|
11
|
+
targetId: raw.target_id,
|
|
12
|
+
targetName: target?.name,
|
|
13
|
+
score: raw.score,
|
|
14
|
+
asr: raw.asr,
|
|
15
|
+
total: raw.total,
|
|
16
|
+
completed: raw.completed,
|
|
17
|
+
createdAt: raw.created_at,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Normalize an SDK target response into a RedTeamTargetDetail. */
|
|
21
|
+
function normalizeTargetDetail(raw) {
|
|
22
|
+
return {
|
|
23
|
+
uuid: raw.uuid,
|
|
24
|
+
name: raw.name,
|
|
25
|
+
status: raw.status,
|
|
26
|
+
targetType: raw.target_type,
|
|
27
|
+
active: raw.active,
|
|
28
|
+
connectionParams: raw.connection_params,
|
|
29
|
+
background: raw.background,
|
|
30
|
+
additionalContext: raw.additional_context,
|
|
31
|
+
metadata: raw.metadata,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Wraps the SDK's RedTeamClient to implement RedTeamService.
|
|
36
|
+
* Provides scan creation, status polling, report retrieval, and target/category listing.
|
|
37
|
+
*/
|
|
38
|
+
export class SdkRedTeamService {
|
|
39
|
+
client;
|
|
40
|
+
constructor(opts) {
|
|
41
|
+
this.client = new RedTeamClient(opts);
|
|
42
|
+
}
|
|
43
|
+
async listTargets() {
|
|
44
|
+
const response = await this.client.targets.list();
|
|
45
|
+
return response.data.map((t) => ({
|
|
46
|
+
uuid: t.uuid,
|
|
47
|
+
name: t.name,
|
|
48
|
+
status: t.status,
|
|
49
|
+
targetType: t.target_type,
|
|
50
|
+
active: t.active,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
async getTarget(uuid) {
|
|
54
|
+
const response = await this.client.targets.get(uuid);
|
|
55
|
+
return normalizeTargetDetail(response);
|
|
56
|
+
}
|
|
57
|
+
async createTarget(request, opts) {
|
|
58
|
+
const response = await this.client.targets.create(request, opts);
|
|
59
|
+
return normalizeTargetDetail(response);
|
|
60
|
+
}
|
|
61
|
+
async updateTarget(uuid, request, opts) {
|
|
62
|
+
const response = await this.client.targets.update(uuid, request, opts);
|
|
63
|
+
return normalizeTargetDetail(response);
|
|
64
|
+
}
|
|
65
|
+
async deleteTarget(uuid) {
|
|
66
|
+
await this.client.targets.delete(uuid);
|
|
67
|
+
}
|
|
68
|
+
async probeTarget(request) {
|
|
69
|
+
const response = await this.client.targets.probe(request);
|
|
70
|
+
return response;
|
|
71
|
+
}
|
|
72
|
+
async getTargetProfile(uuid) {
|
|
73
|
+
const response = await this.client.targets.getProfile(uuid);
|
|
74
|
+
return response;
|
|
75
|
+
}
|
|
76
|
+
async updateTargetProfile(uuid, request) {
|
|
77
|
+
const response = await this.client.targets.updateProfile(uuid, request);
|
|
78
|
+
return response;
|
|
79
|
+
}
|
|
80
|
+
async createScan(request) {
|
|
81
|
+
let jobMetadata = {};
|
|
82
|
+
if (request.jobType === 'STATIC' && request.categories) {
|
|
83
|
+
jobMetadata = { categories: request.categories };
|
|
84
|
+
}
|
|
85
|
+
else if (request.jobType === 'CUSTOM' && request.customPromptSets) {
|
|
86
|
+
jobMetadata = {
|
|
87
|
+
custom_prompt_sets: request.customPromptSets,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const response = await this.client.scans.create({
|
|
91
|
+
name: request.name,
|
|
92
|
+
target: { uuid: request.targetUuid },
|
|
93
|
+
job_type: request.jobType,
|
|
94
|
+
job_metadata: jobMetadata,
|
|
95
|
+
});
|
|
96
|
+
return normalizeJob(response);
|
|
97
|
+
}
|
|
98
|
+
async getScan(jobId) {
|
|
99
|
+
const response = await this.client.scans.get(jobId);
|
|
100
|
+
return normalizeJob(response);
|
|
101
|
+
}
|
|
102
|
+
async listScans(opts) {
|
|
103
|
+
const sdkOpts = {};
|
|
104
|
+
if (opts?.status)
|
|
105
|
+
sdkOpts.status = opts.status;
|
|
106
|
+
if (opts?.jobType)
|
|
107
|
+
sdkOpts.job_type = opts.jobType;
|
|
108
|
+
if (opts?.targetId)
|
|
109
|
+
sdkOpts.target_id = opts.targetId;
|
|
110
|
+
if (opts?.limit)
|
|
111
|
+
sdkOpts.limit = opts.limit;
|
|
112
|
+
const response = await this.client.scans.list(sdkOpts);
|
|
113
|
+
return response.data.map(normalizeJob);
|
|
114
|
+
}
|
|
115
|
+
async abortScan(jobId) {
|
|
116
|
+
await this.client.scans.abort(jobId);
|
|
117
|
+
}
|
|
118
|
+
async getStaticReport(jobId) {
|
|
119
|
+
const raw = (await this.client.reports.getStaticReport(jobId));
|
|
120
|
+
const severityReport = raw.severity_report;
|
|
121
|
+
const stats = (severityReport?.stats ?? []);
|
|
122
|
+
const securityReport = raw.security_report;
|
|
123
|
+
const subCategories = (securityReport?.sub_categories ?? []);
|
|
124
|
+
return {
|
|
125
|
+
score: raw.score,
|
|
126
|
+
asr: raw.asr,
|
|
127
|
+
severityBreakdown: stats.map((s) => ({
|
|
128
|
+
severity: s.severity,
|
|
129
|
+
successful: (s.successful ?? 0),
|
|
130
|
+
failed: (s.failed ?? 0),
|
|
131
|
+
})),
|
|
132
|
+
reportSummary: raw.report_summary,
|
|
133
|
+
categories: subCategories.map((sc) => {
|
|
134
|
+
const successful = (sc.successful ?? 0);
|
|
135
|
+
const failed = (sc.failed ?? 0);
|
|
136
|
+
const total = (sc.total ?? successful + failed);
|
|
137
|
+
return {
|
|
138
|
+
id: sc.id,
|
|
139
|
+
displayName: sc.display_name,
|
|
140
|
+
asr: total > 0 ? (successful / total) * 100 : 0,
|
|
141
|
+
successful,
|
|
142
|
+
failed,
|
|
143
|
+
total,
|
|
144
|
+
};
|
|
145
|
+
}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async getCustomReport(jobId) {
|
|
149
|
+
const raw = (await this.client.customAttackReports.getReport(jobId));
|
|
150
|
+
const reports = (raw.custom_attack_reports ?? []);
|
|
151
|
+
return {
|
|
152
|
+
totalPrompts: raw.total_prompts,
|
|
153
|
+
totalAttacks: raw.total_attacks,
|
|
154
|
+
totalThreats: raw.total_threats,
|
|
155
|
+
failedAttacks: raw.failed_attacks,
|
|
156
|
+
score: raw.score,
|
|
157
|
+
asr: raw.asr,
|
|
158
|
+
promptSets: reports.map((r) => ({
|
|
159
|
+
promptSetId: r.prompt_set_id,
|
|
160
|
+
promptSetName: r.prompt_set_name,
|
|
161
|
+
totalPrompts: r.total_prompts,
|
|
162
|
+
totalAttacks: r.total_attacks,
|
|
163
|
+
totalThreats: r.total_threats,
|
|
164
|
+
threatRate: r.threat_rate,
|
|
165
|
+
})),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
async listAttacks(jobId, opts) {
|
|
169
|
+
const response = await this.client.reports.listAttacks(jobId, opts);
|
|
170
|
+
return response.data.map((a) => ({
|
|
171
|
+
id: a.uuid,
|
|
172
|
+
name: a.attack_name,
|
|
173
|
+
severity: a.severity,
|
|
174
|
+
category: a.category,
|
|
175
|
+
subCategory: a.sub_category,
|
|
176
|
+
successful: a.successful,
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
async listCustomAttacks(jobId, opts) {
|
|
180
|
+
const response = await this.client.customAttackReports.listCustomAttacks(jobId, opts);
|
|
181
|
+
return response.data.map((a) => ({
|
|
182
|
+
promptId: a.prompt_id,
|
|
183
|
+
promptText: a.prompt_text,
|
|
184
|
+
goal: a.goal,
|
|
185
|
+
threat: (a.threat ?? false),
|
|
186
|
+
asr: a.asr,
|
|
187
|
+
promptSetName: a.prompt_set_name,
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
async getCategories() {
|
|
191
|
+
const response = (await this.client.scans.getCategories());
|
|
192
|
+
return response.map((c) => ({
|
|
193
|
+
id: c.id,
|
|
194
|
+
displayName: c.display_name,
|
|
195
|
+
description: c.description,
|
|
196
|
+
subCategories: (c.sub_categories ?? []).map((sc) => ({
|
|
197
|
+
id: sc.id,
|
|
198
|
+
displayName: sc.display_name,
|
|
199
|
+
description: sc.description,
|
|
200
|
+
})),
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
async waitForCompletion(jobId, onProgress, intervalMs = 5000) {
|
|
204
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
205
|
+
// eslint-disable-next-line no-constant-condition
|
|
206
|
+
while (true) {
|
|
207
|
+
const job = await this.getScan(jobId);
|
|
208
|
+
onProgress?.(job);
|
|
209
|
+
if (job.status === 'FAILED') {
|
|
210
|
+
throw new Error(`Scan ${jobId} failed`);
|
|
211
|
+
}
|
|
212
|
+
if (TERMINAL_STATUSES.has(job.status)) {
|
|
213
|
+
return job;
|
|
214
|
+
}
|
|
215
|
+
await delay(intervalMs);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=redteam.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redteam.js","sourceRoot":"","sources":["../../src/airs/redteam.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RuntimeScanResult, RuntimeService } from './types.js';
|
|
2
|
+
export interface PollRetryOptions {
|
|
3
|
+
/** Max retries per rate-limit error before giving up. Default: 5. */
|
|
4
|
+
maxRetries?: number;
|
|
5
|
+
/** Base delay in ms for exponential backoff. Default: 10000. */
|
|
6
|
+
baseDelayMs?: number;
|
|
7
|
+
/** Called on each retry with (attempt, delayMs). */
|
|
8
|
+
onRetry?: (attempt: number, delayMs: number) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class SdkRuntimeService implements RuntimeService {
|
|
11
|
+
private scanner;
|
|
12
|
+
constructor(apiKey: string);
|
|
13
|
+
scanPrompt(profileName: string, prompt: string, response?: string): Promise<RuntimeScanResult>;
|
|
14
|
+
submitBulkScan(profileName: string, prompts: string[], sessionId?: string): Promise<string[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Poll async scan results until all complete or fail.
|
|
17
|
+
*
|
|
18
|
+
* Note: The async query API (`queryByScanIds`) does not return `prompt`,
|
|
19
|
+
* `response`, `triggered`, or `detections` fields. These are set to
|
|
20
|
+
* defaults (`''`, `undefined`, `false`, `{}`) in the returned results.
|
|
21
|
+
* Use `scanPrompt()` (sync API) when these fields are needed.
|
|
22
|
+
*/
|
|
23
|
+
pollResults(scanIds: string[], intervalMs?: number, retryOpts?: PollRetryOptions): Promise<RuntimeScanResult[]>;
|
|
24
|
+
private processQueryResults;
|
|
25
|
+
static formatResultsCsv(results: RuntimeScanResult[]): string;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/airs/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOpE,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAUD,qBAAa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,OAAO,CAA+B;gBAElC,MAAM,EAAE,MAAM;IAKpB,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,CAAC;IAgCvB,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC;IAqBpB;;;;;;;OAOG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,SAA2B,EACrC,SAAS,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAqD/B,OAAO,CAAC,mBAAmB;IAsC3B,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM;CAQ9D"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { Content, init, Scanner } from '@cdot65/prisma-airs-sdk';
|
|
2
|
+
const BATCH_SIZE = 5;
|
|
3
|
+
const DEFAULT_POLL_INTERVAL_MS = 5000;
|
|
4
|
+
const DEFAULT_MAX_RETRIES = 5;
|
|
5
|
+
const DEFAULT_BASE_DELAY_MS = 10_000;
|
|
6
|
+
function isRateLimitError(err) {
|
|
7
|
+
if (err instanceof Error) {
|
|
8
|
+
const msg = err.message.toLowerCase();
|
|
9
|
+
return msg.includes('rate limit') || msg.includes('rate_limit') || msg.includes('429');
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
export class SdkRuntimeService {
|
|
14
|
+
scanner;
|
|
15
|
+
constructor(apiKey) {
|
|
16
|
+
init({ apiKey });
|
|
17
|
+
this.scanner = new Scanner();
|
|
18
|
+
}
|
|
19
|
+
async scanPrompt(profileName, prompt, response) {
|
|
20
|
+
const contentOpts = { prompt };
|
|
21
|
+
if (response)
|
|
22
|
+
contentOpts.response = response;
|
|
23
|
+
const content = new Content(contentOpts);
|
|
24
|
+
const res = await this.scanner.syncScan({ profile_name: profileName }, content, undefined);
|
|
25
|
+
const detected = res.prompt_detected ?? {};
|
|
26
|
+
// Runtime scanning aggregates all 6 detection types — intentionally broader than
|
|
27
|
+
// the guardrail loop's topic_violation-only signal. Runtime is a general-purpose
|
|
28
|
+
// firewall check, not topic-specific evaluation.
|
|
29
|
+
const triggered = !!(detected.topic_violation ||
|
|
30
|
+
detected.injection ||
|
|
31
|
+
detected.toxic_content ||
|
|
32
|
+
detected.dlp ||
|
|
33
|
+
detected.url_cats ||
|
|
34
|
+
detected.malicious_code);
|
|
35
|
+
return {
|
|
36
|
+
prompt,
|
|
37
|
+
response,
|
|
38
|
+
scanId: res.scan_id ?? '',
|
|
39
|
+
reportId: res.report_id ?? '',
|
|
40
|
+
action: res.action === 'block' ? 'block' : 'allow',
|
|
41
|
+
category: res.category ?? 'unknown',
|
|
42
|
+
triggered,
|
|
43
|
+
detections: detected,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async submitBulkScan(profileName, prompts, sessionId) {
|
|
47
|
+
const scanIds = [];
|
|
48
|
+
for (let i = 0; i < prompts.length; i += BATCH_SIZE) {
|
|
49
|
+
const batch = prompts.slice(i, i + BATCH_SIZE);
|
|
50
|
+
const scanObjects = batch.map((prompt, idx) => ({
|
|
51
|
+
req_id: i + idx,
|
|
52
|
+
scan_req: {
|
|
53
|
+
ai_profile: { profile_name: profileName },
|
|
54
|
+
contents: [{ prompt }],
|
|
55
|
+
...(sessionId ? { session_id: sessionId } : {}),
|
|
56
|
+
},
|
|
57
|
+
}));
|
|
58
|
+
const res = await this.scanner.asyncScan(scanObjects);
|
|
59
|
+
scanIds.push(res.scan_id);
|
|
60
|
+
}
|
|
61
|
+
return scanIds;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Poll async scan results until all complete or fail.
|
|
65
|
+
*
|
|
66
|
+
* Note: The async query API (`queryByScanIds`) does not return `prompt`,
|
|
67
|
+
* `response`, `triggered`, or `detections` fields. These are set to
|
|
68
|
+
* defaults (`''`, `undefined`, `false`, `{}`) in the returned results.
|
|
69
|
+
* Use `scanPrompt()` (sync API) when these fields are needed.
|
|
70
|
+
*/
|
|
71
|
+
async pollResults(scanIds, intervalMs = DEFAULT_POLL_INTERVAL_MS, retryOpts) {
|
|
72
|
+
const maxRetries = retryOpts?.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
73
|
+
const baseDelay = retryOpts?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;
|
|
74
|
+
const completed = new Map();
|
|
75
|
+
const pending = new Set(scanIds);
|
|
76
|
+
let retryLevel = 0;
|
|
77
|
+
while (pending.size > 0) {
|
|
78
|
+
// Query all pending IDs in batches of 5 per sweep
|
|
79
|
+
const pendingIds = [...pending];
|
|
80
|
+
let sweepCompleted = true;
|
|
81
|
+
for (let b = 0; b < pendingIds.length; b += 5) {
|
|
82
|
+
const batch = pendingIds.slice(b, b + 5);
|
|
83
|
+
let results;
|
|
84
|
+
try {
|
|
85
|
+
results = await this.scanner.queryByScanIds(batch);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if (isRateLimitError(err) && retryLevel < maxRetries) {
|
|
89
|
+
retryLevel++;
|
|
90
|
+
const delayMs = baseDelay * 2 ** (retryLevel - 1);
|
|
91
|
+
retryOpts?.onRetry?.(retryLevel, delayMs);
|
|
92
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
93
|
+
sweepCompleted = false;
|
|
94
|
+
break; // restart sweep from the beginning
|
|
95
|
+
}
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
this.processQueryResults(results, completed, pending);
|
|
99
|
+
// Small inter-batch delay to avoid hammering the API
|
|
100
|
+
if (b + 5 < pendingIds.length) {
|
|
101
|
+
const batchDelay = retryLevel > 0 ? baseDelay : Math.min(baseDelay, 1000);
|
|
102
|
+
await new Promise((resolve) => setTimeout(resolve, batchDelay));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Only decay retry level after a full sweep with no rate limit errors
|
|
106
|
+
if (sweepCompleted && retryLevel > 0) {
|
|
107
|
+
retryLevel = Math.max(0, retryLevel - 1);
|
|
108
|
+
}
|
|
109
|
+
if (pending.size > 0) {
|
|
110
|
+
const sweepDelay = retryLevel > 0 ? baseDelay * 2 ** retryLevel : intervalMs;
|
|
111
|
+
await new Promise((resolve) => setTimeout(resolve, sweepDelay));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return scanIds.map((id) => completed.get(id));
|
|
115
|
+
}
|
|
116
|
+
processQueryResults(results, completed, pending) {
|
|
117
|
+
for (const r of results) {
|
|
118
|
+
const id = r.scan_id ?? '';
|
|
119
|
+
const status = r.status ?? '';
|
|
120
|
+
if (status === 'COMPLETED' && r.result) {
|
|
121
|
+
const result = r.result;
|
|
122
|
+
completed.set(id, {
|
|
123
|
+
prompt: '', // not available from async API
|
|
124
|
+
response: undefined, // not available from async API
|
|
125
|
+
scanId: result.scan_id ?? id,
|
|
126
|
+
reportId: result.report_id ?? '',
|
|
127
|
+
action: result.action === 'block' ? 'block' : 'allow',
|
|
128
|
+
category: result.category ?? 'unknown',
|
|
129
|
+
triggered: false, // not available from async API — always false
|
|
130
|
+
detections: {}, // not available from async API
|
|
131
|
+
});
|
|
132
|
+
pending.delete(id);
|
|
133
|
+
}
|
|
134
|
+
else if (status === 'FAILED') {
|
|
135
|
+
completed.set(id, {
|
|
136
|
+
prompt: '', // not available from async API
|
|
137
|
+
response: undefined, // not available from async API
|
|
138
|
+
scanId: id,
|
|
139
|
+
reportId: '',
|
|
140
|
+
action: 'allow', // safe default for failed scans
|
|
141
|
+
category: 'error',
|
|
142
|
+
triggered: false, // not available from async API — always false
|
|
143
|
+
detections: {}, // not available from async API
|
|
144
|
+
});
|
|
145
|
+
pending.delete(id);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
static formatResultsCsv(results) {
|
|
150
|
+
const header = 'prompt,action,category,triggered,scan_id,report_id';
|
|
151
|
+
const rows = results.map((r) => {
|
|
152
|
+
const escaped = r.prompt.replace(/"/g, '""');
|
|
153
|
+
return `"${escaped}","${r.action}","${r.category}","${r.triggered}","${r.scanId}","${r.reportId}"`;
|
|
154
|
+
});
|
|
155
|
+
return [header, ...rows].join('\n');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/airs/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ScanResult, ScanService } from './types.js';
|
|
2
|
+
/** Scans prompts against AIRS security profiles via the Prisma AIRS SDK. */
|
|
3
|
+
export declare class AirsScanService implements ScanService {
|
|
4
|
+
private scanner;
|
|
5
|
+
constructor(apiKey: string);
|
|
6
|
+
/** Scan a single prompt synchronously and return the normalized result. */
|
|
7
|
+
scan(profileName: string, prompt: string, sessionId?: string): Promise<ScanResult>;
|
|
8
|
+
/** Scan multiple prompts concurrently (default 5) and return results in order. */
|
|
9
|
+
scanBatch(profileName: string, prompts: string[], concurrency?: number, sessionId?: string): Promise<ScanResult[]>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Debug wrapper that delegates to an inner ScanService and appends
|
|
13
|
+
* each raw response + prompt to a JSONL file for offline inspection.
|
|
14
|
+
*/
|
|
15
|
+
export declare class DebugScanService implements ScanService {
|
|
16
|
+
private inner;
|
|
17
|
+
private filePath;
|
|
18
|
+
constructor(inner: ScanService, filePath: string);
|
|
19
|
+
scan(profileName: string, prompt: string, sessionId?: string): Promise<ScanResult>;
|
|
20
|
+
scanBatch(profileName: string, prompts: string[], concurrency?: number, sessionId?: string): Promise<ScanResult[]>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/airs/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D,4EAA4E;AAC5E,qBAAa,eAAgB,YAAW,WAAW;IACjD,OAAO,CAAC,OAAO,CAA+B;gBAElC,MAAM,EAAE,MAAM;IAK1B,2EAA2E;IACrE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAuBxF,kFAAkF;IAC5E,SAAS,CACb,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,WAAW,SAAI,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC;CAMzB;AAED;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAEhD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ;gBADR,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM;IAGpB,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAalF,SAAS,CACb,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,EACjB,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC;CAMzB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import { Content, init, Scanner } from '@cdot65/prisma-airs-sdk';
|
|
3
|
+
import pLimit from 'p-limit';
|
|
4
|
+
/** Scans prompts against AIRS security profiles via the Prisma AIRS SDK. */
|
|
5
|
+
export class AirsScanService {
|
|
6
|
+
scanner;
|
|
7
|
+
constructor(apiKey) {
|
|
8
|
+
init({ apiKey });
|
|
9
|
+
this.scanner = new Scanner();
|
|
10
|
+
}
|
|
11
|
+
/** Scan a single prompt synchronously and return the normalized result. */
|
|
12
|
+
async scan(profileName, prompt, sessionId) {
|
|
13
|
+
const content = new Content({ prompt });
|
|
14
|
+
const response = await this.scanner.syncScan({ profile_name: profileName }, content, sessionId ? { sessionId } : undefined);
|
|
15
|
+
const action = response.action === 'block' ? 'block' : 'allow';
|
|
16
|
+
const detected = response.prompt_detected;
|
|
17
|
+
const triggered = detected?.topic_violation === true;
|
|
18
|
+
const category = response.category ?? undefined;
|
|
19
|
+
return {
|
|
20
|
+
scanId: response.scan_id ?? '',
|
|
21
|
+
reportId: response.report_id ?? '',
|
|
22
|
+
action: action,
|
|
23
|
+
triggered,
|
|
24
|
+
category,
|
|
25
|
+
raw: response,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Scan multiple prompts concurrently (default 5) and return results in order. */
|
|
29
|
+
async scanBatch(profileName, prompts, concurrency = 5, sessionId) {
|
|
30
|
+
const limit = pLimit(concurrency);
|
|
31
|
+
return Promise.all(prompts.map((prompt) => limit(() => this.scan(profileName, prompt, sessionId))));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Debug wrapper that delegates to an inner ScanService and appends
|
|
36
|
+
* each raw response + prompt to a JSONL file for offline inspection.
|
|
37
|
+
*/
|
|
38
|
+
export class DebugScanService {
|
|
39
|
+
inner;
|
|
40
|
+
filePath;
|
|
41
|
+
constructor(inner, filePath) {
|
|
42
|
+
this.inner = inner;
|
|
43
|
+
this.filePath = filePath;
|
|
44
|
+
}
|
|
45
|
+
async scan(profileName, prompt, sessionId) {
|
|
46
|
+
const result = await this.inner.scan(profileName, prompt, sessionId);
|
|
47
|
+
const entry = JSON.stringify({
|
|
48
|
+
prompt,
|
|
49
|
+
profileName,
|
|
50
|
+
result,
|
|
51
|
+
raw: result.raw,
|
|
52
|
+
timestamp: Date.now(),
|
|
53
|
+
});
|
|
54
|
+
await fs.appendFile(this.filePath, `${entry}\n`);
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
async scanBatch(profileName, prompts, concurrency, sessionId) {
|
|
58
|
+
const limit = pLimit(concurrency ?? 5);
|
|
59
|
+
return Promise.all(prompts.map((prompt) => limit(() => this.scan(profileName, prompt, sessionId))));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/airs/scanner.ts"],"names":[],"mappings":"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"}
|