@cdot65/prisma-airs-sdk 0.1.2 → 0.2.1

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/index.cjs CHANGED
@@ -25,15 +25,27 @@ __export(index_exports, {
25
25
  AI_SEC_API_KEY: () => AI_SEC_API_KEY,
26
26
  AI_SEC_API_TOKEN: () => AI_SEC_API_TOKEN,
27
27
  ASYNC_SCAN_PATH: () => ASYNC_SCAN_PATH,
28
+ Action: () => Action,
28
29
  AgentMetaSchema: () => AgentMetaSchema,
29
30
  AiProfileSchema: () => AiProfileSchema,
30
31
  AsyncScanObjectSchema: () => AsyncScanObjectSchema,
31
32
  AsyncScanResponseSchema: () => AsyncScanResponseSchema,
32
33
  BEARER: () => BEARER,
34
+ Category: () => Category,
33
35
  Content: () => Content,
36
+ CreateCustomTopicRequestSchema: () => CreateCustomTopicRequestSchema,
37
+ CreateSecurityProfileRequestSchema: () => CreateSecurityProfileRequestSchema,
38
+ CustomTopicListResponseSchema: () => CustomTopicListResponseSchema,
39
+ CustomTopicSchema: () => CustomTopicSchema,
34
40
  DEFAULT_ENDPOINT: () => DEFAULT_ENDPOINT,
41
+ DEFAULT_MGMT_ENDPOINT: () => DEFAULT_MGMT_ENDPOINT,
42
+ DEFAULT_TOKEN_ENDPOINT: () => DEFAULT_TOKEN_ENDPOINT,
35
43
  DSDetailResultSchema: () => DSDetailResultSchema,
36
44
  DSResultMetadataSchema: () => DSResultMetadataSchema,
45
+ DeleteProfileConflictSchema: () => DeleteProfileConflictSchema,
46
+ DeleteProfileResponseSchema: () => DeleteProfileResponseSchema,
47
+ DeleteTopicConflictSchema: () => DeleteTopicConflictSchema,
48
+ DeleteTopicResponseSchema: () => DeleteTopicResponseSchema,
37
49
  DetectionServiceResultSchema: () => DetectionServiceResultSchema,
38
50
  DlpReportSchema: () => DlpReportSchema,
39
51
  ErrorResponseSchema: () => ErrorResponseSchema,
@@ -57,9 +69,22 @@ __export(index_exports, {
57
69
  MAX_SESSION_ID_STR_LENGTH: () => MAX_SESSION_ID_STR_LENGTH,
58
70
  MAX_TOKEN_LENGTH: () => MAX_TOKEN_LENGTH,
59
71
  MAX_TRANSACTION_ID_STR_LENGTH: () => MAX_TRANSACTION_ID_STR_LENGTH,
72
+ MGMT_CLIENT_ID: () => MGMT_CLIENT_ID,
73
+ MGMT_CLIENT_SECRET: () => MGMT_CLIENT_SECRET,
74
+ MGMT_ENDPOINT: () => MGMT_ENDPOINT,
75
+ MGMT_PROFILES_TSG_PATH: () => MGMT_PROFILES_TSG_PATH,
76
+ MGMT_PROFILE_PATH: () => MGMT_PROFILE_PATH,
77
+ MGMT_TOKEN_ENDPOINT: () => MGMT_TOKEN_ENDPOINT,
78
+ MGMT_TOPICS_TSG_PATH: () => MGMT_TOPICS_TSG_PATH,
79
+ MGMT_TOPIC_FORCE_PATH: () => MGMT_TOPIC_FORCE_PATH,
80
+ MGMT_TOPIC_PATH: () => MGMT_TOPIC_PATH,
81
+ MGMT_TSG_ID: () => MGMT_TSG_ID,
82
+ ManagementClient: () => ManagementClient,
60
83
  MaskedDataSchema: () => MaskedDataSchema,
61
84
  MetadataSchema: () => MetadataSchema,
62
85
  PAYLOAD_HASH: () => PAYLOAD_HASH,
86
+ PolicySchema: () => PolicySchema,
87
+ ProfilesClient: () => ProfilesClient,
63
88
  PromptDetectedSchema: () => PromptDetectedSchema,
64
89
  PromptDetectionDetailsSchema: () => PromptDetectionDetailsSchema,
65
90
  ResponseDetectedSchema: () => ResponseDetectedSchema,
@@ -74,12 +99,16 @@ __export(index_exports, {
74
99
  ScanResponseSchema: () => ScanResponseSchema,
75
100
  ScanSummarySchema: () => ScanSummarySchema,
76
101
  Scanner: () => Scanner,
102
+ SecurityProfileListResponseSchema: () => SecurityProfileListResponseSchema,
103
+ SecurityProfileSchema: () => SecurityProfileSchema,
77
104
  ThreatScanReportSchema: () => ThreatScanReportSchema,
78
105
  ToolDetectedSchema: () => ToolDetectedSchema,
79
106
  ToolEventMetadataSchema: () => ToolEventMetadataSchema,
80
107
  ToolEventSchema: () => ToolEventSchema,
108
+ TopicsClient: () => TopicsClient,
81
109
  USER_AGENT: () => USER_AGENT,
82
110
  UrlfEntrySchema: () => UrlfEntrySchema,
111
+ Verdict: () => Verdict,
83
112
  globalConfiguration: () => globalConfiguration,
84
113
  init: () => init
85
114
  });
@@ -110,12 +139,24 @@ var MAX_NUMBER_OF_BATCH_SCAN_OBJECTS = 5;
110
139
  var MAX_CONNECTION_POOL_SIZE = 100;
111
140
  var MAX_NUMBER_OF_RETRIES = 5;
112
141
  var HTTP_FORCE_RETRY_STATUS_CODES = [500, 502, 503, 504];
113
- var SDK_VERSION = "0.1.2";
142
+ var SDK_VERSION = "0.2.1";
114
143
  var USER_AGENT = `PAN-AIRS/${SDK_VERSION}-typescript-sdk`;
144
+ var DEFAULT_MGMT_ENDPOINT = "https://api.sase.paloaltonetworks.com/aisec";
145
+ var DEFAULT_TOKEN_ENDPOINT = "https://auth.apps.paloaltonetworks.com/oauth2/access_token";
146
+ var MGMT_CLIENT_ID = "PANW_MGMT_CLIENT_ID";
147
+ var MGMT_CLIENT_SECRET = "PANW_MGMT_CLIENT_SECRET";
148
+ var MGMT_TSG_ID = "PANW_MGMT_TSG_ID";
149
+ var MGMT_ENDPOINT = "PANW_MGMT_ENDPOINT";
150
+ var MGMT_TOKEN_ENDPOINT = "PANW_MGMT_TOKEN_ENDPOINT";
115
151
  var SYNC_SCAN_PATH = "/v1/scan/sync/request";
116
152
  var ASYNC_SCAN_PATH = "/v1/scan/async/request";
117
153
  var SCAN_RESULTS_PATH = "/v1/scan/results";
118
154
  var SCAN_REPORTS_PATH = "/v1/scan/reports";
155
+ var MGMT_PROFILE_PATH = "/v1/mgmt/profile";
156
+ var MGMT_PROFILES_TSG_PATH = "/v1/mgmt/profiles/tsg";
157
+ var MGMT_TOPIC_PATH = "/v1/mgmt/topic";
158
+ var MGMT_TOPICS_TSG_PATH = "/v1/mgmt/topics/tsg";
159
+ var MGMT_TOPIC_FORCE_PATH = "/v1/mgmt/topic/force";
119
160
 
120
161
  // src/errors.ts
121
162
  var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
@@ -124,10 +165,15 @@ var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
124
165
  ErrorType2["USER_REQUEST_PAYLOAD_ERROR"] = "AISEC_USER_REQUEST_PAYLOAD_ERROR";
125
166
  ErrorType2["MISSING_VARIABLE"] = "AISEC_MISSING_VARIABLE";
126
167
  ErrorType2["AISEC_SDK_ERROR"] = "AISEC_SDK_ERROR";
168
+ ErrorType2["OAUTH_ERROR"] = "AISEC_OAUTH_ERROR";
127
169
  return ErrorType2;
128
170
  })(ErrorType || {});
129
171
  var AISecSDKException = class _AISecSDKException extends Error {
130
172
  errorType;
173
+ /**
174
+ * @param message - Human-readable error description.
175
+ * @param errorType - Classification of the error.
176
+ */
131
177
  constructor(message, errorType) {
132
178
  super(errorType ? `${errorType}:${message}` : message);
133
179
  this.name = "AISecSDKException";
@@ -209,6 +255,68 @@ function init(opts = {}) {
209
255
  globalConfiguration.init(opts);
210
256
  }
211
257
 
258
+ // src/http-retry.ts
259
+ function sleep(ms) {
260
+ return new Promise((resolve) => setTimeout(resolve, ms));
261
+ }
262
+ function backoffDelay(attempt) {
263
+ return Math.pow(2, attempt) * 1e3;
264
+ }
265
+ function isRetryableStatus(status) {
266
+ return HTTP_FORCE_RETRY_STATUS_CODES.includes(status);
267
+ }
268
+ function classifyErrorType(status) {
269
+ return status >= 500 ? "AISEC_SERVER_SIDE_ERROR" /* SERVER_SIDE_ERROR */ : "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */;
270
+ }
271
+ function extractErrorMessage(body, status) {
272
+ try {
273
+ const parsed = JSON.parse(body);
274
+ return parsed.error_message ?? parsed.message ?? parsed.error?.message ?? `API error ${status}`;
275
+ } catch {
276
+ return body ? `API error ${status}: ${body}` : `API error ${status}`;
277
+ }
278
+ }
279
+ async function executeWithRetry(opts) {
280
+ const { maxRetries, execute, onRetryableFailure } = opts;
281
+ let lastError;
282
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
283
+ let response;
284
+ try {
285
+ response = await execute(attempt);
286
+ } catch (err) {
287
+ if (err instanceof AISecSDKException) throw err;
288
+ lastError = err;
289
+ if (attempt < maxRetries) {
290
+ await sleep(backoffDelay(attempt));
291
+ continue;
292
+ }
293
+ throw new AISecSDKException(
294
+ lastError.message ?? "Network error",
295
+ "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */
296
+ );
297
+ }
298
+ if (response.ok) return response;
299
+ if (onRetryableFailure) {
300
+ const handled = await onRetryableFailure(response, attempt);
301
+ if (handled) {
302
+ attempt--;
303
+ continue;
304
+ }
305
+ }
306
+ if (isRetryableStatus(response.status) && attempt < maxRetries) {
307
+ await sleep(backoffDelay(attempt));
308
+ continue;
309
+ }
310
+ const errorText = await response.text();
311
+ const errorMessage = extractErrorMessage(errorText, response.status);
312
+ throw new AISecSDKException(errorMessage, classifyErrorType(response.status));
313
+ }
314
+ throw new AISecSDKException(
315
+ lastError?.message ?? "Max retries exceeded",
316
+ "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */
317
+ );
318
+ }
319
+
212
320
  // src/utils.ts
213
321
  var import_node_crypto = require("crypto");
214
322
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -234,9 +342,6 @@ function buildHeaders() {
234
342
  }
235
343
  return headers;
236
344
  }
237
- function sleep(ms) {
238
- return new Promise((resolve) => setTimeout(resolve, ms));
239
- }
240
345
  async function httpRequest(opts) {
241
346
  if (!globalConfiguration.initialized) {
242
347
  throw new AISecSDKException(
@@ -259,48 +364,27 @@ async function httpRequest(opts) {
259
364
  headers[PAYLOAD_HASH] = generatePayloadHash(bodyStr, globalConfiguration.apiKey);
260
365
  }
261
366
  }
262
- const maxRetries = globalConfiguration.numRetries;
263
- let lastError;
264
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
265
- try {
266
- const response = await fetch(url.toString(), {
267
- method: opts.method,
268
- headers,
269
- body: bodyStr
270
- });
271
- if (response.ok) {
272
- const data = await response.json();
273
- return { status: response.status, data };
274
- }
275
- if (HTTP_FORCE_RETRY_STATUS_CODES.includes(response.status) && attempt < maxRetries) {
276
- await sleep(Math.pow(2, attempt) * 1e3);
277
- continue;
278
- }
279
- let errorMessage;
280
- try {
281
- const errorBody = await response.json();
282
- errorMessage = errorBody.message ?? errorBody.error?.message ?? `API error ${response.status}`;
283
- } catch {
284
- errorMessage = `API error ${response.status}`;
285
- }
286
- const errorType = response.status >= 500 ? "AISEC_SERVER_SIDE_ERROR" /* SERVER_SIDE_ERROR */ : "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */;
287
- throw new AISecSDKException(errorMessage, errorType);
288
- } catch (err) {
289
- if (err instanceof AISecSDKException) {
290
- throw err;
291
- }
292
- lastError = err;
293
- if (attempt < maxRetries) {
294
- await sleep(Math.pow(2, attempt) * 1e3);
295
- continue;
296
- }
297
- }
298
- }
299
- throw new AISecSDKException(lastError?.message ?? "Network error", "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */);
367
+ const response = await executeWithRetry({
368
+ maxRetries: globalConfiguration.numRetries,
369
+ execute: () => fetch(url.toString(), {
370
+ method: opts.method,
371
+ headers,
372
+ body: bodyStr
373
+ })
374
+ });
375
+ const data = await response.json();
376
+ return { status: response.status, data };
300
377
  }
301
378
 
302
379
  // src/scan/scanner.ts
303
380
  var Scanner = class {
381
+ /**
382
+ * Perform a synchronous content scan.
383
+ * @param aiProfile - AI security profile to scan against.
384
+ * @param content - Content to scan.
385
+ * @param opts - Optional transaction/session IDs and metadata.
386
+ * @returns Scan response with verdict, action, and detection details.
387
+ */
304
388
  async syncScan(aiProfile, content, opts = {}) {
305
389
  if (opts.trId && opts.trId.length > MAX_TRANSACTION_ID_STR_LENGTH) {
306
390
  throw new AISecSDKException(
@@ -328,6 +412,11 @@ var Scanner = class {
328
412
  });
329
413
  return res.data;
330
414
  }
415
+ /**
416
+ * Submit content for asynchronous scanning.
417
+ * @param scanObjects - Array of scan objects (1–5 items).
418
+ * @returns Response containing scan IDs for later querying.
419
+ */
331
420
  async asyncScan(scanObjects) {
332
421
  if (scanObjects.length < 1) {
333
422
  throw new AISecSDKException(
@@ -348,6 +437,11 @@ var Scanner = class {
348
437
  });
349
438
  return res.data;
350
439
  }
440
+ /**
441
+ * Query scan results by scan IDs.
442
+ * @param scanIds - Array of scan UUIDs (1–5 items).
443
+ * @returns Array of scan results with status and response data.
444
+ */
351
445
  async queryByScanIds(scanIds) {
352
446
  if (scanIds.length < 1) {
353
447
  throw new AISecSDKException(
@@ -373,6 +467,11 @@ var Scanner = class {
373
467
  });
374
468
  return res.data;
375
469
  }
470
+ /**
471
+ * Query detailed threat reports by report IDs.
472
+ * @param reportIds - Array of report IDs (1–5 items).
473
+ * @returns Array of threat scan reports with detection details.
474
+ */
376
475
  async queryByReportIds(reportIds) {
377
476
  if (reportIds.length < 1) {
378
477
  throw new AISecSDKException(
@@ -484,6 +583,7 @@ var Content = class _Content {
484
583
  set toolEvent(value) {
485
584
  this._toolEvent = value;
486
585
  }
586
+ /** Total byte length of all text content fields. */
487
587
  get length() {
488
588
  let total = 0;
489
589
  if (this._prompt) total += Buffer.byteLength(this._prompt);
@@ -493,6 +593,7 @@ var Content = class _Content {
493
593
  if (this._codeResponse) total += Buffer.byteLength(this._codeResponse);
494
594
  return total;
495
595
  }
596
+ /** Serialize to the API request format. */
496
597
  toJSON() {
497
598
  const obj = {};
498
599
  if (this._prompt !== void 0) obj.prompt = this._prompt;
@@ -503,6 +604,10 @@ var Content = class _Content {
503
604
  if (this._toolEvent !== void 0) obj.tool_event = this._toolEvent;
504
605
  return obj;
505
606
  }
607
+ /**
608
+ * Create a Content instance from an API response object.
609
+ * @param json - Scan request contents inner object.
610
+ */
506
611
  static fromJSON(json) {
507
612
  return new _Content({
508
613
  prompt: json.prompt,
@@ -513,6 +618,10 @@ var Content = class _Content {
513
618
  toolEvent: json.tool_event
514
619
  });
515
620
  }
621
+ /**
622
+ * Load content from a JSON file.
623
+ * @param filePath - Path to JSON file containing scan request contents.
624
+ */
516
625
  static fromJSONFile(filePath) {
517
626
  const raw = (0, import_node_fs.readFileSync)(filePath, "utf-8");
518
627
  const parsed = JSON.parse(raw);
@@ -520,6 +629,23 @@ var Content = class _Content {
520
629
  }
521
630
  };
522
631
 
632
+ // src/models/enums.ts
633
+ var Verdict = {
634
+ BENIGN: "benign",
635
+ MALICIOUS: "malicious",
636
+ UNKNOWN: "unknown"
637
+ };
638
+ var Action = {
639
+ ALLOW: "allow",
640
+ BLOCK: "block",
641
+ ALERT: "alert"
642
+ };
643
+ var Category = {
644
+ BENIGN: "benign",
645
+ MALICIOUS: "malicious",
646
+ UNKNOWN: "unknown"
647
+ };
648
+
523
649
  // src/models/ai-profile.ts
524
650
  var import_zod = require("zod");
525
651
  var AiProfileSchema = import_zod.z.object({
@@ -744,6 +870,513 @@ var ErrorResponseSchema = import_zod14.z.object({
744
870
  unit: import_zod14.z.string().optional()
745
871
  }).optional()
746
872
  });
873
+
874
+ // src/models/mgmt-security-profile.ts
875
+ var import_zod15 = require("zod");
876
+ var DlpDataProfileSchema = import_zod15.z.object({
877
+ profile_name: import_zod15.z.string(),
878
+ active: import_zod15.z.boolean().optional()
879
+ }).passthrough();
880
+ var DlpSchema = import_zod15.z.object({
881
+ dlp_status: import_zod15.z.string().optional(),
882
+ data_profiles: import_zod15.z.array(DlpDataProfileSchema).optional()
883
+ }).passthrough();
884
+ var DataLeakDetectionSchema = import_zod15.z.object({
885
+ "data-leak-detection-status": import_zod15.z.string().optional(),
886
+ dlp: DlpSchema.optional()
887
+ }).passthrough();
888
+ var AppProtectionSchema = import_zod15.z.object({
889
+ "prompt-injection": import_zod15.z.string().optional(),
890
+ "jailbreak-detection": import_zod15.z.string().optional()
891
+ }).passthrough();
892
+ var ModelProtectionSchema = import_zod15.z.object({
893
+ "model-denial-of-service": import_zod15.z.string().optional()
894
+ }).passthrough();
895
+ var AgentProtectionSchema = import_zod15.z.object({
896
+ "malicious-agent-activity": import_zod15.z.string().optional()
897
+ }).passthrough();
898
+ var LatencySchema = import_zod15.z.object({
899
+ status: import_zod15.z.string().optional(),
900
+ max_latency_ms: import_zod15.z.number().optional()
901
+ }).passthrough();
902
+ var ModelConfigurationSchema = import_zod15.z.object({
903
+ latency: LatencySchema.optional()
904
+ }).passthrough();
905
+ var PolicySchema = import_zod15.z.object({
906
+ "data-leak-detection": DataLeakDetectionSchema.optional(),
907
+ "app-protection": AppProtectionSchema.optional(),
908
+ "model-protection": ModelProtectionSchema.optional(),
909
+ "agent-protection": AgentProtectionSchema.optional(),
910
+ "model-configuration": ModelConfigurationSchema.optional()
911
+ }).passthrough();
912
+ var SecurityProfileSchema = import_zod15.z.object({
913
+ profile_id: import_zod15.z.string().optional(),
914
+ profile_name: import_zod15.z.string(),
915
+ revision: import_zod15.z.number().optional(),
916
+ active: import_zod15.z.boolean().optional(),
917
+ policy: PolicySchema.optional(),
918
+ created_by: import_zod15.z.string().optional(),
919
+ updated_by: import_zod15.z.string().optional(),
920
+ last_modified_ts: import_zod15.z.string().optional()
921
+ }).passthrough();
922
+ var CreateSecurityProfileRequestSchema = import_zod15.z.object({
923
+ profile_id: import_zod15.z.string().optional(),
924
+ profile_name: import_zod15.z.string(),
925
+ revision: import_zod15.z.number().optional(),
926
+ active: import_zod15.z.boolean().optional(),
927
+ policy: PolicySchema.optional(),
928
+ created_by: import_zod15.z.string().optional(),
929
+ updated_by: import_zod15.z.string().optional(),
930
+ last_modified_ts: import_zod15.z.string().optional()
931
+ }).passthrough();
932
+ var SecurityProfileListResponseSchema = import_zod15.z.object({
933
+ ai_profiles: import_zod15.z.array(SecurityProfileSchema),
934
+ next_offset: import_zod15.z.number().optional()
935
+ }).passthrough();
936
+ var DeleteProfileResponseSchema = import_zod15.z.object({
937
+ message: import_zod15.z.string()
938
+ }).passthrough();
939
+ var DeleteProfileConflictSchema = import_zod15.z.object({
940
+ message: import_zod15.z.string(),
941
+ payload: import_zod15.z.array(
942
+ import_zod15.z.object({
943
+ policy_id: import_zod15.z.string(),
944
+ policy_name: import_zod15.z.string(),
945
+ priority: import_zod15.z.number()
946
+ }).passthrough()
947
+ )
948
+ }).passthrough();
949
+
950
+ // src/models/mgmt-custom-topic.ts
951
+ var import_zod16 = require("zod");
952
+ var CustomTopicSchema = import_zod16.z.object({
953
+ topic_id: import_zod16.z.string().optional(),
954
+ topic_name: import_zod16.z.string(),
955
+ revision: import_zod16.z.number().optional(),
956
+ active: import_zod16.z.boolean().optional(),
957
+ description: import_zod16.z.string().optional(),
958
+ examples: import_zod16.z.array(import_zod16.z.string()).optional(),
959
+ created_by: import_zod16.z.string().optional(),
960
+ updated_by: import_zod16.z.string().optional(),
961
+ last_modified_ts: import_zod16.z.string().optional(),
962
+ created_ts: import_zod16.z.string().optional()
963
+ }).passthrough();
964
+ var CreateCustomTopicRequestSchema = import_zod16.z.object({
965
+ topic_id: import_zod16.z.string().optional(),
966
+ topic_name: import_zod16.z.string(),
967
+ revision: import_zod16.z.number().optional(),
968
+ active: import_zod16.z.boolean().optional(),
969
+ description: import_zod16.z.string().optional(),
970
+ examples: import_zod16.z.array(import_zod16.z.string()).optional(),
971
+ created_by: import_zod16.z.string().optional(),
972
+ updated_by: import_zod16.z.string().optional(),
973
+ last_modified_ts: import_zod16.z.string().optional(),
974
+ created_ts: import_zod16.z.string().optional()
975
+ }).passthrough();
976
+ var CustomTopicListResponseSchema = import_zod16.z.object({
977
+ custom_topics: import_zod16.z.array(CustomTopicSchema),
978
+ next_offset: import_zod16.z.number().optional()
979
+ }).passthrough();
980
+ var DeleteTopicResponseSchema = import_zod16.z.object({
981
+ message: import_zod16.z.string()
982
+ }).passthrough();
983
+ var DeleteTopicConflictSchema = import_zod16.z.object({
984
+ message: import_zod16.z.string(),
985
+ payload: import_zod16.z.array(
986
+ import_zod16.z.object({
987
+ profile_id: import_zod16.z.string(),
988
+ profile_name: import_zod16.z.string(),
989
+ revision: import_zod16.z.number()
990
+ }).passthrough()
991
+ )
992
+ }).passthrough();
993
+
994
+ // src/models/oauth-token.ts
995
+ var import_zod17 = require("zod");
996
+ var OAuthTokenResponseSchema = import_zod17.z.object({
997
+ access_token: import_zod17.z.string(),
998
+ token_type: import_zod17.z.string().optional(),
999
+ expires_in: import_zod17.z.number(),
1000
+ scope: import_zod17.z.string().optional()
1001
+ });
1002
+
1003
+ // src/management/oauth-client.ts
1004
+ var TOKEN_BUFFER_MS = 3e4;
1005
+ var OAuthClient = class {
1006
+ tokenEndpoint;
1007
+ clientId;
1008
+ clientSecret;
1009
+ tsgId;
1010
+ accessToken = null;
1011
+ expiresAt = 0;
1012
+ pendingFetch = null;
1013
+ constructor(opts) {
1014
+ this.clientId = opts.clientId;
1015
+ this.clientSecret = opts.clientSecret;
1016
+ this.tsgId = opts.tsgId;
1017
+ this.tokenEndpoint = opts.tokenEndpoint ?? DEFAULT_TOKEN_ENDPOINT;
1018
+ }
1019
+ /**
1020
+ * Get a valid access token, refreshing if needed.
1021
+ * @returns Bearer access token string.
1022
+ */
1023
+ async getToken() {
1024
+ if (this.accessToken && Date.now() < this.expiresAt - TOKEN_BUFFER_MS) {
1025
+ return this.accessToken;
1026
+ }
1027
+ if (this.pendingFetch) {
1028
+ return this.pendingFetch;
1029
+ }
1030
+ this.pendingFetch = this.fetchToken().finally(() => {
1031
+ this.pendingFetch = null;
1032
+ });
1033
+ return this.pendingFetch;
1034
+ }
1035
+ /** Clear the cached token, forcing a fresh fetch on next call. */
1036
+ clearToken() {
1037
+ this.accessToken = null;
1038
+ this.expiresAt = 0;
1039
+ }
1040
+ async fetchToken() {
1041
+ const credentials = btoa(`${this.clientId}:${this.clientSecret}`);
1042
+ const body = new URLSearchParams({
1043
+ grant_type: "client_credentials",
1044
+ scope: `tsg_id:${this.tsgId}`
1045
+ });
1046
+ let response;
1047
+ try {
1048
+ response = await fetch(this.tokenEndpoint, {
1049
+ method: "POST",
1050
+ headers: {
1051
+ "Content-Type": "application/x-www-form-urlencoded",
1052
+ Authorization: `Basic ${credentials}`
1053
+ },
1054
+ body: body.toString()
1055
+ });
1056
+ } catch (err) {
1057
+ throw new AISecSDKException(
1058
+ `Token request failed: ${err.message}`,
1059
+ "AISEC_OAUTH_ERROR" /* OAUTH_ERROR */
1060
+ );
1061
+ }
1062
+ if (!response.ok) {
1063
+ let errorMsg;
1064
+ try {
1065
+ const errorBody = await response.json();
1066
+ errorMsg = errorBody.error_description ?? errorBody.error ?? `Token request failed with status ${response.status}`;
1067
+ } catch {
1068
+ errorMsg = `Token request failed with status ${response.status}`;
1069
+ }
1070
+ throw new AISecSDKException(errorMsg, "AISEC_OAUTH_ERROR" /* OAUTH_ERROR */);
1071
+ }
1072
+ const data = OAuthTokenResponseSchema.parse(await response.json());
1073
+ this.accessToken = data.access_token;
1074
+ this.expiresAt = Date.now() + data.expires_in * 1e3;
1075
+ return this.accessToken;
1076
+ }
1077
+ };
1078
+
1079
+ // src/management/management-http-client.ts
1080
+ async function managementHttpRequest(opts) {
1081
+ const { method, baseUrl, path, body, params, oauthClient, numRetries } = opts;
1082
+ let hadTokenRefresh = false;
1083
+ const response = await executeWithRetry({
1084
+ maxRetries: numRetries,
1085
+ execute: async () => {
1086
+ const token = await oauthClient.getToken();
1087
+ const stripped = baseUrl.replace(/\/+$/, "");
1088
+ const url = new URL(`${stripped}${path}`);
1089
+ if (params) {
1090
+ for (const [key, value] of Object.entries(params)) {
1091
+ url.searchParams.set(key, value);
1092
+ }
1093
+ }
1094
+ const headers = {
1095
+ Authorization: `Bearer ${token}`,
1096
+ "User-Agent": USER_AGENT
1097
+ };
1098
+ let bodyStr;
1099
+ if (body !== void 0) {
1100
+ headers["Content-Type"] = "application/json";
1101
+ bodyStr = JSON.stringify(body);
1102
+ }
1103
+ return fetch(url.toString(), { method, headers, body: bodyStr });
1104
+ },
1105
+ onRetryableFailure: async (response2) => {
1106
+ if (response2.status === 401 && !hadTokenRefresh) {
1107
+ hadTokenRefresh = true;
1108
+ oauthClient.clearToken();
1109
+ return true;
1110
+ }
1111
+ return false;
1112
+ }
1113
+ });
1114
+ const text = await response.text();
1115
+ const data = text ? JSON.parse(text) : {};
1116
+ return { status: response.status, data };
1117
+ }
1118
+
1119
+ // src/management/profiles.ts
1120
+ var ProfilesClient = class {
1121
+ baseUrl;
1122
+ oauthClient;
1123
+ tsgId;
1124
+ numRetries;
1125
+ constructor(opts) {
1126
+ this.baseUrl = opts.baseUrl;
1127
+ this.oauthClient = opts.oauthClient;
1128
+ this.tsgId = opts.tsgId;
1129
+ this.numRetries = opts.numRetries;
1130
+ }
1131
+ /**
1132
+ * Create a new security profile.
1133
+ * @param request - Profile configuration.
1134
+ * @returns The created security profile.
1135
+ */
1136
+ async create(request) {
1137
+ const res = await managementHttpRequest({
1138
+ method: "POST",
1139
+ baseUrl: this.baseUrl,
1140
+ path: MGMT_PROFILE_PATH,
1141
+ body: request,
1142
+ oauthClient: this.oauthClient,
1143
+ numRetries: this.numRetries
1144
+ });
1145
+ return res.data;
1146
+ }
1147
+ /**
1148
+ * List security profiles for the TSG.
1149
+ * @param opts - Pagination options.
1150
+ * @returns Paginated list of security profiles.
1151
+ */
1152
+ async list(opts) {
1153
+ const params = {
1154
+ offset: String(opts?.offset ?? 0),
1155
+ limit: String(opts?.limit ?? 100)
1156
+ };
1157
+ const res = await managementHttpRequest({
1158
+ method: "GET",
1159
+ baseUrl: this.baseUrl,
1160
+ path: `${MGMT_PROFILES_TSG_PATH}/${this.tsgId}`,
1161
+ params,
1162
+ oauthClient: this.oauthClient,
1163
+ numRetries: this.numRetries
1164
+ });
1165
+ return res.data;
1166
+ }
1167
+ /**
1168
+ * Update an existing security profile.
1169
+ * @param profileId - UUID of the profile to update.
1170
+ * @param request - Updated profile configuration.
1171
+ * @returns The updated security profile.
1172
+ */
1173
+ async update(profileId, request) {
1174
+ if (!isValidUuid(profileId)) {
1175
+ throw new AISecSDKException(
1176
+ `Invalid profile_id: ${profileId}`,
1177
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1178
+ );
1179
+ }
1180
+ const res = await managementHttpRequest({
1181
+ method: "PUT",
1182
+ baseUrl: this.baseUrl,
1183
+ path: `${MGMT_PROFILE_PATH}/uuid/${profileId}`,
1184
+ body: request,
1185
+ oauthClient: this.oauthClient,
1186
+ numRetries: this.numRetries
1187
+ });
1188
+ return res.data;
1189
+ }
1190
+ /**
1191
+ * Delete a security profile.
1192
+ * @param profileId - UUID of the profile to delete.
1193
+ * @returns Deletion confirmation message.
1194
+ */
1195
+ async delete(profileId) {
1196
+ if (!isValidUuid(profileId)) {
1197
+ throw new AISecSDKException(
1198
+ `Invalid profile_id: ${profileId}`,
1199
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1200
+ );
1201
+ }
1202
+ const res = await managementHttpRequest({
1203
+ method: "DELETE",
1204
+ baseUrl: this.baseUrl,
1205
+ path: `${MGMT_PROFILE_PATH}/${profileId}`,
1206
+ oauthClient: this.oauthClient,
1207
+ numRetries: this.numRetries
1208
+ });
1209
+ return res.data;
1210
+ }
1211
+ };
1212
+
1213
+ // src/management/topics.ts
1214
+ var TopicsClient = class {
1215
+ baseUrl;
1216
+ oauthClient;
1217
+ tsgId;
1218
+ numRetries;
1219
+ constructor(opts) {
1220
+ this.baseUrl = opts.baseUrl;
1221
+ this.oauthClient = opts.oauthClient;
1222
+ this.tsgId = opts.tsgId;
1223
+ this.numRetries = opts.numRetries;
1224
+ }
1225
+ /**
1226
+ * Create a new custom topic.
1227
+ * @param request - Topic definition with name, description, and examples.
1228
+ * @returns The created custom topic.
1229
+ */
1230
+ async create(request) {
1231
+ const res = await managementHttpRequest({
1232
+ method: "POST",
1233
+ baseUrl: this.baseUrl,
1234
+ path: MGMT_TOPIC_PATH,
1235
+ body: request,
1236
+ oauthClient: this.oauthClient,
1237
+ numRetries: this.numRetries
1238
+ });
1239
+ return res.data;
1240
+ }
1241
+ /**
1242
+ * List custom topics for the TSG.
1243
+ * @param opts - Pagination options.
1244
+ * @returns Paginated list of custom topics.
1245
+ */
1246
+ async list(opts) {
1247
+ const params = {
1248
+ offset: String(opts?.offset ?? 0),
1249
+ limit: String(opts?.limit ?? 100)
1250
+ };
1251
+ const res = await managementHttpRequest({
1252
+ method: "GET",
1253
+ baseUrl: this.baseUrl,
1254
+ path: `${MGMT_TOPICS_TSG_PATH}/${this.tsgId}`,
1255
+ params,
1256
+ oauthClient: this.oauthClient,
1257
+ numRetries: this.numRetries
1258
+ });
1259
+ return res.data;
1260
+ }
1261
+ /**
1262
+ * Update an existing custom topic.
1263
+ * @param topicId - UUID of the topic to update.
1264
+ * @param request - Updated topic definition.
1265
+ * @returns The updated custom topic.
1266
+ */
1267
+ async update(topicId, request) {
1268
+ if (!isValidUuid(topicId)) {
1269
+ throw new AISecSDKException(
1270
+ `Invalid topic_id: ${topicId}`,
1271
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1272
+ );
1273
+ }
1274
+ const res = await managementHttpRequest({
1275
+ method: "PUT",
1276
+ baseUrl: this.baseUrl,
1277
+ path: `${MGMT_TOPIC_PATH}/uuid/${topicId}`,
1278
+ body: request,
1279
+ oauthClient: this.oauthClient,
1280
+ numRetries: this.numRetries
1281
+ });
1282
+ return res.data;
1283
+ }
1284
+ /**
1285
+ * Delete a custom topic. Fails if topic is referenced by a profile.
1286
+ * @param topicId - UUID of the topic to delete.
1287
+ * @returns Deletion confirmation message.
1288
+ */
1289
+ async delete(topicId) {
1290
+ if (!isValidUuid(topicId)) {
1291
+ throw new AISecSDKException(
1292
+ `Invalid topic_id: ${topicId}`,
1293
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1294
+ );
1295
+ }
1296
+ const res = await managementHttpRequest({
1297
+ method: "DELETE",
1298
+ baseUrl: this.baseUrl,
1299
+ path: `${MGMT_TOPIC_PATH}/${topicId}`,
1300
+ oauthClient: this.oauthClient,
1301
+ numRetries: this.numRetries
1302
+ });
1303
+ return res.data;
1304
+ }
1305
+ /**
1306
+ * Force-delete a custom topic, removing it from any referencing profiles.
1307
+ * @param topicId - UUID of the topic to force-delete.
1308
+ * @returns Deletion confirmation message.
1309
+ */
1310
+ async forceDelete(topicId) {
1311
+ if (!isValidUuid(topicId)) {
1312
+ throw new AISecSDKException(
1313
+ `Invalid topic_id: ${topicId}`,
1314
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1315
+ );
1316
+ }
1317
+ const res = await managementHttpRequest({
1318
+ method: "DELETE",
1319
+ baseUrl: this.baseUrl,
1320
+ path: `${MGMT_TOPIC_FORCE_PATH}/${topicId}`,
1321
+ oauthClient: this.oauthClient,
1322
+ numRetries: this.numRetries
1323
+ });
1324
+ return res.data;
1325
+ }
1326
+ };
1327
+
1328
+ // src/management/client.ts
1329
+ var ManagementClient = class {
1330
+ profiles;
1331
+ topics;
1332
+ constructor(opts = {}) {
1333
+ const clientId = opts.clientId ?? process.env[MGMT_CLIENT_ID];
1334
+ const clientSecret = opts.clientSecret ?? process.env[MGMT_CLIENT_SECRET];
1335
+ const tsgId = opts.tsgId ?? process.env[MGMT_TSG_ID];
1336
+ const apiEndpoint = opts.apiEndpoint ?? process.env[MGMT_ENDPOINT] ?? DEFAULT_MGMT_ENDPOINT;
1337
+ const tokenEndpoint = opts.tokenEndpoint ?? process.env[MGMT_TOKEN_ENDPOINT];
1338
+ const numRetries = Math.min(
1339
+ Math.max(opts.numRetries ?? MAX_NUMBER_OF_RETRIES, 0),
1340
+ MAX_NUMBER_OF_RETRIES
1341
+ );
1342
+ if (!clientId) {
1343
+ throw new AISecSDKException(
1344
+ "clientId is required (option or PANW_MGMT_CLIENT_ID env var)",
1345
+ "AISEC_MISSING_VARIABLE" /* MISSING_VARIABLE */
1346
+ );
1347
+ }
1348
+ if (!clientSecret) {
1349
+ throw new AISecSDKException(
1350
+ "clientSecret is required (option or PANW_MGMT_CLIENT_SECRET env var)",
1351
+ "AISEC_MISSING_VARIABLE" /* MISSING_VARIABLE */
1352
+ );
1353
+ }
1354
+ if (!tsgId) {
1355
+ throw new AISecSDKException(
1356
+ "tsgId is required (option or PANW_MGMT_TSG_ID env var)",
1357
+ "AISEC_MISSING_VARIABLE" /* MISSING_VARIABLE */
1358
+ );
1359
+ }
1360
+ const oauthClient = new OAuthClient({
1361
+ clientId,
1362
+ clientSecret,
1363
+ tsgId,
1364
+ tokenEndpoint
1365
+ });
1366
+ this.profiles = new ProfilesClient({
1367
+ baseUrl: apiEndpoint,
1368
+ oauthClient,
1369
+ tsgId,
1370
+ numRetries
1371
+ });
1372
+ this.topics = new TopicsClient({
1373
+ baseUrl: apiEndpoint,
1374
+ oauthClient,
1375
+ tsgId,
1376
+ numRetries
1377
+ });
1378
+ }
1379
+ };
747
1380
  // Annotate the CommonJS export names for ESM import in node:
748
1381
  0 && (module.exports = {
749
1382
  AISecSDKException,
@@ -751,15 +1384,27 @@ var ErrorResponseSchema = import_zod14.z.object({
751
1384
  AI_SEC_API_KEY,
752
1385
  AI_SEC_API_TOKEN,
753
1386
  ASYNC_SCAN_PATH,
1387
+ Action,
754
1388
  AgentMetaSchema,
755
1389
  AiProfileSchema,
756
1390
  AsyncScanObjectSchema,
757
1391
  AsyncScanResponseSchema,
758
1392
  BEARER,
1393
+ Category,
759
1394
  Content,
1395
+ CreateCustomTopicRequestSchema,
1396
+ CreateSecurityProfileRequestSchema,
1397
+ CustomTopicListResponseSchema,
1398
+ CustomTopicSchema,
760
1399
  DEFAULT_ENDPOINT,
1400
+ DEFAULT_MGMT_ENDPOINT,
1401
+ DEFAULT_TOKEN_ENDPOINT,
761
1402
  DSDetailResultSchema,
762
1403
  DSResultMetadataSchema,
1404
+ DeleteProfileConflictSchema,
1405
+ DeleteProfileResponseSchema,
1406
+ DeleteTopicConflictSchema,
1407
+ DeleteTopicResponseSchema,
763
1408
  DetectionServiceResultSchema,
764
1409
  DlpReportSchema,
765
1410
  ErrorResponseSchema,
@@ -783,9 +1428,22 @@ var ErrorResponseSchema = import_zod14.z.object({
783
1428
  MAX_SESSION_ID_STR_LENGTH,
784
1429
  MAX_TOKEN_LENGTH,
785
1430
  MAX_TRANSACTION_ID_STR_LENGTH,
1431
+ MGMT_CLIENT_ID,
1432
+ MGMT_CLIENT_SECRET,
1433
+ MGMT_ENDPOINT,
1434
+ MGMT_PROFILES_TSG_PATH,
1435
+ MGMT_PROFILE_PATH,
1436
+ MGMT_TOKEN_ENDPOINT,
1437
+ MGMT_TOPICS_TSG_PATH,
1438
+ MGMT_TOPIC_FORCE_PATH,
1439
+ MGMT_TOPIC_PATH,
1440
+ MGMT_TSG_ID,
1441
+ ManagementClient,
786
1442
  MaskedDataSchema,
787
1443
  MetadataSchema,
788
1444
  PAYLOAD_HASH,
1445
+ PolicySchema,
1446
+ ProfilesClient,
789
1447
  PromptDetectedSchema,
790
1448
  PromptDetectionDetailsSchema,
791
1449
  ResponseDetectedSchema,
@@ -800,12 +1458,16 @@ var ErrorResponseSchema = import_zod14.z.object({
800
1458
  ScanResponseSchema,
801
1459
  ScanSummarySchema,
802
1460
  Scanner,
1461
+ SecurityProfileListResponseSchema,
1462
+ SecurityProfileSchema,
803
1463
  ThreatScanReportSchema,
804
1464
  ToolDetectedSchema,
805
1465
  ToolEventMetadataSchema,
806
1466
  ToolEventSchema,
1467
+ TopicsClient,
807
1468
  USER_AGENT,
808
1469
  UrlfEntrySchema,
1470
+ Verdict,
809
1471
  globalConfiguration,
810
1472
  init
811
1473
  });