@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.js CHANGED
@@ -23,12 +23,24 @@ var MAX_NUMBER_OF_BATCH_SCAN_OBJECTS = 5;
23
23
  var MAX_CONNECTION_POOL_SIZE = 100;
24
24
  var MAX_NUMBER_OF_RETRIES = 5;
25
25
  var HTTP_FORCE_RETRY_STATUS_CODES = [500, 502, 503, 504];
26
- var SDK_VERSION = "0.1.2";
26
+ var SDK_VERSION = "0.2.1";
27
27
  var USER_AGENT = `PAN-AIRS/${SDK_VERSION}-typescript-sdk`;
28
+ var DEFAULT_MGMT_ENDPOINT = "https://api.sase.paloaltonetworks.com/aisec";
29
+ var DEFAULT_TOKEN_ENDPOINT = "https://auth.apps.paloaltonetworks.com/oauth2/access_token";
30
+ var MGMT_CLIENT_ID = "PANW_MGMT_CLIENT_ID";
31
+ var MGMT_CLIENT_SECRET = "PANW_MGMT_CLIENT_SECRET";
32
+ var MGMT_TSG_ID = "PANW_MGMT_TSG_ID";
33
+ var MGMT_ENDPOINT = "PANW_MGMT_ENDPOINT";
34
+ var MGMT_TOKEN_ENDPOINT = "PANW_MGMT_TOKEN_ENDPOINT";
28
35
  var SYNC_SCAN_PATH = "/v1/scan/sync/request";
29
36
  var ASYNC_SCAN_PATH = "/v1/scan/async/request";
30
37
  var SCAN_RESULTS_PATH = "/v1/scan/results";
31
38
  var SCAN_REPORTS_PATH = "/v1/scan/reports";
39
+ var MGMT_PROFILE_PATH = "/v1/mgmt/profile";
40
+ var MGMT_PROFILES_TSG_PATH = "/v1/mgmt/profiles/tsg";
41
+ var MGMT_TOPIC_PATH = "/v1/mgmt/topic";
42
+ var MGMT_TOPICS_TSG_PATH = "/v1/mgmt/topics/tsg";
43
+ var MGMT_TOPIC_FORCE_PATH = "/v1/mgmt/topic/force";
32
44
 
33
45
  // src/errors.ts
34
46
  var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
@@ -37,10 +49,15 @@ var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
37
49
  ErrorType2["USER_REQUEST_PAYLOAD_ERROR"] = "AISEC_USER_REQUEST_PAYLOAD_ERROR";
38
50
  ErrorType2["MISSING_VARIABLE"] = "AISEC_MISSING_VARIABLE";
39
51
  ErrorType2["AISEC_SDK_ERROR"] = "AISEC_SDK_ERROR";
52
+ ErrorType2["OAUTH_ERROR"] = "AISEC_OAUTH_ERROR";
40
53
  return ErrorType2;
41
54
  })(ErrorType || {});
42
55
  var AISecSDKException = class _AISecSDKException extends Error {
43
56
  errorType;
57
+ /**
58
+ * @param message - Human-readable error description.
59
+ * @param errorType - Classification of the error.
60
+ */
44
61
  constructor(message, errorType) {
45
62
  super(errorType ? `${errorType}:${message}` : message);
46
63
  this.name = "AISecSDKException";
@@ -122,6 +139,68 @@ function init(opts = {}) {
122
139
  globalConfiguration.init(opts);
123
140
  }
124
141
 
142
+ // src/http-retry.ts
143
+ function sleep(ms) {
144
+ return new Promise((resolve) => setTimeout(resolve, ms));
145
+ }
146
+ function backoffDelay(attempt) {
147
+ return Math.pow(2, attempt) * 1e3;
148
+ }
149
+ function isRetryableStatus(status) {
150
+ return HTTP_FORCE_RETRY_STATUS_CODES.includes(status);
151
+ }
152
+ function classifyErrorType(status) {
153
+ return status >= 500 ? "AISEC_SERVER_SIDE_ERROR" /* SERVER_SIDE_ERROR */ : "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */;
154
+ }
155
+ function extractErrorMessage(body, status) {
156
+ try {
157
+ const parsed = JSON.parse(body);
158
+ return parsed.error_message ?? parsed.message ?? parsed.error?.message ?? `API error ${status}`;
159
+ } catch {
160
+ return body ? `API error ${status}: ${body}` : `API error ${status}`;
161
+ }
162
+ }
163
+ async function executeWithRetry(opts) {
164
+ const { maxRetries, execute, onRetryableFailure } = opts;
165
+ let lastError;
166
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
167
+ let response;
168
+ try {
169
+ response = await execute(attempt);
170
+ } catch (err) {
171
+ if (err instanceof AISecSDKException) throw err;
172
+ lastError = err;
173
+ if (attempt < maxRetries) {
174
+ await sleep(backoffDelay(attempt));
175
+ continue;
176
+ }
177
+ throw new AISecSDKException(
178
+ lastError.message ?? "Network error",
179
+ "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */
180
+ );
181
+ }
182
+ if (response.ok) return response;
183
+ if (onRetryableFailure) {
184
+ const handled = await onRetryableFailure(response, attempt);
185
+ if (handled) {
186
+ attempt--;
187
+ continue;
188
+ }
189
+ }
190
+ if (isRetryableStatus(response.status) && attempt < maxRetries) {
191
+ await sleep(backoffDelay(attempt));
192
+ continue;
193
+ }
194
+ const errorText = await response.text();
195
+ const errorMessage = extractErrorMessage(errorText, response.status);
196
+ throw new AISecSDKException(errorMessage, classifyErrorType(response.status));
197
+ }
198
+ throw new AISecSDKException(
199
+ lastError?.message ?? "Max retries exceeded",
200
+ "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */
201
+ );
202
+ }
203
+
125
204
  // src/utils.ts
126
205
  import { createHmac } from "crypto";
127
206
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -147,9 +226,6 @@ function buildHeaders() {
147
226
  }
148
227
  return headers;
149
228
  }
