@cdot65/prisma-airs-cli 3.0.1 → 3.1.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/dist/{chunk-JXHYQFEK.js → chunk-DSNQSBLE.js} +200 -0
- package/dist/cli/index.js +499 -2
- package/dist/index.d.ts +200 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
|
@@ -456,6 +456,51 @@ function normalizeFile(raw) {
|
|
|
456
456
|
result: raw.result
|
|
457
457
|
};
|
|
458
458
|
}
|
|
459
|
+
function normalizeModel(raw) {
|
|
460
|
+
return {
|
|
461
|
+
uuid: raw.uuid,
|
|
462
|
+
tsgId: raw.tsg_id,
|
|
463
|
+
name: raw.name,
|
|
464
|
+
createdAt: raw.created_at,
|
|
465
|
+
updatedAt: raw.updated_at,
|
|
466
|
+
latestVersionUuid: raw.latest_version_uuid,
|
|
467
|
+
latestVersionFingerprint: raw.latest_version_fingerprint,
|
|
468
|
+
latestVersionRevision: raw.latest_version_revision,
|
|
469
|
+
latestVersionHfCommitSha: raw.latest_version_hf_commit_sha,
|
|
470
|
+
latestVersionOutcome: raw.latest_version_outcome,
|
|
471
|
+
latestVersionFormats: raw.latest_version_formats,
|
|
472
|
+
latestVersionSourceTypes: raw.latest_version_source_types,
|
|
473
|
+
latestVersionScanTime: raw.latest_version_scan_time
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
function normalizeModelVersion(raw) {
|
|
477
|
+
const summary = raw.last_eval_summary;
|
|
478
|
+
return {
|
|
479
|
+
uuid: raw.uuid,
|
|
480
|
+
tsgId: raw.tsg_id,
|
|
481
|
+
modelUuid: raw.model_uuid,
|
|
482
|
+
revision: raw.revision,
|
|
483
|
+
createdAt: raw.created_at,
|
|
484
|
+
updatedAt: raw.updated_at,
|
|
485
|
+
fingerprint: raw.fingerprint,
|
|
486
|
+
fileCount: raw.file_count,
|
|
487
|
+
license: raw.license,
|
|
488
|
+
latestScanTime: raw.latest_scan_time,
|
|
489
|
+
hfCommitSha: raw.hf_commit_sha,
|
|
490
|
+
hfCommitTitle: raw.hf_commit_title,
|
|
491
|
+
hfCommitAuthors: raw.hf_commit_authors,
|
|
492
|
+
hfModelName: raw.hf_model_name,
|
|
493
|
+
hfOrganization: raw.hf_organization,
|
|
494
|
+
modelFormats: raw.model_formats,
|
|
495
|
+
sourceTypes: raw.source_types,
|
|
496
|
+
lastEvalOutcome: raw.last_eval_outcome,
|
|
497
|
+
lastEvalSummary: summary ? {
|
|
498
|
+
rulesFailed: summary.rules_failed ?? 0,
|
|
499
|
+
rulesPassed: summary.rules_passed ?? 0,
|
|
500
|
+
totalRules: summary.total_rules ?? 0
|
|
501
|
+
} : summary
|
|
502
|
+
};
|
|
503
|
+
}
|
|
459
504
|
var SdkModelSecurityService = class {
|
|
460
505
|
client;
|
|
461
506
|
constructor(opts) {
|
|
@@ -680,6 +725,58 @@ var SdkModelSecurityService = class {
|
|
|
680
725
|
expiresAt: raw.expires_at
|
|
681
726
|
};
|
|
682
727
|
}
|
|
728
|
+
// -----------------------------------------------------------------------
|
|
729
|
+
// Models (read-only catalog)
|
|
730
|
+
// -----------------------------------------------------------------------
|
|
731
|
+
async listModels(opts) {
|
|
732
|
+
const sdkOpts = {};
|
|
733
|
+
if (opts?.search) sdkOpts.search = opts.search;
|
|
734
|
+
if (opts?.searchQuery) sdkOpts.search_query = opts.searchQuery;
|
|
735
|
+
if (opts?.sortField) sdkOpts.sort_field = opts.sortField;
|
|
736
|
+
if (opts?.sortOrder) sdkOpts.sort_order = opts.sortOrder;
|
|
737
|
+
if (opts?.skip !== void 0) sdkOpts.skip = opts.skip;
|
|
738
|
+
if (opts?.limit !== void 0) sdkOpts.limit = opts.limit;
|
|
739
|
+
const response = await this.client.models.listModels(sdkOpts);
|
|
740
|
+
const raw = response;
|
|
741
|
+
return {
|
|
742
|
+
totalItems: raw.pagination.total_items ?? 0,
|
|
743
|
+
models: raw.models.map(normalizeModel)
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
async getModel(uuid) {
|
|
747
|
+
const response = await this.client.models.getModel(uuid);
|
|
748
|
+
return normalizeModel(response);
|
|
749
|
+
}
|
|
750
|
+
async listModelVersions(modelUuid, opts) {
|
|
751
|
+
const sdkOpts = {};
|
|
752
|
+
if (opts?.sortOrder) sdkOpts.sort_order = opts.sortOrder;
|
|
753
|
+
if (opts?.skip !== void 0) sdkOpts.skip = opts.skip;
|
|
754
|
+
if (opts?.limit !== void 0) sdkOpts.limit = opts.limit;
|
|
755
|
+
const response = await this.client.models.listModelVersions(modelUuid, sdkOpts);
|
|
756
|
+
const raw = response;
|
|
757
|
+
return {
|
|
758
|
+
totalItems: raw.pagination.total_items ?? 0,
|
|
759
|
+
versions: raw.model_versions.map(normalizeModelVersion)
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
async getModelVersion(uuid) {
|
|
763
|
+
const response = await this.client.models.getModelVersion(uuid);
|
|
764
|
+
return normalizeModelVersion(response);
|
|
765
|
+
}
|
|
766
|
+
async listModelVersionFiles(modelVersionUuid, opts) {
|
|
767
|
+
const sdkOpts = {};
|
|
768
|
+
if (opts?.skip !== void 0) sdkOpts.skip = opts.skip;
|
|
769
|
+
if (opts?.limit !== void 0) sdkOpts.limit = opts.limit;
|
|
770
|
+
const response = await this.client.models.listModelVersionFiles(
|
|
771
|
+
modelVersionUuid,
|
|
772
|
+
sdkOpts
|
|
773
|
+
);
|
|
774
|
+
const raw = response;
|
|
775
|
+
return {
|
|
776
|
+
totalItems: raw.pagination.total_items ?? 0,
|
|
777
|
+
files: raw.files.map(normalizeFile)
|
|
778
|
+
};
|
|
779
|
+
}
|
|
683
780
|
};
|
|
684
781
|
|
|
685
782
|
// src/airs/promptsets.ts
|
|
@@ -862,6 +959,37 @@ function sanitizeTargetMetadata(metadata) {
|
|
|
862
959
|
}
|
|
863
960
|
return metadata;
|
|
864
961
|
}
|
|
962
|
+
function normalizeChannel(raw) {
|
|
963
|
+
return {
|
|
964
|
+
uuid: raw.uuid,
|
|
965
|
+
name: raw.name,
|
|
966
|
+
description: raw.description,
|
|
967
|
+
status: raw.status,
|
|
968
|
+
addedBy: raw.added_by,
|
|
969
|
+
createdAt: raw.created_at,
|
|
970
|
+
updatedAt: raw.updated_at,
|
|
971
|
+
lastOnlineAt: raw.last_online_at,
|
|
972
|
+
connectedClientsCount: raw.connected_clients_count,
|
|
973
|
+
outdatedClientsCount: raw.outdated_clients_count,
|
|
974
|
+
features: raw.features
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
function normalizeErrorLog(raw) {
|
|
978
|
+
return {
|
|
979
|
+
createdAt: raw.created_at,
|
|
980
|
+
updatedAt: raw.updated_at,
|
|
981
|
+
jobId: raw.job_id,
|
|
982
|
+
targetId: raw.target_id,
|
|
983
|
+
targetVersion: raw.target_version,
|
|
984
|
+
attackId: raw.attack_id,
|
|
985
|
+
errorType: raw.error_type,
|
|
986
|
+
errorSource: raw.error_source,
|
|
987
|
+
errorMessage: raw.error_message,
|
|
988
|
+
targetObject: raw.target_object,
|
|
989
|
+
extraInfo: raw.extra_info,
|
|
990
|
+
version: raw.version
|
|
991
|
+
};
|
|
992
|
+
}
|
|
865
993
|
function normalizeTargetDetail(raw) {
|
|
866
994
|
return {
|
|
867
995
|
uuid: raw.uuid,
|
|
@@ -1210,6 +1338,76 @@ var SdkRedTeamService = class {
|
|
|
1210
1338
|
await delay(intervalMs);
|
|
1211
1339
|
}
|
|
1212
1340
|
}
|
|
1341
|
+
async listChannels(opts) {
|
|
1342
|
+
const sdkOpts = {};
|
|
1343
|
+
if (opts?.limit != null) sdkOpts.limit = opts.limit;
|
|
1344
|
+
if (opts?.offset != null) sdkOpts.skip = opts.offset;
|
|
1345
|
+
if (opts?.search) sdkOpts.search = opts.search;
|
|
1346
|
+
if (opts?.status) sdkOpts.status = opts.status;
|
|
1347
|
+
const raw = await this.client.networkBroker.listChannels(sdkOpts);
|
|
1348
|
+
const pagination = raw.pagination;
|
|
1349
|
+
return {
|
|
1350
|
+
channels: (raw.data ?? []).map(normalizeChannel),
|
|
1351
|
+
totalItems: pagination?.total_items
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
async getChannel(channelId) {
|
|
1355
|
+
const raw = await this.client.networkBroker.getChannel(channelId);
|
|
1356
|
+
return normalizeChannel(raw);
|
|
1357
|
+
}
|
|
1358
|
+
async createChannel(request) {
|
|
1359
|
+
const body = { name: request.name };
|
|
1360
|
+
if (request.description !== void 0) body.description = request.description;
|
|
1361
|
+
const raw = await this.client.networkBroker.createChannel(
|
|
1362
|
+
body
|
|
1363
|
+
);
|
|
1364
|
+
return normalizeChannel(raw);
|
|
1365
|
+
}
|
|
1366
|
+
async updateChannel(channelId, request) {
|
|
1367
|
+
const body = {};
|
|
1368
|
+
if (request.name !== void 0) body.name = request.name;
|
|
1369
|
+
if (request.description !== void 0) body.description = request.description;
|
|
1370
|
+
const raw = await this.client.networkBroker.updateChannel(
|
|
1371
|
+
channelId,
|
|
1372
|
+
body
|
|
1373
|
+
);
|
|
1374
|
+
return normalizeChannel(raw);
|
|
1375
|
+
}
|
|
1376
|
+
async getChannelStats() {
|
|
1377
|
+
const raw = await this.client.networkBroker.getChannelStats();
|
|
1378
|
+
return {
|
|
1379
|
+
serverDomain: raw.network_channels_server_domain,
|
|
1380
|
+
dockerRegistry: raw.docker_registry,
|
|
1381
|
+
helmChart: raw.helm_chart,
|
|
1382
|
+
dockerImage: raw.docker_image,
|
|
1383
|
+
onlineChannels: raw.online_channels,
|
|
1384
|
+
totalChannels: raw.total_channels,
|
|
1385
|
+
clientVersion: raw.client_version
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
async getLanguages(management = false) {
|
|
1389
|
+
const raw = await (management ? this.client.getManagementLanguages() : this.client.getLanguages());
|
|
1390
|
+
return {
|
|
1391
|
+
multilingualEnabled: Boolean(raw.multilingual_enabled),
|
|
1392
|
+
supportedJobTypes: raw.supported_job_types ?? [],
|
|
1393
|
+
languages: (raw.languages ?? []).map((l) => ({
|
|
1394
|
+
code: l.code,
|
|
1395
|
+
name: l.name
|
|
1396
|
+
}))
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
async getTargetProfileErrorLogs(targetId, opts) {
|
|
1400
|
+
const sdkOpts = {};
|
|
1401
|
+
if (opts?.limit != null) sdkOpts.limit = opts.limit;
|
|
1402
|
+
if (opts?.offset != null) sdkOpts.skip = opts.offset;
|
|
1403
|
+
if (opts?.search) sdkOpts.search = opts.search;
|
|
1404
|
+
const raw = await this.client.getTargetProfileErrorLogs(targetId, sdkOpts);
|
|
1405
|
+
const pagination = raw.pagination;
|
|
1406
|
+
return {
|
|
1407
|
+
logs: (raw.data ?? []).map(normalizeErrorLog),
|
|
1408
|
+
totalItems: pagination?.total_items
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1213
1411
|
};
|
|
1214
1412
|
|
|
1215
1413
|
// src/airs/runtime.ts
|
|
@@ -1509,6 +1707,7 @@ var ConfigSchema = z.object({
|
|
|
1509
1707
|
redTeamDataEndpoint: z.string().optional(),
|
|
1510
1708
|
redTeamMgmtEndpoint: z.string().optional(),
|
|
1511
1709
|
redTeamTokenEndpoint: z.string().optional(),
|
|
1710
|
+
redTeamNetworkBrokerEndpoint: z.string().optional(),
|
|
1512
1711
|
// Model Security (endpoints only; creds shared with mgmt*)
|
|
1513
1712
|
modelSecDataEndpoint: z.string().optional(),
|
|
1514
1713
|
modelSecMgmtEndpoint: z.string().optional(),
|
|
@@ -1539,6 +1738,7 @@ function fromEnv() {
|
|
|
1539
1738
|
redTeamDataEndpoint: env.PANW_RED_TEAM_DATA_ENDPOINT,
|
|
1540
1739
|
redTeamMgmtEndpoint: env.PANW_RED_TEAM_MGMT_ENDPOINT,
|
|
1541
1740
|
redTeamTokenEndpoint: env.PANW_RED_TEAM_TOKEN_ENDPOINT,
|
|
1741
|
+
redTeamNetworkBrokerEndpoint: env.PANW_RED_TEAM_NETWORK_BROKER_ENDPOINT,
|
|
1542
1742
|
modelSecDataEndpoint: env.PANW_MODEL_SEC_DATA_ENDPOINT,
|
|
1543
1743
|
modelSecMgmtEndpoint: env.PANW_MODEL_SEC_MGMT_ENDPOINT,
|
|
1544
1744
|
modelSecTokenEndpoint: env.PANW_MODEL_SEC_TOKEN_ENDPOINT,
|
package/dist/cli/index.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
sanitizeFilename,
|
|
20
20
|
validateTopic,
|
|
21
21
|
writeBackupFile
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-DSNQSBLE.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/index.ts
|
|
25
25
|
import "dotenv/config";
|
|
@@ -1032,6 +1032,171 @@ function renderLabelValues(key, values) {
|
|
|
1032
1032
|
}
|
|
1033
1033
|
console.log();
|
|
1034
1034
|
}
|
|
1035
|
+
function renderModelList(models, format = "pretty") {
|
|
1036
|
+
if (models.length === 0) {
|
|
1037
|
+
ui.emptyList("models");
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
if (format !== "pretty") {
|
|
1041
|
+
const rows = models.map((m) => ({
|
|
1042
|
+
id: m.uuid,
|
|
1043
|
+
name: m.name,
|
|
1044
|
+
outcome: m.latestVersionOutcome ?? "",
|
|
1045
|
+
formats: (m.latestVersionFormats ?? []).join(", "),
|
|
1046
|
+
scanned: m.latestVersionScanTime ?? ""
|
|
1047
|
+
}));
|
|
1048
|
+
console.log(
|
|
1049
|
+
formatOutput(
|
|
1050
|
+
rows,
|
|
1051
|
+
[
|
|
1052
|
+
{ key: "id", label: "ID" },
|
|
1053
|
+
{ key: "name", label: "Name" },
|
|
1054
|
+
{ key: "outcome", label: "Outcome" },
|
|
1055
|
+
{ key: "formats", label: "Formats" },
|
|
1056
|
+
{ key: "scanned", label: "Last Scan" }
|
|
1057
|
+
],
|
|
1058
|
+
format
|
|
1059
|
+
)
|
|
1060
|
+
);
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
ui.section("Models:");
|
|
1064
|
+
for (const m of models) {
|
|
1065
|
+
ui.dim(m.uuid);
|
|
1066
|
+
const outcome = m.latestVersionOutcome ? stateColor(m.latestVersionOutcome)(m.latestVersionOutcome) : chalk6.dim("unscanned");
|
|
1067
|
+
const formats = m.latestVersionFormats && m.latestVersionFormats.length > 0 ? chalk6.dim(` [${m.latestVersionFormats.join(", ")}]`) : "";
|
|
1068
|
+
console.log(` ${m.name} ${outcome}${formats}`);
|
|
1069
|
+
console.log();
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
function renderModelDetail(model, format = "pretty") {
|
|
1073
|
+
if (format !== "pretty") {
|
|
1074
|
+
console.log(format === "json" ? JSON.stringify(model, null, 2) : yamlDump2(model));
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
ui.section("Model Detail:");
|
|
1078
|
+
const pairs = [
|
|
1079
|
+
["UUID", model.uuid],
|
|
1080
|
+
["Name", model.name],
|
|
1081
|
+
["Created", model.createdAt],
|
|
1082
|
+
["Updated", model.updatedAt]
|
|
1083
|
+
];
|
|
1084
|
+
if (model.latestVersionUuid != null) pairs.push(["Latest Version", model.latestVersionUuid]);
|
|
1085
|
+
if (model.latestVersionRevision != null)
|
|
1086
|
+
pairs.push(["Latest Revision", model.latestVersionRevision]);
|
|
1087
|
+
if (model.latestVersionOutcome != null)
|
|
1088
|
+
pairs.push([
|
|
1089
|
+
"Latest Outcome",
|
|
1090
|
+
stateColor(model.latestVersionOutcome)(model.latestVersionOutcome)
|
|
1091
|
+
]);
|
|
1092
|
+
if (model.latestVersionFormats?.length)
|
|
1093
|
+
pairs.push(["Formats", model.latestVersionFormats.join(", ")]);
|
|
1094
|
+
if (model.latestVersionSourceTypes?.length)
|
|
1095
|
+
pairs.push(["Source Types", model.latestVersionSourceTypes.join(", ")]);
|
|
1096
|
+
if (model.latestVersionScanTime != null) pairs.push(["Last Scan", model.latestVersionScanTime]);
|
|
1097
|
+
ui.keyValue(pairs);
|
|
1098
|
+
console.log();
|
|
1099
|
+
}
|
|
1100
|
+
function renderModelVersionList(versions, format = "pretty") {
|
|
1101
|
+
if (versions.length === 0) {
|
|
1102
|
+
ui.emptyList("versions");
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
if (format !== "pretty") {
|
|
1106
|
+
const rows = versions.map((v) => ({
|
|
1107
|
+
id: v.uuid,
|
|
1108
|
+
revision: v.revision,
|
|
1109
|
+
files: v.fileCount ?? "",
|
|
1110
|
+
outcome: v.lastEvalOutcome ?? "",
|
|
1111
|
+
scanned: v.latestScanTime ?? ""
|
|
1112
|
+
}));
|
|
1113
|
+
console.log(
|
|
1114
|
+
formatOutput(
|
|
1115
|
+
rows,
|
|
1116
|
+
[
|
|
1117
|
+
{ key: "id", label: "ID" },
|
|
1118
|
+
{ key: "revision", label: "Revision" },
|
|
1119
|
+
{ key: "files", label: "Files" },
|
|
1120
|
+
{ key: "outcome", label: "Outcome" },
|
|
1121
|
+
{ key: "scanned", label: "Last Scan" }
|
|
1122
|
+
],
|
|
1123
|
+
format
|
|
1124
|
+
)
|
|
1125
|
+
);
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
1128
|
+
ui.section("Model Versions:");
|
|
1129
|
+
for (const v of versions) {
|
|
1130
|
+
ui.dim(v.uuid);
|
|
1131
|
+
const outcome = v.lastEvalOutcome ? stateColor(v.lastEvalOutcome)(v.lastEvalOutcome) : chalk6.dim("unscanned");
|
|
1132
|
+
const files = v.fileCount != null ? ` files: ${v.fileCount}` : "";
|
|
1133
|
+
console.log(` ${v.revision} ${outcome}${files}`);
|
|
1134
|
+
console.log();
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function renderModelVersionDetail(version, format = "pretty") {
|
|
1138
|
+
if (format !== "pretty") {
|
|
1139
|
+
console.log(format === "json" ? JSON.stringify(version, null, 2) : yamlDump2(version));
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
ui.section("Model Version Detail:");
|
|
1143
|
+
const pairs = [
|
|
1144
|
+
["UUID", version.uuid],
|
|
1145
|
+
["Model", version.modelUuid],
|
|
1146
|
+
["Revision", version.revision],
|
|
1147
|
+
["Created", version.createdAt],
|
|
1148
|
+
["Updated", version.updatedAt]
|
|
1149
|
+
];
|
|
1150
|
+
if (version.fileCount != null) pairs.push(["File Count", version.fileCount]);
|
|
1151
|
+
if (version.license != null) pairs.push(["License", version.license]);
|
|
1152
|
+
if (version.modelFormats?.length) pairs.push(["Formats", version.modelFormats.join(", ")]);
|
|
1153
|
+
if (version.sourceTypes?.length) pairs.push(["Source Types", version.sourceTypes.join(", ")]);
|
|
1154
|
+
if (version.hfModelName != null) pairs.push(["HF Model", version.hfModelName]);
|
|
1155
|
+
if (version.hfOrganization != null) pairs.push(["HF Organization", version.hfOrganization]);
|
|
1156
|
+
if (version.lastEvalOutcome != null)
|
|
1157
|
+
pairs.push(["Last Outcome", stateColor(version.lastEvalOutcome)(version.lastEvalOutcome)]);
|
|
1158
|
+
if (version.latestScanTime != null) pairs.push(["Last Scan", version.latestScanTime]);
|
|
1159
|
+
ui.keyValue(pairs);
|
|
1160
|
+
if (version.lastEvalSummary) {
|
|
1161
|
+
ui.section("Last Eval Summary:");
|
|
1162
|
+
ui.keyValue([
|
|
1163
|
+
["Passed", version.lastEvalSummary.rulesPassed],
|
|
1164
|
+
["Failed", version.lastEvalSummary.rulesFailed],
|
|
1165
|
+
["Total", version.lastEvalSummary.totalRules]
|
|
1166
|
+
]);
|
|
1167
|
+
}
|
|
1168
|
+
console.log();
|
|
1169
|
+
}
|
|
1170
|
+
function renderModelFileList(files, format = "pretty") {
|
|
1171
|
+
if (files.length === 0) {
|
|
1172
|
+
ui.emptyList("files");
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
if (format !== "pretty") {
|
|
1176
|
+
const rows = files.map((f) => ({
|
|
1177
|
+
id: f.uuid,
|
|
1178
|
+
path: f.path,
|
|
1179
|
+
type: f.type,
|
|
1180
|
+
formats: f.formats.join(", "),
|
|
1181
|
+
result: f.result
|
|
1182
|
+
}));
|
|
1183
|
+
console.log(
|
|
1184
|
+
formatOutput(
|
|
1185
|
+
rows,
|
|
1186
|
+
[
|
|
1187
|
+
{ key: "id", label: "ID" },
|
|
1188
|
+
{ key: "path", label: "Path" },
|
|
1189
|
+
{ key: "type", label: "Type" },
|
|
1190
|
+
{ key: "formats", label: "Formats" },
|
|
1191
|
+
{ key: "result", label: "Result" }
|
|
1192
|
+
],
|
|
1193
|
+
format
|
|
1194
|
+
)
|
|
1195
|
+
);
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
renderFileList(files);
|
|
1199
|
+
}
|
|
1035
1200
|
|
|
1036
1201
|
// src/cli/renderer/redteam.ts
|
|
1037
1202
|
import chalk7 from "chalk";
|
|
@@ -1582,6 +1747,170 @@ function renderRegistryCredentials(creds, format = "pretty") {
|
|
|
1582
1747
|
]);
|
|
1583
1748
|
console.log();
|
|
1584
1749
|
}
|
|
1750
|
+
function channelStatusColor(status) {
|
|
1751
|
+
switch (status.toUpperCase()) {
|
|
1752
|
+
case "ONLINE":
|
|
1753
|
+
return chalk7.green;
|
|
1754
|
+
case "DRAFT":
|
|
1755
|
+
return chalk7.yellow;
|
|
1756
|
+
case "OFFLINE":
|
|
1757
|
+
return chalk7.red;
|
|
1758
|
+
default:
|
|
1759
|
+
return chalk7.white;
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
function renderChannelList(channels, format = "pretty") {
|
|
1763
|
+
if (channels.length === 0) {
|
|
1764
|
+
ui.emptyList("channels");
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
if (format !== "pretty") {
|
|
1768
|
+
const rows = channels.map((c) => ({
|
|
1769
|
+
id: c.uuid ?? "",
|
|
1770
|
+
name: c.name ?? "",
|
|
1771
|
+
status: c.status ?? "",
|
|
1772
|
+
clients: c.connectedClientsCount ?? "",
|
|
1773
|
+
lastOnline: c.lastOnlineAt ?? ""
|
|
1774
|
+
}));
|
|
1775
|
+
console.log(
|
|
1776
|
+
formatOutput(
|
|
1777
|
+
rows,
|
|
1778
|
+
[
|
|
1779
|
+
{ key: "id", label: "ID" },
|
|
1780
|
+
{ key: "name", label: "Name" },
|
|
1781
|
+
{ key: "status", label: "Status" },
|
|
1782
|
+
{ key: "clients", label: "Clients" },
|
|
1783
|
+
{ key: "lastOnline", label: "Last Online" }
|
|
1784
|
+
],
|
|
1785
|
+
format
|
|
1786
|
+
)
|
|
1787
|
+
);
|
|
1788
|
+
return;
|
|
1789
|
+
}
|
|
1790
|
+
ui.section("Network Broker Channels:");
|
|
1791
|
+
for (const c of channels) {
|
|
1792
|
+
if (c.uuid) ui.dim(c.uuid);
|
|
1793
|
+
const status = c.status ? channelStatusColor(c.status)(c.status) : chalk7.dim("unknown");
|
|
1794
|
+
const clients = c.connectedClientsCount != null ? ` clients: ${c.connectedClientsCount}` : "";
|
|
1795
|
+
console.log(` ${c.name ?? "(unnamed)"} ${status}${clients}`);
|
|
1796
|
+
console.log();
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
function renderChannelDetail(channel, format = "pretty") {
|
|
1800
|
+
if (format !== "pretty") {
|
|
1801
|
+
console.log(format === "json" ? JSON.stringify(channel, null, 2) : yamlDump3(channel));
|
|
1802
|
+
return;
|
|
1803
|
+
}
|
|
1804
|
+
ui.section("Channel Detail:");
|
|
1805
|
+
const pairs = [["UUID", channel.uuid]];
|
|
1806
|
+
if (channel.name != null) pairs.push(["Name", channel.name]);
|
|
1807
|
+
if (channel.description != null) pairs.push(["Description", channel.description]);
|
|
1808
|
+
if (channel.status != null)
|
|
1809
|
+
pairs.push(["Status", channelStatusColor(channel.status)(channel.status)]);
|
|
1810
|
+
if (channel.connectedClientsCount != null)
|
|
1811
|
+
pairs.push(["Connected Clients", channel.connectedClientsCount]);
|
|
1812
|
+
if (channel.outdatedClientsCount != null)
|
|
1813
|
+
pairs.push(["Outdated Clients", channel.outdatedClientsCount]);
|
|
1814
|
+
if (channel.lastOnlineAt != null) pairs.push(["Last Online", channel.lastOnlineAt]);
|
|
1815
|
+
if (channel.addedBy != null) pairs.push(["Added By", channel.addedBy]);
|
|
1816
|
+
if (channel.createdAt != null) pairs.push(["Created", channel.createdAt]);
|
|
1817
|
+
if (channel.updatedAt != null) pairs.push(["Updated", channel.updatedAt]);
|
|
1818
|
+
ui.keyValue(pairs);
|
|
1819
|
+
if (channel.features && Object.keys(channel.features).length > 0) {
|
|
1820
|
+
ui.section("Features:");
|
|
1821
|
+
ui.keyValue(Object.entries(channel.features).map(([k, v]) => [k, v]));
|
|
1822
|
+
}
|
|
1823
|
+
console.log();
|
|
1824
|
+
}
|
|
1825
|
+
function renderChannelStats(stats, format = "pretty") {
|
|
1826
|
+
if (format !== "pretty") {
|
|
1827
|
+
console.log(format === "json" ? JSON.stringify(stats, null, 2) : yamlDump3(stats));
|
|
1828
|
+
return;
|
|
1829
|
+
}
|
|
1830
|
+
ui.section("Network Broker Stats:");
|
|
1831
|
+
const pairs = [];
|
|
1832
|
+
if (stats.onlineChannels != null) pairs.push(["Online Channels", stats.onlineChannels]);
|
|
1833
|
+
if (stats.totalChannels != null) pairs.push(["Total Channels", stats.totalChannels]);
|
|
1834
|
+
if (stats.serverDomain != null) pairs.push(["Server Domain", stats.serverDomain]);
|
|
1835
|
+
if (stats.dockerRegistry != null) pairs.push(["Docker Registry", stats.dockerRegistry]);
|
|
1836
|
+
if (stats.dockerImage != null) pairs.push(["Docker Image", stats.dockerImage]);
|
|
1837
|
+
if (stats.helmChart != null) pairs.push(["Helm Chart", stats.helmChart]);
|
|
1838
|
+
if (stats.clientVersion != null) pairs.push(["Client Version", stats.clientVersion]);
|
|
1839
|
+
ui.keyValue(pairs);
|
|
1840
|
+
console.log();
|
|
1841
|
+
}
|
|
1842
|
+
function renderLanguages(data, format = "pretty") {
|
|
1843
|
+
if (format !== "pretty") {
|
|
1844
|
+
if (format === "json" || format === "yaml") {
|
|
1845
|
+
console.log(format === "json" ? JSON.stringify(data, null, 2) : yamlDump3(data));
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1848
|
+
console.log(
|
|
1849
|
+
formatOutput(
|
|
1850
|
+
data.languages.map((l) => ({ code: l.code, name: l.name })),
|
|
1851
|
+
[
|
|
1852
|
+
{ key: "code", label: "Code" },
|
|
1853
|
+
{ key: "name", label: "Name" }
|
|
1854
|
+
],
|
|
1855
|
+
format
|
|
1856
|
+
)
|
|
1857
|
+
);
|
|
1858
|
+
return;
|
|
1859
|
+
}
|
|
1860
|
+
ui.section("Tenant Languages:");
|
|
1861
|
+
ui.keyValue([
|
|
1862
|
+
["Multilingual", data.multilingualEnabled ? activeState(true) : activeState(false)],
|
|
1863
|
+
["Supported Job Types", data.supportedJobTypes.join(", ") || "(none)"]
|
|
1864
|
+
]);
|
|
1865
|
+
if (data.languages.length === 0) {
|
|
1866
|
+
ui.emptyList("languages");
|
|
1867
|
+
return;
|
|
1868
|
+
}
|
|
1869
|
+
ui.section("Languages:");
|
|
1870
|
+
for (const l of data.languages) {
|
|
1871
|
+
console.log(` ${chalk7.dim(l.code)} ${l.name}`);
|
|
1872
|
+
}
|
|
1873
|
+
console.log();
|
|
1874
|
+
}
|
|
1875
|
+
function renderErrorLogs(logs, format = "pretty") {
|
|
1876
|
+
if (logs.length === 0) {
|
|
1877
|
+
ui.emptyList("error logs");
|
|
1878
|
+
return;
|
|
1879
|
+
}
|
|
1880
|
+
if (format !== "pretty") {
|
|
1881
|
+
const rows = logs.map((l) => ({
|
|
1882
|
+
createdAt: l.createdAt,
|
|
1883
|
+
errorType: l.errorType ?? "",
|
|
1884
|
+
errorSource: l.errorSource ?? "",
|
|
1885
|
+
jobId: l.jobId ?? "",
|
|
1886
|
+
message: l.errorMessage ?? ""
|
|
1887
|
+
}));
|
|
1888
|
+
console.log(
|
|
1889
|
+
formatOutput(
|
|
1890
|
+
rows,
|
|
1891
|
+
[
|
|
1892
|
+
{ key: "createdAt", label: "Created" },
|
|
1893
|
+
{ key: "errorType", label: "Type" },
|
|
1894
|
+
{ key: "errorSource", label: "Source" },
|
|
1895
|
+
{ key: "jobId", label: "Job" },
|
|
1896
|
+
{ key: "message", label: "Message" }
|
|
1897
|
+
],
|
|
1898
|
+
format
|
|
1899
|
+
)
|
|
1900
|
+
);
|
|
1901
|
+
return;
|
|
1902
|
+
}
|
|
1903
|
+
ui.section("Target-Profile Error Logs:");
|
|
1904
|
+
for (const l of logs) {
|
|
1905
|
+
const type = l.errorType ? chalk7.red(l.errorType) : chalk7.dim("error");
|
|
1906
|
+
console.log(
|
|
1907
|
+
` ${chalk7.dim(l.createdAt)} ${type}${l.errorSource ? ` (${l.errorSource})` : ""}`
|
|
1908
|
+
);
|
|
1909
|
+
if (l.errorMessage) console.log(` ${l.errorMessage}`);
|
|
1910
|
+
if (l.jobId) console.log(` ${chalk7.dim(`job: ${l.jobId}`)}`);
|
|
1911
|
+
console.log();
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1585
1914
|
|
|
1586
1915
|
// src/cli/renderer/runtime.ts
|
|
1587
1916
|
import chalk8 from "chalk";
|
|
@@ -2340,7 +2669,8 @@ function redTeamClientOptions(config) {
|
|
|
2340
2669
|
tsgId: config.mgmtTsgId,
|
|
2341
2670
|
dataEndpoint: config.redTeamDataEndpoint,
|
|
2342
2671
|
mgmtEndpoint: config.redTeamMgmtEndpoint,
|
|
2343
|
-
tokenEndpoint: config.redTeamTokenEndpoint ?? config.mgmtTokenEndpoint
|
|
2672
|
+
tokenEndpoint: config.redTeamTokenEndpoint ?? config.mgmtTokenEndpoint,
|
|
2673
|
+
networkBrokerEndpoint: config.redTeamNetworkBrokerEndpoint
|
|
2344
2674
|
};
|
|
2345
2675
|
}
|
|
2346
2676
|
function modelSecurityClientOptions(config) {
|
|
@@ -3057,6 +3387,76 @@ function registerModelSecurityCommand(program) {
|
|
|
3057
3387
|
fail(err);
|
|
3058
3388
|
}
|
|
3059
3389
|
});
|
|
3390
|
+
const models = ms.command("models").description("Browse the scanned model catalog (read-only)");
|
|
3391
|
+
models.command("list").description("List models in the catalog").option("--search <text>", "Filter by search text").option("--search-query <text>", "Filter by model UUID or name").option("--sort-field <field>", "Sort field: created_at, updated_at").option("--sort-order <order>", "Sort order: asc, desc").option("--limit <n>", "Max results").option("--offset <n>", "Starting offset").option("--output <format>", "Output format: pretty, table, csv, json, yaml", "pretty").addHelpText("after", examples("airs model-security models list")).action(async (opts) => {
|
|
3392
|
+
try {
|
|
3393
|
+
const fmt = opts.output;
|
|
3394
|
+
if (fmt === "pretty") renderModelSecurityHeader();
|
|
3395
|
+
const service = await createService();
|
|
3396
|
+
const result = await service.listModels({
|
|
3397
|
+
search: opts.search,
|
|
3398
|
+
searchQuery: opts.searchQuery,
|
|
3399
|
+
sortField: opts.sortField,
|
|
3400
|
+
sortOrder: opts.sortOrder,
|
|
3401
|
+
limit: opts.limit ? Number.parseInt(opts.limit, 10) : void 0,
|
|
3402
|
+
skip: opts.offset ? Number.parseInt(opts.offset, 10) : void 0
|
|
3403
|
+
});
|
|
3404
|
+
renderModelList(result.models, fmt);
|
|
3405
|
+
} catch (err) {
|
|
3406
|
+
fail(err);
|
|
3407
|
+
}
|
|
3408
|
+
});
|
|
3409
|
+
models.command("get <uuid>").description("Get a model by UUID").option("--output <format>", "Output format: pretty, json, yaml", "pretty").action(async (uuid, opts) => {
|
|
3410
|
+
try {
|
|
3411
|
+
const fmt = opts.output;
|
|
3412
|
+
if (fmt === "pretty") renderModelSecurityHeader();
|
|
3413
|
+
const service = await createService();
|
|
3414
|
+
const model = await service.getModel(uuid);
|
|
3415
|
+
renderModelDetail(model, fmt);
|
|
3416
|
+
} catch (err) {
|
|
3417
|
+
fail(err);
|
|
3418
|
+
}
|
|
3419
|
+
});
|
|
3420
|
+
models.command("versions <modelUuid>").description("List versions of a model").option("--sort-order <order>", "Sort order: asc, desc").option("--limit <n>", "Max results").option("--offset <n>", "Starting offset").option("--output <format>", "Output format: pretty, table, csv, json, yaml", "pretty").action(async (modelUuid, opts) => {
|
|
3421
|
+
try {
|
|
3422
|
+
const fmt = opts.output;
|
|
3423
|
+
if (fmt === "pretty") renderModelSecurityHeader();
|
|
3424
|
+
const service = await createService();
|
|
3425
|
+
const result = await service.listModelVersions(modelUuid, {
|
|
3426
|
+
sortOrder: opts.sortOrder,
|
|
3427
|
+
limit: opts.limit ? Number.parseInt(opts.limit, 10) : void 0,
|
|
3428
|
+
skip: opts.offset ? Number.parseInt(opts.offset, 10) : void 0
|
|
3429
|
+
});
|
|
3430
|
+
renderModelVersionList(result.versions, fmt);
|
|
3431
|
+
} catch (err) {
|
|
3432
|
+
fail(err);
|
|
3433
|
+
}
|
|
3434
|
+
});
|
|
3435
|
+
models.command("version <uuid>").description("Get a model version by UUID").option("--output <format>", "Output format: pretty, json, yaml", "pretty").action(async (uuid, opts) => {
|
|
3436
|
+
try {
|
|
3437
|
+
const fmt = opts.output;
|
|
3438
|
+
if (fmt === "pretty") renderModelSecurityHeader();
|
|
3439
|
+
const service = await createService();
|
|
3440
|
+
const version = await service.getModelVersion(uuid);
|
|
3441
|
+
renderModelVersionDetail(version, fmt);
|
|
3442
|
+
} catch (err) {
|
|
3443
|
+
fail(err);
|
|
3444
|
+
}
|
|
3445
|
+
});
|
|
3446
|
+
models.command("files <modelVersionUuid>").description("List files in a model version").option("--limit <n>", "Max results").option("--offset <n>", "Starting offset").option("--output <format>", "Output format: pretty, table, csv, json, yaml", "pretty").action(async (modelVersionUuid, opts) => {
|
|
3447
|
+
try {
|
|
3448
|
+
const fmt = opts.output;
|
|
3449
|
+
if (fmt === "pretty") renderModelSecurityHeader();
|
|
3450
|
+
const service = await createService();
|
|
3451
|
+
const result = await service.listModelVersionFiles(modelVersionUuid, {
|
|
3452
|
+
limit: opts.limit ? Number.parseInt(opts.limit, 10) : void 0,
|
|
3453
|
+
skip: opts.offset ? Number.parseInt(opts.offset, 10) : void 0
|
|
3454
|
+
});
|
|
3455
|
+
renderModelFileList(result.files, fmt);
|
|
3456
|
+
} catch (err) {
|
|
3457
|
+
fail(err);
|
|
3458
|
+
}
|
|
3459
|
+
});
|
|
3060
3460
|
}
|
|
3061
3461
|
|
|
3062
3462
|
// src/cli/commands/redteam.ts
|
|
@@ -4051,6 +4451,103 @@ function registerRedteamCommand(program) {
|
|
|
4051
4451
|
fail(err);
|
|
4052
4452
|
}
|
|
4053
4453
|
});
|
|
4454
|
+
targets.command("error-logs <targetId>").description("List target-profile error logs").option("--limit <n>", "Max results").option("--offset <n>", "Starting offset").option("--search <text>", "Filter by search text").option("--output <format>", "Output format: pretty, table, csv, json, yaml", "pretty").addHelpText("after", examples("airs redteam targets error-logs <targetId>")).action(async (targetId, opts) => {
|
|
4455
|
+
try {
|
|
4456
|
+
const fmt = opts.output;
|
|
4457
|
+
if (fmt === "pretty") renderRedteamHeader();
|
|
4458
|
+
const service = await createService2();
|
|
4459
|
+
const { logs } = await service.getTargetProfileErrorLogs(targetId, {
|
|
4460
|
+
limit: opts.limit ? parsePositiveInt(opts.limit, "--limit") : void 0,
|
|
4461
|
+
offset: opts.offset ? Number.parseInt(opts.offset, 10) : void 0,
|
|
4462
|
+
search: opts.search
|
|
4463
|
+
});
|
|
4464
|
+
renderErrorLogs(logs, fmt);
|
|
4465
|
+
} catch (err) {
|
|
4466
|
+
fail(err);
|
|
4467
|
+
}
|
|
4468
|
+
});
|
|
4469
|
+
const networkBroker = redteam.command("network-broker").description("Manage red team network broker channels");
|
|
4470
|
+
const channels = networkBroker.command("channels").description("Manage network broker channels");
|
|
4471
|
+
channels.command("list").description("List network broker channels").option("--limit <n>", "Max results").option("--offset <n>", "Starting offset").option("--search <text>", "Filter by search text").option("--status <status...>", "Filter by status (ONLINE, OFFLINE, DRAFT)").option("--output <format>", "Output format: pretty, table, csv, json, yaml", "pretty").action(async (opts) => {
|
|
4472
|
+
try {
|
|
4473
|
+
const fmt = opts.output;
|
|
4474
|
+
if (fmt === "pretty") renderRedteamHeader();
|
|
4475
|
+
const service = await createService2();
|
|
4476
|
+
const { channels: list } = await service.listChannels({
|
|
4477
|
+
limit: opts.limit ? parsePositiveInt(opts.limit, "--limit") : void 0,
|
|
4478
|
+
offset: opts.offset ? Number.parseInt(opts.offset, 10) : void 0,
|
|
4479
|
+
search: opts.search,
|
|
4480
|
+
status: opts.status
|
|
4481
|
+
});
|
|
4482
|
+
renderChannelList(list, fmt);
|
|
4483
|
+
} catch (err) {
|
|
4484
|
+
fail(err);
|
|
4485
|
+
}
|
|
4486
|
+
});
|
|
4487
|
+
channels.command("get <channelId>").description("Get a network broker channel").option("--output <format>", "Output format: pretty, json, yaml", "pretty").action(async (channelId, opts) => {
|
|
4488
|
+
try {
|
|
4489
|
+
const fmt = opts.output;
|
|
4490
|
+
if (fmt === "pretty") renderRedteamHeader();
|
|
4491
|
+
const service = await createService2();
|
|
4492
|
+
const channel = await service.getChannel(channelId);
|
|
4493
|
+
renderChannelDetail(channel, fmt);
|
|
4494
|
+
} catch (err) {
|
|
4495
|
+
fail(err);
|
|
4496
|
+
}
|
|
4497
|
+
});
|
|
4498
|
+
channels.command("create").description("Create a network broker channel").requiredOption("--name <name>", "Channel name").option("--description <text>", "Channel description").action(async (opts) => {
|
|
4499
|
+
try {
|
|
4500
|
+
renderRedteamHeader();
|
|
4501
|
+
const service = await createService2();
|
|
4502
|
+
const channel = await service.createChannel({
|
|
4503
|
+
name: opts.name,
|
|
4504
|
+
description: opts.description
|
|
4505
|
+
});
|
|
4506
|
+
ui.success(`Channel created: ${channel.uuid}`);
|
|
4507
|
+
renderChannelDetail(channel);
|
|
4508
|
+
} catch (err) {
|
|
4509
|
+
fail(err);
|
|
4510
|
+
}
|
|
4511
|
+
});
|
|
4512
|
+
channels.command("update <channelId>").description("Update a network broker channel").option("--name <name>", "New channel name").option("--description <text>", "New channel description").action(async (channelId, opts) => {
|
|
4513
|
+
try {
|
|
4514
|
+
if (opts.name === void 0 && opts.description === void 0) {
|
|
4515
|
+
usageError("Specify --name and/or --description to update");
|
|
4516
|
+
}
|
|
4517
|
+
renderRedteamHeader();
|
|
4518
|
+
const service = await createService2();
|
|
4519
|
+
const channel = await service.updateChannel(channelId, {
|
|
4520
|
+
name: opts.name,
|
|
4521
|
+
description: opts.description
|
|
4522
|
+
});
|
|
4523
|
+
ui.success(`Channel updated: ${channel.uuid}`);
|
|
4524
|
+
renderChannelDetail(channel);
|
|
4525
|
+
} catch (err) {
|
|
4526
|
+
fail(err);
|
|
4527
|
+
}
|
|
4528
|
+
});
|
|
4529
|
+
networkBroker.command("stats").description("Show network broker channel statistics").option("--output <format>", "Output format: pretty, json, yaml", "pretty").action(async (opts) => {
|
|
4530
|
+
try {
|
|
4531
|
+
const fmt = opts.output;
|
|
4532
|
+
if (fmt === "pretty") renderRedteamHeader();
|
|
4533
|
+
const service = await createService2();
|
|
4534
|
+
const stats = await service.getChannelStats();
|
|
4535
|
+
renderChannelStats(stats, fmt);
|
|
4536
|
+
} catch (err) {
|
|
4537
|
+
fail(err);
|
|
4538
|
+
}
|
|
4539
|
+
});
|
|
4540
|
+
redteam.command("languages").description("List tenant languages and supported job types").option("--management", "Query the management-plane endpoint instead of the data plane").option("--output <format>", "Output format: pretty, table, csv, json, yaml", "pretty").action(async (opts) => {
|
|
4541
|
+
try {
|
|
4542
|
+
const fmt = opts.output;
|
|
4543
|
+
if (fmt === "pretty") renderRedteamHeader();
|
|
4544
|
+
const service = await createService2();
|
|
4545
|
+
const data = await service.getLanguages(Boolean(opts.management));
|
|
4546
|
+
renderLanguages(data, fmt);
|
|
4547
|
+
} catch (err) {
|
|
4548
|
+
fail(err);
|
|
4549
|
+
}
|
|
4550
|
+
});
|
|
4054
4551
|
}
|
|
4055
4552
|
|
|
4056
4553
|
// src/cli/commands/runtime.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -349,6 +349,71 @@ interface RegistryCredentials {
|
|
|
349
349
|
token: string;
|
|
350
350
|
expiry: string;
|
|
351
351
|
}
|
|
352
|
+
/** Normalized network broker channel. */
|
|
353
|
+
interface RedTeamChannel {
|
|
354
|
+
uuid?: string;
|
|
355
|
+
name?: string | null;
|
|
356
|
+
description?: string | null;
|
|
357
|
+
status?: string | null;
|
|
358
|
+
addedBy?: string | null;
|
|
359
|
+
createdAt?: string | null;
|
|
360
|
+
updatedAt?: string | null;
|
|
361
|
+
lastOnlineAt?: string | null;
|
|
362
|
+
connectedClientsCount?: number | null;
|
|
363
|
+
outdatedClientsCount?: number | null;
|
|
364
|
+
features?: Record<string, boolean> | null;
|
|
365
|
+
}
|
|
366
|
+
/** Filters for listing network broker channels. */
|
|
367
|
+
interface RedTeamChannelListOptions {
|
|
368
|
+
limit?: number;
|
|
369
|
+
offset?: number;
|
|
370
|
+
search?: string;
|
|
371
|
+
status?: string | string[];
|
|
372
|
+
}
|
|
373
|
+
/** Request to create a network broker channel. */
|
|
374
|
+
interface RedTeamChannelCreateRequest {
|
|
375
|
+
name: string;
|
|
376
|
+
description?: string;
|
|
377
|
+
}
|
|
378
|
+
/** Request to update a network broker channel. */
|
|
379
|
+
interface RedTeamChannelUpdateRequest {
|
|
380
|
+
name?: string;
|
|
381
|
+
description?: string;
|
|
382
|
+
}
|
|
383
|
+
/** Normalized network broker channel statistics. */
|
|
384
|
+
interface RedTeamChannelStats {
|
|
385
|
+
serverDomain?: string | null;
|
|
386
|
+
dockerRegistry?: string | null;
|
|
387
|
+
helmChart?: string | null;
|
|
388
|
+
dockerImage?: string | null;
|
|
389
|
+
onlineChannels?: number | null;
|
|
390
|
+
totalChannels?: number | null;
|
|
391
|
+
clientVersion?: string | null;
|
|
392
|
+
}
|
|
393
|
+
/** Normalized tenant language configuration. */
|
|
394
|
+
interface RedTeamLanguages {
|
|
395
|
+
multilingualEnabled: boolean;
|
|
396
|
+
supportedJobTypes: string[];
|
|
397
|
+
languages: Array<{
|
|
398
|
+
code: string;
|
|
399
|
+
name: string;
|
|
400
|
+
}>;
|
|
401
|
+
}
|
|
402
|
+
/** Normalized target-profile error log entry. */
|
|
403
|
+
interface RedTeamErrorLog {
|
|
404
|
+
createdAt: string;
|
|
405
|
+
updatedAt: string;
|
|
406
|
+
jobId?: string | null;
|
|
407
|
+
targetId?: string | null;
|
|
408
|
+
targetVersion?: number | null;
|
|
409
|
+
attackId?: string | null;
|
|
410
|
+
errorType?: string | null;
|
|
411
|
+
errorSource?: string | null;
|
|
412
|
+
errorMessage?: string | null;
|
|
413
|
+
targetObject?: Record<string, unknown> | null;
|
|
414
|
+
extraInfo?: Record<string, unknown> | null;
|
|
415
|
+
version?: number;
|
|
416
|
+
}
|
|
352
417
|
/** Contract for AI Red Team scan operations. */
|
|
353
418
|
interface RedTeamService {
|
|
354
419
|
/** Get EULA content. */
|
|
@@ -439,6 +504,30 @@ interface RedTeamService {
|
|
|
439
504
|
getCategories(): Promise<RedTeamCategory[]>;
|
|
440
505
|
/** Poll until scan completes. Calls onProgress for status updates. */
|
|
441
506
|
waitForCompletion(jobId: string, onProgress?: (job: RedTeamJob) => void, intervalMs?: number): Promise<RedTeamJob>;
|
|
507
|
+
/** List network broker channels. */
|
|
508
|
+
listChannels(opts?: RedTeamChannelListOptions): Promise<{
|
|
509
|
+
channels: RedTeamChannel[];
|
|
510
|
+
totalItems?: number;
|
|
511
|
+
}>;
|
|
512
|
+
/** Get a network broker channel by ID. */
|
|
513
|
+
getChannel(channelId: string): Promise<RedTeamChannel>;
|
|
514
|
+
/** Create a network broker channel. */
|
|
515
|
+
createChannel(request: RedTeamChannelCreateRequest): Promise<RedTeamChannel>;
|
|
516
|
+
/** Update a network broker channel. */
|
|
517
|
+
updateChannel(channelId: string, request: RedTeamChannelUpdateRequest): Promise<RedTeamChannel>;
|
|
518
|
+
/** Get network broker channel statistics. */
|
|
519
|
+
getChannelStats(): Promise<RedTeamChannelStats>;
|
|
520
|
+
/** List tenant languages (data plane, or management plane when `management`). */
|
|
521
|
+
getLanguages(management?: boolean): Promise<RedTeamLanguages>;
|
|
522
|
+
/** List target-profile error logs. */
|
|
523
|
+
getTargetProfileErrorLogs(targetId: string, opts?: {
|
|
524
|
+
limit?: number;
|
|
525
|
+
offset?: number;
|
|
526
|
+
search?: string;
|
|
527
|
+
}): Promise<{
|
|
528
|
+
logs: RedTeamErrorLog[];
|
|
529
|
+
totalItems?: number;
|
|
530
|
+
}>;
|
|
442
531
|
}
|
|
443
532
|
/** Normalized security group. */
|
|
444
533
|
interface ModelSecurityGroup {
|
|
@@ -606,6 +695,63 @@ interface ModelSecurityPyPIAuth {
|
|
|
606
695
|
url: string;
|
|
607
696
|
expiresAt: string;
|
|
608
697
|
}
|
|
698
|
+
/** Normalized model catalog entry. */
|
|
699
|
+
interface ModelSecurityModel {
|
|
700
|
+
uuid: string;
|
|
701
|
+
tsgId: string;
|
|
702
|
+
name: string;
|
|
703
|
+
createdAt: string;
|
|
704
|
+
updatedAt: string;
|
|
705
|
+
latestVersionUuid?: string | null;
|
|
706
|
+
latestVersionFingerprint?: string | null;
|
|
707
|
+
latestVersionRevision?: string | null;
|
|
708
|
+
latestVersionHfCommitSha?: string | null;
|
|
709
|
+
latestVersionOutcome?: string | null;
|
|
710
|
+
latestVersionFormats?: string[] | null;
|
|
711
|
+
latestVersionSourceTypes?: string[] | null;
|
|
712
|
+
latestVersionScanTime?: string | null;
|
|
713
|
+
}
|
|
714
|
+
/** Filter options for listing models. */
|
|
715
|
+
interface ModelSecurityModelListOptions {
|
|
716
|
+
search?: string;
|
|
717
|
+
searchQuery?: string;
|
|
718
|
+
sortField?: string;
|
|
719
|
+
sortOrder?: string;
|
|
720
|
+
skip?: number;
|
|
721
|
+
limit?: number;
|
|
722
|
+
}
|
|
723
|
+
/** Normalized model version. */
|
|
724
|
+
interface ModelSecurityModelVersion {
|
|
725
|
+
uuid: string;
|
|
726
|
+
tsgId: string;
|
|
727
|
+
modelUuid: string;
|
|
728
|
+
revision: string;
|
|
729
|
+
createdAt: string;
|
|
730
|
+
updatedAt: string;
|
|
731
|
+
fingerprint?: string | null;
|
|
732
|
+
fileCount?: number | null;
|
|
733
|
+
license?: string | null;
|
|
734
|
+
latestScanTime?: string | null;
|
|
735
|
+
hfCommitSha?: string | null;
|
|
736
|
+
hfCommitTitle?: string | null;
|
|
737
|
+
hfCommitAuthors?: string[] | null;
|
|
738
|
+
hfModelName?: string | null;
|
|
739
|
+
hfOrganization?: string | null;
|
|
740
|
+
modelFormats?: string[] | null;
|
|
741
|
+
sourceTypes?: string[] | null;
|
|
742
|
+
lastEvalOutcome?: string | null;
|
|
743
|
+
lastEvalSummary?: {
|
|
744
|
+
rulesFailed: number;
|
|
745
|
+
rulesPassed: number;
|
|
746
|
+
totalRules: number;
|
|
747
|
+
} | null;
|
|
748
|
+
}
|
|
749
|
+
/** Filter options for listing model versions. */
|
|
750
|
+
interface ModelSecurityModelVersionListOptions {
|
|
751
|
+
sortOrder?: string;
|
|
752
|
+
skip?: number;
|
|
753
|
+
limit?: number;
|
|
754
|
+
}
|
|
609
755
|
/** Contract for Model Security operations. */
|
|
610
756
|
interface ModelSecurityService {
|
|
611
757
|
listGroups(opts?: ModelSecurityGroupListOptions): Promise<{
|
|
@@ -671,6 +817,23 @@ interface ModelSecurityService {
|
|
|
671
817
|
values: string[];
|
|
672
818
|
}>;
|
|
673
819
|
getPyPIAuth(): Promise<ModelSecurityPyPIAuth>;
|
|
820
|
+
listModels(opts?: ModelSecurityModelListOptions): Promise<{
|
|
821
|
+
totalItems: number;
|
|
822
|
+
models: ModelSecurityModel[];
|
|
823
|
+
}>;
|
|
824
|
+
getModel(uuid: string): Promise<ModelSecurityModel>;
|
|
825
|
+
listModelVersions(modelUuid: string, opts?: ModelSecurityModelVersionListOptions): Promise<{
|
|
826
|
+
totalItems: number;
|
|
827
|
+
versions: ModelSecurityModelVersion[];
|
|
828
|
+
}>;
|
|
829
|
+
getModelVersion(uuid: string): Promise<ModelSecurityModelVersion>;
|
|
830
|
+
listModelVersionFiles(modelVersionUuid: string, opts?: {
|
|
831
|
+
skip?: number;
|
|
832
|
+
limit?: number;
|
|
833
|
+
}): Promise<{
|
|
834
|
+
totalItems: number;
|
|
835
|
+
files: ModelSecurityFile[];
|
|
836
|
+
}>;
|
|
674
837
|
}
|
|
675
838
|
/** Normalized security profile. */
|
|
676
839
|
interface SecurityProfileInfo {
|
|
@@ -1016,6 +1179,23 @@ declare class SdkModelSecurityService implements ModelSecurityService {
|
|
|
1016
1179
|
values: string[];
|
|
1017
1180
|
}>;
|
|
1018
1181
|
getPyPIAuth(): Promise<ModelSecurityPyPIAuth>;
|
|
1182
|
+
listModels(opts?: ModelSecurityModelListOptions): Promise<{
|
|
1183
|
+
totalItems: number;
|
|
1184
|
+
models: ModelSecurityModel[];
|
|
1185
|
+
}>;
|
|
1186
|
+
getModel(uuid: string): Promise<ModelSecurityModel>;
|
|
1187
|
+
listModelVersions(modelUuid: string, opts?: ModelSecurityModelVersionListOptions): Promise<{
|
|
1188
|
+
totalItems: number;
|
|
1189
|
+
versions: ModelSecurityModelVersion[];
|
|
1190
|
+
}>;
|
|
1191
|
+
getModelVersion(uuid: string): Promise<ModelSecurityModelVersion>;
|
|
1192
|
+
listModelVersionFiles(modelVersionUuid: string, opts?: {
|
|
1193
|
+
skip?: number;
|
|
1194
|
+
limit?: number;
|
|
1195
|
+
}): Promise<{
|
|
1196
|
+
totalItems: number;
|
|
1197
|
+
files: ModelSecurityFile[];
|
|
1198
|
+
}>;
|
|
1019
1199
|
}
|
|
1020
1200
|
|
|
1021
1201
|
/**
|
|
@@ -1139,6 +1319,23 @@ declare class SdkRedTeamService implements RedTeamService {
|
|
|
1139
1319
|
}): Promise<RedTeamCustomAttack[]>;
|
|
1140
1320
|
getCategories(): Promise<RedTeamCategory[]>;
|
|
1141
1321
|
waitForCompletion(jobId: string, onProgress?: (job: RedTeamJob) => void, intervalMs?: number): Promise<RedTeamJob>;
|
|
1322
|
+
listChannels(opts?: RedTeamChannelListOptions): Promise<{
|
|
1323
|
+
channels: RedTeamChannel[];
|
|
1324
|
+
totalItems?: number;
|
|
1325
|
+
}>;
|
|
1326
|
+
getChannel(channelId: string): Promise<RedTeamChannel>;
|
|
1327
|
+
createChannel(request: RedTeamChannelCreateRequest): Promise<RedTeamChannel>;
|
|
1328
|
+
updateChannel(channelId: string, request: RedTeamChannelUpdateRequest): Promise<RedTeamChannel>;
|
|
1329
|
+
getChannelStats(): Promise<RedTeamChannelStats>;
|
|
1330
|
+
getLanguages(management?: boolean): Promise<RedTeamLanguages>;
|
|
1331
|
+
getTargetProfileErrorLogs(targetId: string, opts?: {
|
|
1332
|
+
limit?: number;
|
|
1333
|
+
offset?: number;
|
|
1334
|
+
search?: string;
|
|
1335
|
+
}): Promise<{
|
|
1336
|
+
logs: RedTeamErrorLog[];
|
|
1337
|
+
totalItems?: number;
|
|
1338
|
+
}>;
|
|
1142
1339
|
}
|
|
1143
1340
|
|
|
1144
1341
|
interface PollRetryOptions {
|
|
@@ -1230,6 +1427,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1230
1427
|
redTeamDataEndpoint: z.ZodOptional<z.ZodString>;
|
|
1231
1428
|
redTeamMgmtEndpoint: z.ZodOptional<z.ZodString>;
|
|
1232
1429
|
redTeamTokenEndpoint: z.ZodOptional<z.ZodString>;
|
|
1430
|
+
redTeamNetworkBrokerEndpoint: z.ZodOptional<z.ZodString>;
|
|
1233
1431
|
modelSecDataEndpoint: z.ZodOptional<z.ZodString>;
|
|
1234
1432
|
modelSecMgmtEndpoint: z.ZodOptional<z.ZodString>;
|
|
1235
1433
|
modelSecTokenEndpoint: z.ZodOptional<z.ZodString>;
|
|
@@ -1251,6 +1449,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1251
1449
|
redTeamDataEndpoint?: string | undefined;
|
|
1252
1450
|
redTeamMgmtEndpoint?: string | undefined;
|
|
1253
1451
|
redTeamTokenEndpoint?: string | undefined;
|
|
1452
|
+
redTeamNetworkBrokerEndpoint?: string | undefined;
|
|
1254
1453
|
modelSecDataEndpoint?: string | undefined;
|
|
1255
1454
|
modelSecMgmtEndpoint?: string | undefined;
|
|
1256
1455
|
modelSecTokenEndpoint?: string | undefined;
|
|
@@ -1268,6 +1467,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1268
1467
|
redTeamDataEndpoint?: string | undefined;
|
|
1269
1468
|
redTeamMgmtEndpoint?: string | undefined;
|
|
1270
1469
|
redTeamTokenEndpoint?: string | undefined;
|
|
1470
|
+
redTeamNetworkBrokerEndpoint?: string | undefined;
|
|
1271
1471
|
modelSecDataEndpoint?: string | undefined;
|
|
1272
1472
|
modelSecMgmtEndpoint?: string | undefined;
|
|
1273
1473
|
modelSecTokenEndpoint?: string | undefined;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdot65/prisma-airs-cli",
|
|
3
3
|
"packageManager": "pnpm@10.6.5",
|
|
4
|
-
"version": "3.0
|
|
4
|
+
"version": "3.1.0",
|
|
5
5
|
"description": "CLI and library for Palo Alto Prisma AIRS — guardrail refinement, AI red teaming, model security scanning, profile audits",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/index.js",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"license": "MIT",
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@cdot65/prisma-airs-sdk": "^0.
|
|
47
|
+
"@cdot65/prisma-airs-sdk": "^0.13.0",
|
|
48
48
|
"@inquirer/prompts": "^8.3.0",
|
|
49
49
|
"chalk": "^5.6.2",
|
|
50
50
|
"commander": "^14.0.3",
|