150
- function sleep(ms) {
151
- return new Promise((resolve) => setTimeout(resolve, ms));
152
- }
153
229
  async function httpRequest(opts) {
154
230
  if (!globalConfiguration.initialized) {
155
231
  throw new AISecSDKException(
@@ -172,48 +248,27 @@ async function httpRequest(opts) {
172
248
  headers[PAYLOAD_HASH] = generatePayloadHash(bodyStr, globalConfiguration.apiKey);
173
249
  }
174
250
  }
175
- const maxRetries = globalConfiguration.numRetries;
176
- let lastError;
177
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
178
- try {
179
- const response = await fetch(url.toString(), {
180
- method: opts.method,
181
- headers,
182
- body: bodyStr
183
- });
184
- if (response.ok) {
185
- const data = await response.json();
186
- return { status: response.status, data };
187
- }
188
- if (HTTP_FORCE_RETRY_STATUS_CODES.includes(response.status) && attempt < maxRetries) {
189
- await sleep(Math.pow(2, attempt) * 1e3);
190
- continue;
191
- }
192
- let errorMessage;
193
- try {
194
- const errorBody = await response.json();
195
- errorMessage = errorBody.message ?? errorBody.error?.message ?? `API error ${response.status}`;
196
- } catch {
197
- errorMessage = `API error ${response.status}`;
198
- }
199
- const errorType = response.status >= 500 ? "AISEC_SERVER_SIDE_ERROR" /* SERVER_SIDE_ERROR */ : "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */;
200
- throw new AISecSDKException(errorMessage, errorType);
201
- } catch (err) {
202
- if (err instanceof AISecSDKException) {
203
- throw err;
204
- }
205
- lastError = err;
206
- if (attempt < maxRetries) {
207
- await sleep(Math.pow(2, attempt) * 1e3);
208
- continue;
209
- }
210
- }
211
- }
212
- throw new AISecSDKException(lastError?.message ?? "Network error", "AISEC_CLIENT_SIDE_ERROR" /* CLIENT_SIDE_ERROR */);
251
+ const response = await executeWithRetry({
252
+ maxRetries: globalConfiguration.numRetries,
253
+ execute: () => fetch(url.toString(), {
254
+ method: opts.method,
255
+ headers,
256
+ body: bodyStr
257
+ })
258
+ });
259
+ const data = await response.json();
260
+ return { status: response.status, data };
213
261
  }
214
262
 
215
263
  // src/scan/scanner.ts
216
264
  var Scanner = class {
265
+ /**
266
+ * Perform a synchronous content scan.
267
+ * @param aiProfile - AI security profile to scan against.
268
+ * @param content - Content to scan.
269
+ * @param opts - Optional transaction/session IDs and metadata.
270
+ * @returns Scan response with verdict, action, and detection details.
271
+ */
217
272
  async syncScan(aiProfile, content, opts = {}) {
218
273
  if (opts.trId && opts.trId.length > MAX_TRANSACTION_ID_STR_LENGTH) {
219
274
  throw new AISecSDKException(
@@ -241,6 +296,11 @@ var Scanner = class {
241
296
  });
242
297
  return res.data;
243
298
  }
299
+ /**
300
+ * Submit content for asynchronous scanning.
301
+ * @param scanObjects - Array of scan objects (1–5 items).
302
+ * @returns Response containing scan IDs for later querying.
303
+ */
244
304
  async asyncScan(scanObjects) {
245
305
  if (scanObjects.length < 1) {
246
306
  throw new AISecSDKException(
@@ -261,6 +321,11 @@ var Scanner = class {
261
321
  });
262
322
  return res.data;
263
323
  }
324
+ /**
325
+ * Query scan results by scan IDs.
326
+ * @param scanIds - Array of scan UUIDs (1–5 items).
327
+ * @returns Array of scan results with status and response data.
328
+ */
264
329
  async queryByScanIds(scanIds) {
265
330
  if (scanIds.length < 1) {
266
331
  throw new AISecSDKException(
@@ -286,6 +351,11 @@ var Scanner = class {
286
351
  });
287
352
  return res.data;
288
353
  }
354
+ /**
355
+ * Query detailed threat reports by report IDs.
356
+ * @param reportIds - Array of report IDs (1–5 items).
357
+ * @returns Array of threat scan reports with detection details.
358
+ */
289
359
  async queryByReportIds(reportIds) {
290
360
  if (reportIds.length < 1) {
291
361
  throw new AISecSDKException(
@@ -397,6 +467,7 @@ var Content = class _Content {
397
467
  set toolEvent(value) {
398
468
  this._toolEvent = value;
399
469
  }
470
+ /** Total byte length of all text content fields. */
400
471
  get length() {
401
472
  let total = 0;
402
473
  if (this._prompt) total += Buffer.byteLength(this._prompt);
@@ -406,6 +477,7 @@ var Content = class _Content {
406
477
  if (this._codeResponse) total += Buffer.byteLength(this._codeResponse);
407
478
  return total;
408
479
  }
480
+ /** Serialize to the API request format. */
409
481
  toJSON() {
410
482
  const obj = {};
411
483
  if (this._prompt !== void 0) obj.prompt = this._prompt;
@@ -416,6 +488,10 @@ var Content = class _Content {
416
488
  if (this._toolEvent !== void 0) obj.tool_event = this._toolEvent;
417
489
  return obj;
418
490
  }
491
+ /**
492
+ * Create a Content instance from an API response object.
493
+ * @param json - Scan request contents inner object.
494
+ */
419
495
  static fromJSON(json) {
420
496
  return new _Content({
421
497
  prompt: json.prompt,
@@ -426,6 +502,10 @@ var Content = class _Content {
426
502
  toolEvent: json.tool_event
427
503
  });
428
504
  }
505
+ /**
506
+ * Load content from a JSON file.
507
+ * @param filePath - Path to JSON file containing scan request contents.
508
+ */
429
509
  static fromJSONFile(filePath) {
430
510
  const raw = readFileSync(filePath, "utf-8");
431
511
  const parsed = JSON.parse(raw);
@@ -433,6 +513,23 @@ var Content = class _Content {
433
513
  }
434
514
  };
435
515
 
516
+ // src/models/enums.ts
517
+ var Verdict = {
518
+ BENIGN: "benign",
519
+ MALICIOUS: "malicious",
520
+ UNKNOWN: "unknown"
521
+ };
522
+ var Action = {
523
+ ALLOW: "allow",
524
+ BLOCK: "block",
525
+ ALERT: "alert"
526
+ };
527
+ var Category = {
528
+ BENIGN: "benign",
529
+ MALICIOUS: "malicious",
530
+ UNKNOWN: "unknown"
531
+ };
532
+
436
533
  // src/models/ai-profile.ts
437
534
  import { z } from "zod";
438
535
  var AiProfileSchema = z.object({
@@ -657,21 +754,540 @@ var ErrorResponseSchema = z14.object({
657
754
  unit: z14.string().optional()
658
755
  }).optional()
659
756
  });
757
+
758
+ // src/models/mgmt-security-profile.ts
759
+ import { z as z15 } from "zod";
760
+ var DlpDataProfileSchema = z15.object({
761
+ profile_name: z15.string(),
762
+ active: z15.boolean().optional()
763
+ }).passthrough();
764
+ var DlpSchema = z15.object({
765
+ dlp_status: z15.string().optional(),
766
+ data_profiles: z15.array(DlpDataProfileSchema).optional()
767
+ }).passthrough();
768
+ var DataLeakDetectionSchema = z15.object({
769
+ "data-leak-detection-status": z15.string().optional(),
770
+ dlp: DlpSchema.optional()
771
+ }).passthrough();
772
+ var AppProtectionSchema = z15.object({
773
+ "prompt-injection": z15.string().optional(),
774
+ "jailbreak-detection": z15.string().optional()
775
+ }).passthrough();
776
+ var ModelProtectionSchema = z15.object({
777
+ "model-denial-of-service": z15.string().optional()
778
+ }).passthrough();
779
+ var AgentProtectionSchema = z15.object({
780
+ "malicious-agent-activity": z15.string().optional()
781
+ }).passthrough();
782
+ var LatencySchema = z15.object({
783
+ status: z15.string().optional(),
784
+ max_latency_ms: z15.number().optional()
785
+ }).passthrough();
786
+ var ModelConfigurationSchema = z15.object({
787
+ latency: LatencySchema.optional()
788
+ }).passthrough();
789
+ var PolicySchema = z15.object({
790
+ "data-leak-detection": DataLeakDetectionSchema.optional(),
791
+ "app-protection": AppProtectionSchema.optional(),
792
+ "model-protection": ModelProtectionSchema.optional(),
793
+ "agent-protection": AgentProtectionSchema.optional(),
794
+ "model-configuration": ModelConfigurationSchema.optional()
795
+ }).passthrough();
796
+ var SecurityProfileSchema = z15.object({
797
+ profile_id: z15.string().optional(),
798
+ profile_name: z15.string(),
799
+ revision: z15.number().optional(),
800
+ active: z15.boolean().optional(),
801
+ policy: PolicySchema.optional(),
802
+ created_by: z15.string().optional(),
803
+ updated_by: z15.string().optional(),
804
+ last_modified_ts: z15.string().optional()
805
+ }).passthrough();
806
+ var CreateSecurityProfileRequestSchema = z15.object({
807
+ profile_id: z15.string().optional(),
808
+ profile_name: z15.string(),
809
+ revision: z15.number().optional(),
810
+ active: z15.boolean().optional(),
811
+ policy: PolicySchema.optional(),
812
+ created_by: z15.string().optional(),
813
+ updated_by: z15.string().optional(),
814
+ last_modified_ts: z15.string().optional()
815
+ }).passthrough();
816
+ var SecurityProfileListResponseSchema = z15.object({
817
+ ai_profiles: z15.array(SecurityProfileSchema),
818
+ next_offset: z15.number().optional()
819
+ }).passthrough();
820
+ var DeleteProfileResponseSchema = z15.object({
821
+ message: z15.string()
822
+ }).passthrough();
823
+ var DeleteProfileConflictSchema = z15.object({
824
+ message: z15.string(),
825
+ payload: z15.array(
826
+ z15.object({
827
+ policy_id: z15.string(),
828
+ policy_name: z15.string(),
829
+ priority: z15.number()
830
+ }).passthrough()
831
+ )
832
+ }).passthrough();
833
+
834
+ // src/models/mgmt-custom-topic.ts
835
+ import { z as z16 } from "zod";
836
+ var CustomTopicSchema = z16.object({
837
+ topic_id: z16.string().optional(),
838
+ topic_name: z16.string(),
839
+ revision: z16.number().optional(),
840
+ active: z16.boolean().optional(),
841
+ description: z16.string().optional(),
842
+ examples: z16.array(z16.string()).optional(),
843
+ created_by: z16.string().optional(),
844
+ updated_by: z16.string().optional(),
845
+ last_modified_ts: z16.string().optional(),
846
+ created_ts: z16.string().optional()
847
+ }).passthrough();
848
+ var CreateCustomTopicRequestSchema = z16.object({
849
+ topic_id: z16.string().optional(),
850
+ topic_name: z16.string(),
851
+ revision: z16.number().optional(),
852
+ active: z16.boolean().optional(),
853
+ description: z16.string().optional(),
854
+ examples: z16.array(z16.string()).optional(),
855
+ created_by: z16.string().optional(),
856
+ updated_by: z16.string().optional(),
857
+ last_modified_ts: z16.string().optional(),
858
+ created_ts: z16.string().optional()
859
+ }).passthrough();
860
+ var CustomTopicListResponseSchema = z16.object({
861
+ custom_topics: z16.array(CustomTopicSchema),
862
+ next_offset: z16.number().optional()
863
+ }).passthrough();
864
+ var DeleteTopicResponseSchema = z16.object({
865
+ message: z16.string()
866
+ }).passthrough();
867
+ var DeleteTopicConflictSchema = z16.object({
868
+ message: z16.string(),
869
+ payload: z16.array(
870
+ z16.object({
871
+ profile_id: z16.string(),
872
+ profile_name: z16.string(),
873
+ revision: z16.number()
874
+ }).passthrough()
875
+ )
876
+ }).passthrough();
877
+
878
+ // src/models/oauth-token.ts
879
+ import { z as z17 } from "zod";
880
+ var OAuthTokenResponseSchema = z17.object({
881
+ access_token: z17.string(),
882
+ token_type: z17.string().optional(),
883
+ expires_in: z17.number(),
884
+ scope: z17.string().optional()
885
+ });
886
+
887
+ // src/management/oauth-client.ts
888
+ var TOKEN_BUFFER_MS = 3e4;
889
+ var OAuthClient = class {
890
+ tokenEndpoint;
891
+ clientId;
892
+ clientSecret;
893
+ tsgId;
894
+ accessToken = null;
895
+ expiresAt = 0;
896
+ pendingFetch = null;
897
+ constructor(opts) {
898
+ this.clientId = opts.clientId;
899
+ this.clientSecret = opts.clientSecret;
900
+ this.tsgId = opts.tsgId;
901
+ this.tokenEndpoint = opts.tokenEndpoint ?? DEFAULT_TOKEN_ENDPOINT;
902
+ }
903
+ /**
904
+ * Get a valid access token, refreshing if needed.
905
+ * @returns Bearer access token string.
906
+ */
907
+ async getToken() {
908
+ if (this.accessToken && Date.now() < this.expiresAt - TOKEN_BUFFER_MS) {
909
+ return this.accessToken;
910
+ }
911
+ if (this.pendingFetch) {
912
+ return this.pendingFetch;
913
+ }
914
+ this.pendingFetch = this.fetchToken().finally(() => {
915
+ this.pendingFetch = null;
916
+ });
917
+ return this.pendingFetch;
918
+ }
919
+ /** Clear the cached token, forcing a fresh fetch on next call. */
920
+ clearToken() {
921
+ this.accessToken = null;
922
+ this.expiresAt = 0;
923
+ }
924
+ async fetchToken() {
925
+ const credentials = btoa(`${this.clientId}:${this.clientSecret}`);
926
+ const body = new URLSearchParams({
927
+ grant_type: "client_credentials",
928
+ scope: `tsg_id:${this.tsgId}`
929
+ });
930
+ let response;
931
+ try {
932
+ response = await fetch(this.tokenEndpoint, {
933
+ method: "POST",
934
+ headers: {
935
+ "Content-Type": "application/x-www-form-urlencoded",
936
+ Authorization: `Basic ${credentials}`
937
+ },
938
+ body: body.toString()
939
+ });
940
+ } catch (err) {
941
+ throw new AISecSDKException(
942
+ `Token request failed: ${err.message}`,
943
+ "AISEC_OAUTH_ERROR" /* OAUTH_ERROR */
944
+ );
945
+ }
946
+ if (!response.ok) {
947
+ let errorMsg;
948
+ try {
949
+ const errorBody = await response.json();
950
+ errorMsg = errorBody.error_description ?? errorBody.error ?? `Token request failed with status ${response.status}`;
951
+ } catch {
952
+ errorMsg = `Token request failed with status ${response.status}`;
953
+ }
954
+ throw new AISecSDKException(errorMsg, "AISEC_OAUTH_ERROR" /* OAUTH_ERROR */);
955
+ }
956
+ const data = OAuthTokenResponseSchema.parse(await response.json());
957
+ this.accessToken = data.access_token;
958
+ this.expiresAt = Date.now() + data.expires_in * 1e3;
959
+ return this.accessToken;
960
+ }
961
+ };
962
+
963
+ // src/management/management-http-client.ts
964
+ async function managementHttpRequest(opts) {
965
+ const { method, baseUrl, path, body, params, oauthClient, numRetries } = opts;
966
+ let hadTokenRefresh = false;
967
+ const response = await executeWithRetry({
968
+ maxRetries: numRetries,
969
+ execute: async () => {
970
+ const token = await oauthClient.getToken();
971
+ const stripped = baseUrl.replace(/\/+$/, "");
972
+ const url = new URL(`${stripped}${path}`);
973
+ if (params) {
974
+ for (const [key, value] of Object.entries(params)) {
975
+ url.searchParams.set(key, value);
976
+ }
977
+ }
978
+ const headers = {
979
+ Authorization: `Bearer ${token}`,
980
+ "User-Agent": USER_AGENT
981
+ };
982
+ let bodyStr;
983
+ if (body !== void 0) {
984
+ headers["Content-Type"] = "application/json";
985
+ bodyStr = JSON.stringify(body);
986
+ }
987
+ return fetch(url.toString(), { method, headers, body: bodyStr });
988
+ },
989
+ onRetryableFailure: async (response2) => {
990
+ if (response2.status === 401 && !hadTokenRefresh) {
991
+ hadTokenRefresh = true;
992
+ oauthClient.clearToken();
993
+ return true;
994
+ }
995
+ return false;
996
+ }
997
+ });
998
+ const text = await response.text();
999
+ const data = text ? JSON.parse(text) : {};
1000
+ return { status: response.status, data };
1001
+ }
1002
+
1003
+ // src/management/profiles.ts
1004
+ var ProfilesClient = class {
1005
+ baseUrl;
1006
+ oauthClient;
1007
+ tsgId;
1008
+ numRetries;
1009
+ constructor(opts) {
1010
+ this.baseUrl = opts.baseUrl;
1011
+ this.oauthClient = opts.oauthClient;
1012
+ this.tsgId = opts.tsgId;
1013
+ this.numRetries = opts.numRetries;
1014
+ }
1015
+ /**
1016
+ * Create a new security profile.
1017
+ * @param request - Profile configuration.
1018
+ * @returns The created security profile.
1019
+ */
1020
+ async create(request) {
1021
+ const res = await managementHttpRequest({
1022
+ method: "POST",
1023
+ baseUrl: this.baseUrl,
1024
+ path: MGMT_PROFILE_PATH,
1025
+ body: request,
1026
+ oauthClient: this.oauthClient,
1027
+ numRetries: this.numRetries
1028
+ });
1029
+ return res.data;
1030
+ }
1031
+ /**
1032
+ * List security profiles for the TSG.
1033
+ * @param opts - Pagination options.
1034
+ * @returns Paginated list of security profiles.
1035
+ */
1036
+ async list(opts) {
1037
+ const params = {
1038
+ offset: String(opts?.offset ?? 0),
1039
+ limit: String(opts?.limit ?? 100)
1040
+ };
1041
+ const res = await managementHttpRequest({
1042
+ method: "GET",
1043
+ baseUrl: this.baseUrl,
1044
+ path: `${MGMT_PROFILES_TSG_PATH}/${this.tsgId}`,
1045
+ params,
1046
+ oauthClient: this.oauthClient,
1047
+ numRetries: this.numRetries
1048
+ });
1049
+ return res.data;
1050
+ }
1051
+ /**
1052
+ * Update an existing security profile.
1053
+ * @param profileId - UUID of the profile to update.
1054
+ * @param request - Updated profile configuration.
1055
+ * @returns The updated security profile.
1056
+ */
1057
+ async update(profileId, request) {
1058
+ if (!isValidUuid(profileId)) {
1059
+ throw new AISecSDKException(
1060
+ `Invalid profile_id: ${profileId}`,
1061
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1062
+ );
1063
+ }
1064
+ const res = await managementHttpRequest({
1065
+ method: "PUT",
1066
+ baseUrl: this.baseUrl,
1067
+ path: `${MGMT_PROFILE_PATH}/uuid/${profileId}`,
1068
+ body: request,
1069
+ oauthClient: this.oauthClient,
1070
+ numRetries: this.numRetries
1071
+ });
1072
+ return res.data;
1073
+ }
1074
+ /**
1075
+ * Delete a security profile.
1076
+ * @param profileId - UUID of the profile to delete.
1077
+ * @returns Deletion confirmation message.
1078
+ */
1079
+ async delete(profileId) {
1080
+ if (!isValidUuid(profileId)) {
1081
+ throw new AISecSDKException(
1082
+ `Invalid profile_id: ${profileId}`,
1083
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1084
+ );
1085
+ }
1086
+ const res = await managementHttpRequest({
1087
+ method: "DELETE",
1088
+ baseUrl: this.baseUrl,
1089
+ path: `${MGMT_PROFILE_PATH}/${profileId}`,
1090
+ oauthClient: this.oauthClient,
1091
+ numRetries: this.numRetries
1092
+ });
1093
+ return res.data;
1094
+ }
1095
+ };
1096
+
1097
+ // src/management/topics.ts
1098
+ var TopicsClient = class {
1099
+ baseUrl;
1100
+ oauthClient;
1101
+ tsgId;
1102
+ numRetries;
1103
+ constructor(opts) {
1104
+ this.baseUrl = opts.baseUrl;
1105
+ this.oauthClient = opts.oauthClient;
1106
+ this.tsgId = opts.tsgId;
1107
+ this.numRetries = opts.numRetries;
1108
+ }
1109
+ /**
1110
+ * Create a new custom topic.
1111
+ * @param request - Topic definition with name, description, and examples.
1112
+ * @returns The created custom topic.
1113
+ */
1114
+ async create(request) {
1115
+ const res = await managementHttpRequest({
1116
+ method: "POST",
1117
+ baseUrl: this.baseUrl,
1118
+ path: MGMT_TOPIC_PATH,
1119
+ body: request,
1120
+ oauthClient: this.oauthClient,
1121
+ numRetries: this.numRetries
1122
+ });
1123
+ return res.data;
1124
+ }
1125
+ /**
1126
+ * List custom topics for the TSG.
1127
+ * @param opts - Pagination options.
1128
+ * @returns Paginated list of custom topics.
1129
+ */
1130
+ async list(opts) {
1131
+ const params = {
1132
+ offset: String(opts?.offset ?? 0),
1133
+ limit: String(opts?.limit ?? 100)
1134
+ };
1135
+ const res = await managementHttpRequest({
1136
+ method: "GET",
1137
+ baseUrl: this.baseUrl,
1138
+ path: `${MGMT_TOPICS_TSG_PATH}/${this.tsgId}`,
1139
+ params,
1140
+ oauthClient: this.oauthClient,
1141
+ numRetries: this.numRetries
1142
+ });
1143
+ return res.data;
1144
+ }
1145
+ /**
1146
+ * Update an existing custom topic.
1147
+ * @param topicId - UUID of the topic to update.
1148
+ * @param request - Updated topic definition.
1149
+ * @returns The updated custom topic.
1150
+ */
1151
+ async update(topicId, request) {
1152
+ if (!isValidUuid(topicId)) {
1153
+ throw new AISecSDKException(
1154
+ `Invalid topic_id: ${topicId}`,
1155
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1156
+ );
1157
+ }
1158
+ const res = await managementHttpRequest({
1159
+ method: "PUT",
1160
+ baseUrl: this.baseUrl,
1161
+ path: `${MGMT_TOPIC_PATH}/uuid/${topicId}`,
1162
+ body: request,
1163
+ oauthClient: this.oauthClient,
1164
+ numRetries: this.numRetries
1165
+ });
1166
+ return res.data;
1167
+ }
1168
+ /**
1169
+ * Delete a custom topic. Fails if topic is referenced by a profile.
1170
+ * @param topicId - UUID of the topic to delete.
1171
+ * @returns Deletion confirmation message.
1172
+ */
1173
+ async delete(topicId) {
1174
+ if (!isValidUuid(topicId)) {
1175
+ throw new AISecSDKException(
1176
+ `Invalid topic_id: ${topicId}`,
1177
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1178
+ );
1179
+ }
1180
+ const res = await managementHttpRequest({
1181
+ method: "DELETE",
1182
+ baseUrl: this.baseUrl,
1183
+ path: `${MGMT_TOPIC_PATH}/${topicId}`,
1184
+ oauthClient: this.oauthClient,
1185
+ numRetries: this.numRetries
1186
+ });
1187
+ return res.data;
1188
+ }
1189
+ /**
1190
+ * Force-delete a custom topic, removing it from any referencing profiles.
1191
+ * @param topicId - UUID of the topic to force-delete.
1192
+ * @returns Deletion confirmation message.
1193
+ */
1194
+ async forceDelete(topicId) {
1195
+ if (!isValidUuid(topicId)) {
1196
+ throw new AISecSDKException(
1197
+ `Invalid topic_id: ${topicId}`,
1198
+ "AISEC_USER_REQUEST_PAYLOAD_ERROR" /* USER_REQUEST_PAYLOAD_ERROR */
1199
+ );
1200
+ }
1201
+ const res = await managementHttpRequest({
1202
+ method: "DELETE",
1203
+ baseUrl: this.baseUrl,
1204
+ path: `${MGMT_TOPIC_FORCE_PATH}/${topicId}`,
1205
+ oauthClient: this.oauthClient,
1206
+ numRetries: this.numRetries
1207
+ });
1208
+ return res.data;
1209
+ }
1210
+ };
1211
+
1212
+ // src/management/client.ts
1213
+ var ManagementClient = class {
1214
+ profiles;
1215
+ topics;
1216
+ constructor(opts = {}) {
1217
+ const clientId = opts.clientId ?? process.env[MGMT_CLIENT_ID];
1218
+ const clientSecret = opts.clientSecret ?? process.env[MGMT_CLIENT_SECRET];
1219
+ const tsgId = opts.tsgId ?? process.env[MGMT_TSG_ID];
1220
+ const apiEndpoint = opts.apiEndpoint ?? process.env[MGMT_ENDPOINT] ?? DEFAULT_MGMT_ENDPOINT;
1221
+ const tokenEndpoint = opts.tokenEndpoint ?? process.env[MGMT_TOKEN_ENDPOINT];
1222
+ const numRetries = Math.min(
1223
+ Math.max(opts.numRetries ?? MAX_NUMBER_OF_RETRIES, 0),
1224
+ MAX_NUMBER_OF_RETRIES
1225
+ );
1226
+ if (!clientId) {
1227
+ throw new AISecSDKException(
1228
+ "clientId is required (option or PANW_MGMT_CLIENT_ID env var)",
1229
+ "AISEC_MISSING_VARIABLE" /* MISSING_VARIABLE */
1230
+ );
1231
+ }
1232
+ if (!clientSecret) {
1233
+ throw new AISecSDKException(
1234
+ "clientSecret is required (option or PANW_MGMT_CLIENT_SECRET env var)",
1235
+ "AISEC_MISSING_VARIABLE" /* MISSING_VARIABLE */
1236
+ );
1237
+ }
1238
+ if (!tsgId) {
1239
+ throw new AISecSDKException(
1240
+ "tsgId is required (option or PANW_MGMT_TSG_ID env var)",
1241
+ "AISEC_MISSING_VARIABLE" /* MISSING_VARIABLE */
1242
+ );
1243
+ }
1244
+ const oauthClient = new OAuthClient({
1245
+ clientId,
1246
+ clientSecret,
1247
+ tsgId,
1248
+ tokenEndpoint
1249
+ });
1250
+ this.profiles = new ProfilesClient({
1251
+ baseUrl: apiEndpoint,
1252
+ oauthClient,
1253
+ tsgId,
1254
+ numRetries
1255
+ });
1256
+ this.topics = new TopicsClient({
1257
+ baseUrl: apiEndpoint,
1258
+ oauthClient,
1259
+ tsgId,
1260
+ numRetries
1261
+ });
1262
+ }
1263
+ };
660
1264
  export {
661
1265
  AISecSDKException,
662
1266
  AI_SEC_API_ENDPOINT,
663
1267
  AI_SEC_API_KEY,
664
1268
  AI_SEC_API_TOKEN,
665
1269
  ASYNC_SCAN_PATH,
1270
+ Action,
666
1271
  AgentMetaSchema,
667
1272
  AiProfileSchema,
668
1273
  AsyncScanObjectSchema,
669
1274
  AsyncScanResponseSchema,
670
1275
  BEARER,
1276
+ Category,
671
1277
  Content,
1278
+ CreateCustomTopicRequestSchema,
1279
+ CreateSecurityProfileRequestSchema,
1280
+ CustomTopicListResponseSchema,
1281
+ CustomTopicSchema,
672
1282
  DEFAULT_ENDPOINT,
1283
+ DEFAULT_MGMT_ENDPOINT,
1284
+ DEFAULT_TOKEN_ENDPOINT,
673
1285
  DSDetailResultSchema,
674
1286
  DSResultMetadataSchema,
1287
+ DeleteProfileConflictSchema,
1288
+ DeleteProfileResponseSchema,
1289
+ DeleteTopicConflictSchema,
1290
+ DeleteTopicResponseSchema,
675
1291
  DetectionServiceResultSchema,
676
1292
  DlpReportSchema,
677
1293
  ErrorResponseSchema,
@@ -695,9 +1311,22 @@ export {
695
1311
  MAX_SESSION_ID_STR_LENGTH,
696
1312
  MAX_TOKEN_LENGTH,
697
1313
  MAX_TRANSACTION_ID_STR_LENGTH,
1314
+ MGMT_CLIENT_ID,
1315
+ MGMT_CLIENT_SECRET,
1316
+ MGMT_ENDPOINT,
1317
+ MGMT_PROFILES_TSG_PATH,
1318
+ MGMT_PROFILE_PATH,
1319
+ MGMT_TOKEN_ENDPOINT,
1320
+ MGMT_TOPICS_TSG_PATH,
1321
+ MGMT_TOPIC_FORCE_PATH,
1322
+ MGMT_TOPIC_PATH,
1323
+ MGMT_TSG_ID,
1324
+ ManagementClient,
698
1325
  MaskedDataSchema,
699
1326
  MetadataSchema,
700
1327
  PAYLOAD_HASH,
1328
+ PolicySchema,
1329
+ ProfilesClient,
701
1330
  PromptDetectedSchema,
702
1331
  PromptDetectionDetailsSchema,
703
1332
  ResponseDetectedSchema,
@@ -712,12 +1341,16 @@ export {
712
1341
  ScanResponseSchema,
713
1342
  ScanSummarySchema,
714
1343
  Scanner,
1344
+ SecurityProfileListResponseSchema,
1345
+ SecurityProfileSchema,
715
1346
  ThreatScanReportSchema,
716
1347
  ToolDetectedSchema,
717
1348
  ToolEventMetadataSchema,
718
1349
  ToolEventSchema,
1350
+ TopicsClient,
719
1351
  USER_AGENT,
720
1352
  UrlfEntrySchema,
1353
+ Verdict,
721
1354
  globalConfiguration,
722
1355
  init
723
1356
  };