@cdot65/prisma-airs-cli 5.10.0 → 5.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{chunk-XQOICLSH.js → chunk-37SN57XQ.js} +3 -0
- package/dist/cli/index.js +199 -17
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
- **SCM dashboard and sessions** — `runtime dashboard` and `runtime sessions` expose application activity, daily trends, checked pagination and explicit session-to-content drill-down. Legacy `scan-logs query` is **broken/under refactor** and exits with migration guidance; see the [session reference](https://cdot65.github.io/prisma-airs-cli/cli/runtime/sessions/)
|
|
21
21
|
- **Guardrail Optimization** — atomic CLI commands (`create`, `apply`, `eval`, `revert`) for custom topic guardrails, designed for autonomous agent loops (see [`AGENTS.md`](AGENTS.md))
|
|
22
22
|
- **AI Red Teaming** — adversarial scanning with static, dynamic, and custom prompt set attack modes
|
|
23
|
-
- **[AI Gateway](https://cdot65.github.io/prisma-airs-cli/cli/aigateway/resources/)** — workspaces, configs, guardrails, providers, API keys, integrations, MCP, deployments, plugins, audit logs, and telemetry
|
|
23
|
+
- **[AI Gateway](https://cdot65.github.io/prisma-airs-cli/cli/aigateway/resources/)** — workspaces (scope-first provisioning), IAM scopes, configs, guardrails, providers, API keys, integrations, MCP, deployments, plugins, audit logs, and telemetry
|
|
24
24
|
- **Model Security** — ML model supply chain scanning with security groups, rules, and violation tracking
|
|
25
25
|
- **Unified automation output** — resource reads support `pretty`, `table`, `markdown`, `csv`, `json`, and `yaml`, with pipe-safe stdout; environment deliverables use HTML or Markdown
|
|
26
26
|
- **Complete pagination** — consistent `--limit`, `--offset`, and `--all` traversal with a configurable safety cap
|
|
@@ -2268,6 +2268,8 @@ var ConfigSchema = z.object({
|
|
|
2268
2268
|
aiGwDataEndpoint: z.string().optional(),
|
|
2269
2269
|
aiGwAdminEndpoint: z.string().optional(),
|
|
2270
2270
|
aiGwTokenEndpoint: z.string().optional(),
|
|
2271
|
+
// SCM IAM (workspace scopes); creds shared with mgmt*
|
|
2272
|
+
iamEndpoint: z.string().optional(),
|
|
2271
2273
|
// Runtime inference has separate key authentication, never management OAuth.
|
|
2272
2274
|
aiGwInferenceEndpoint: z.string().optional(),
|
|
2273
2275
|
aiGwInferenceApiKey: z.string().optional(),
|
|
@@ -2488,6 +2490,7 @@ function fromEnv() {
|
|
|
2488
2490
|
aiGwDataEndpoint: env.PANW_AI_GW_DATA_ENDPOINT,
|
|
2489
2491
|
aiGwAdminEndpoint: env.PANW_AI_GW_ADMIN_ENDPOINT,
|
|
2490
2492
|
aiGwTokenEndpoint: env.PANW_AI_GW_TOKEN_ENDPOINT,
|
|
2493
|
+
iamEndpoint: env.PANW_IAM_ENDPOINT,
|
|
2491
2494
|
aiGwInferenceEndpoint: env.PANW_AI_GW_INFERENCE_ENDPOINT,
|
|
2492
2495
|
aiGwInferenceApiKey: env.PANW_AI_GW_INFERENCE_API_KEY,
|
|
2493
2496
|
aiGwInferenceModel: env.PANW_AI_GW_INFERENCE_MODEL,
|
package/dist/cli/index.js
CHANGED
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
validateTopic,
|
|
41
41
|
writeBackupFile,
|
|
42
42
|
writeReportFile
|
|
43
|
-
} from "../chunk-
|
|
43
|
+
} from "../chunk-37SN57XQ.js";
|
|
44
44
|
|
|
45
45
|
// src/cli/index.ts
|
|
46
46
|
import "dotenv/config";
|
|
@@ -126,6 +126,7 @@ function aiGatewayClientOptions(config) {
|
|
|
126
126
|
tsgId: config.mgmtTsgId,
|
|
127
127
|
dataEndpoint: config.aiGwDataEndpoint,
|
|
128
128
|
adminEndpoint: config.aiGwAdminEndpoint,
|
|
129
|
+
iamEndpoint: config.iamEndpoint,
|
|
129
130
|
tokenEndpoint: config.aiGwTokenEndpoint ?? config.mgmtTokenEndpoint
|
|
130
131
|
};
|
|
131
132
|
}
|
|
@@ -707,6 +708,62 @@ function renderWorkspaceDetail(workspace, format = "pretty") {
|
|
|
707
708
|
}
|
|
708
709
|
console.log();
|
|
709
710
|
}
|
|
711
|
+
function scopeBindings(scope) {
|
|
712
|
+
return scope.resources.map((r) => `${r.resourceType}:${r.resourceId}`).join(", ");
|
|
713
|
+
}
|
|
714
|
+
function renderScopeList(scopes, format = "pretty") {
|
|
715
|
+
if (scopes.length === 0 && (format === "json" || format === "yaml")) {
|
|
716
|
+
console.log(format === "json" ? "[]" : yamlDump([]).trimEnd());
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
if (scopes.length === 0) {
|
|
720
|
+
ui.emptyList("IAM scopes");
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
if (format !== "pretty") {
|
|
724
|
+
const rows = scopes.map((s) => ({
|
|
725
|
+
name: s.name,
|
|
726
|
+
description: s.description,
|
|
727
|
+
resources: scopeBindings(s),
|
|
728
|
+
tsgId: s.tsgId
|
|
729
|
+
}));
|
|
730
|
+
console.log(
|
|
731
|
+
formatOutput(
|
|
732
|
+
rows,
|
|
733
|
+
[
|
|
734
|
+
{ key: "name", label: "Name" },
|
|
735
|
+
{ key: "description", label: "Description" },
|
|
736
|
+
{ key: "resources", label: "Bound resources" },
|
|
737
|
+
{ key: "tsgId", label: "TSG" }
|
|
738
|
+
],
|
|
739
|
+
format
|
|
740
|
+
)
|
|
741
|
+
);
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
ui.section("IAM Scopes:");
|
|
745
|
+
for (const s of scopes) {
|
|
746
|
+
const bindings = scopeBindings(s);
|
|
747
|
+
console.log(` ${s.name} ${bindings ? chalk4.dim(bindings) : chalk4.yellow("unbound")}`);
|
|
748
|
+
if (s.description) console.log(` ${chalk4.dim(s.description)}`);
|
|
749
|
+
console.log();
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
function renderScopeDetail(scope, format = "pretty") {
|
|
753
|
+
if (format !== "pretty") {
|
|
754
|
+
console.log(format === "json" ? JSON.stringify(scope, null, 2) : yamlDump(scope));
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
ui.section("IAM Scope:");
|
|
758
|
+
ui.keyValue([
|
|
759
|
+
["Name", scope.name],
|
|
760
|
+
["Description", scope.description || chalk4.dim("(none)")],
|
|
761
|
+
["TSG", scope.tsgId],
|
|
762
|
+
["ID", scope.id],
|
|
763
|
+
["Bound resources", scopeBindings(scope) || chalk4.yellow("none \u2014 unbound")]
|
|
764
|
+
]);
|
|
765
|
+
console.log();
|
|
766
|
+
}
|
|
710
767
|
function renderCostReport(report, format = "pretty") {
|
|
711
768
|
if (format !== "pretty") {
|
|
712
769
|
emitDetail(
|
|
@@ -3251,6 +3308,18 @@ function normalizeWorkspaceDetail(raw) {
|
|
|
3251
3308
|
settings: raw.settings
|
|
3252
3309
|
};
|
|
3253
3310
|
}
|
|
3311
|
+
function normalizeScope(raw) {
|
|
3312
|
+
return {
|
|
3313
|
+
name: raw.name,
|
|
3314
|
+
description: raw.description,
|
|
3315
|
+
resources: raw.resources.map((r) => ({
|
|
3316
|
+
resourceType: r.resource_type,
|
|
3317
|
+
resourceId: r.resource_id
|
|
3318
|
+
})),
|
|
3319
|
+
tsgId: raw.tsg_id,
|
|
3320
|
+
id: raw.id
|
|
3321
|
+
};
|
|
3322
|
+
}
|
|
3254
3323
|
function aiGatewayGrantHint(err) {
|
|
3255
3324
|
const status = err?.status ?? err?.statusCode;
|
|
3256
3325
|
if (status !== 403) return void 0;
|
|
@@ -3294,18 +3363,38 @@ var SdkAiGatewayService = class {
|
|
|
3294
3363
|
}
|
|
3295
3364
|
}
|
|
3296
3365
|
async createWorkspace(request) {
|
|
3297
|
-
const body = {
|
|
3298
|
-
|
|
3299
|
-
scope_name: request.scopeName
|
|
3300
|
-
};
|
|
3366
|
+
const body = { name: request.name };
|
|
3367
|
+
if (request.scopeName !== void 0) body.scope_name = request.scopeName;
|
|
3301
3368
|
if (request.description !== void 0) body.description = request.description;
|
|
3302
3369
|
if (request.icon !== void 0) body.icon = request.icon;
|
|
3303
3370
|
if (request.defaults !== void 0) body.defaults = request.defaults;
|
|
3304
3371
|
if (request.users !== void 0) body.users = request.users;
|
|
3305
3372
|
if (request.usageLimits !== void 0) body.usage_limits = request.usageLimits;
|
|
3306
3373
|
if (request.rateLimits !== void 0) body.rate_limits = request.rateLimits;
|
|
3307
|
-
const
|
|
3308
|
-
|
|
3374
|
+
const result = await this.client.workspaces.provision(
|
|
3375
|
+
body,
|
|
3376
|
+
request.existingScope ? { existingScope: true } : {}
|
|
3377
|
+
);
|
|
3378
|
+
const created = result.workspace;
|
|
3379
|
+
const workspace = await this.refetchAfterWrite(created.id, created);
|
|
3380
|
+
return { workspace, scope: normalizeScope(result.scope), scopeCreated: result.scopeCreated };
|
|
3381
|
+
}
|
|
3382
|
+
async listScopes() {
|
|
3383
|
+
const response = await this.client.iamScopes.list();
|
|
3384
|
+
return response.items.map(normalizeScope);
|
|
3385
|
+
}
|
|
3386
|
+
async getScope(name) {
|
|
3387
|
+
return normalizeScope(await this.client.iamScopes.get(name));
|
|
3388
|
+
}
|
|
3389
|
+
async createScope(request) {
|
|
3390
|
+
return normalizeScope(await this.client.iamScopes.create(request));
|
|
3391
|
+
}
|
|
3392
|
+
async bindScope(name, workspaceRef) {
|
|
3393
|
+
const slug = await this.resolveWorkspaceRef(workspaceRef, ["admin"], true);
|
|
3394
|
+
return normalizeScope(await this.client.iamScopes.bindWorkspace(name, slug));
|
|
3395
|
+
}
|
|
3396
|
+
async deleteScope(name) {
|
|
3397
|
+
await this.client.iamScopes.delete(name);
|
|
3309
3398
|
}
|
|
3310
3399
|
async updateWorkspace(workspaceRef, request) {
|
|
3311
3400
|
const ref = await this.resolveWorkspaceRef(workspaceRef, ["admin"]);
|
|
@@ -5414,44 +5503,60 @@ function registerAiGatewayCommand(program) {
|
|
|
5414
5503
|
failWithGrantHint(err);
|
|
5415
5504
|
}
|
|
5416
5505
|
});
|
|
5417
|
-
workspace.command("create").description("Create a workspace (admin plane)").requiredOption("--name <name>", "Display name").
|
|
5506
|
+
const workspaceCreate = workspace.command("create").description("Create a workspace: IAM scope \u2192 workspace \u2192 bind scope (admin plane)").requiredOption("--name <name>", "Display name").option(
|
|
5418
5507
|
"--scope-name <scope>",
|
|
5419
|
-
"
|
|
5508
|
+
"IAM scope to create and bind (e.g. ws_production_bx7qw0). Default: ws_<name>_<suffix>"
|
|
5509
|
+
).option(
|
|
5510
|
+
"--existing-scope",
|
|
5511
|
+
"Bind an IAM scope that already exists instead of creating one (requires --scope-name)"
|
|
5420
5512
|
).option("--description <text>", "Workspace description").option("--icon <icon>", "Workspace icon").option("--metadata <json>", "Sugar for defaults.metadata (flat string map)").option("--defaults <json>", "Workspace defaults object").option("--users <ids>", "Comma-separated user ids to seed the workspace with").option("--usage-limits <json>", "Usage-limit policies \u2014 a JSON ARRAY of policy objects").option("--rate-limits <json>", "Rate-limit policies \u2014 a JSON ARRAY of policy objects").option("--output <format>", "Output format: pretty, json, yaml", "pretty").addHelpText(
|
|
5421
5513
|
"after",
|
|
5422
5514
|
examples(
|
|
5515
|
+
'airs aigateway workspaces create --name truffles --description "Online recipe generation application"',
|
|
5423
5516
|
"airs aigateway workspaces create --name Production --scope-name ws_production_bx7qw0",
|
|
5424
|
-
|
|
5517
|
+
"airs aigateway workspaces create --name Staging --scope-name ws_staging_q1x8mz --existing-scope",
|
|
5518
|
+
`airs aigateway workspaces create --name Production --metadata '{"env":"production"}' --rate-limits '[{"type":"requests","unit":"rpm","value":100}]'`
|
|
5425
5519
|
)
|
|
5426
5520
|
).action(async (opts) => {
|
|
5427
5521
|
try {
|
|
5428
|
-
const fmt = opts
|
|
5522
|
+
const fmt = await resolveOutput(workspaceCreate, opts, {
|
|
5523
|
+
allowed: ["pretty", "json", "yaml"]
|
|
5524
|
+
});
|
|
5429
5525
|
if (fmt === "pretty") renderAiGatewayHeader();
|
|
5430
|
-
if (
|
|
5526
|
+
if (opts.existingScope && !opts.scopeName) {
|
|
5527
|
+
throw new CliUsageError("--existing-scope requires --scope-name");
|
|
5528
|
+
}
|
|
5529
|
+
if (opts.scopeName && scopeNameLooksUnrelated(opts.name, opts.scopeName)) {
|
|
5431
5530
|
ui.warn(
|
|
5432
|
-
`--scope-name '${opts.scopeName}' shares no token with --name '${opts.name}'.
|
|
5531
|
+
`--scope-name '${opts.scopeName}' shares no token with --name '${opts.name}'. Operators find workspaces by scope in SCM Access Management; an unrelated name is easy to lose.`
|
|
5433
5532
|
);
|
|
5434
5533
|
}
|
|
5435
5534
|
const service = await createService();
|
|
5436
|
-
const workspace2 = await service.createWorkspace({
|
|
5535
|
+
const { workspace: workspace2, scope, scopeCreated } = await service.createWorkspace({
|
|
5437
5536
|
...buildWorkspaceWriteRequest(opts),
|
|
5438
5537
|
name: opts.name,
|
|
5439
|
-
scopeName: opts.scopeName
|
|
5538
|
+
...opts.scopeName !== void 0 ? { scopeName: opts.scopeName } : {},
|
|
5539
|
+
...opts.existingScope ? { existingScope: true } : {}
|
|
5440
5540
|
});
|
|
5441
5541
|
ui.success(`Workspace created: ${workspace2.id}`);
|
|
5542
|
+
ui.status(
|
|
5543
|
+
`IAM scope ${scope.name} ${scopeCreated ? "created and " : ""}bound to workspace ${workspace2.slug}. Grant that scope to the service accounts that should reach the workspace on the data plane.`
|
|
5544
|
+
);
|
|
5442
5545
|
renderWorkspaceDetail(workspace2, fmt);
|
|
5443
5546
|
} catch (err) {
|
|
5444
5547
|
failWithGrantHint(err);
|
|
5445
5548
|
}
|
|
5446
5549
|
});
|
|
5447
|
-
workspace.command("update <ref>").description("Update a workspace (admin plane, partial patch)").option("--name <name>", "New display name").option("--description <text>", "New description").option("--icon <icon>", "New icon").option("--metadata <json>", "Sugar for defaults.metadata (flat string map)").option("--defaults <json>", "Workspace defaults object").option("--usage-limits <json>", "Usage-limit policies \u2014 a JSON ARRAY of policy objects").option("--rate-limits <json>", "Rate-limit policies \u2014 a JSON ARRAY of policy objects").option("--output <format>", "Output format: pretty, json, yaml", "pretty").addHelpText(
|
|
5550
|
+
const workspaceUpdate = workspace.command("update <ref>").description("Update a workspace (admin plane, partial patch)").option("--name <name>", "New display name").option("--description <text>", "New description").option("--icon <icon>", "New icon").option("--metadata <json>", "Sugar for defaults.metadata (flat string map)").option("--defaults <json>", "Workspace defaults object").option("--usage-limits <json>", "Usage-limit policies \u2014 a JSON ARRAY of policy objects").option("--rate-limits <json>", "Rate-limit policies \u2014 a JSON ARRAY of policy objects").option("--output <format>", "Output format: pretty, json, yaml", "pretty").addHelpText(
|
|
5448
5551
|
"after",
|
|
5449
5552
|
examples(
|
|
5450
5553
|
`airs aigateway workspaces update ws-produc-985697 --description 'Production workloads, us-east'`
|
|
5451
5554
|
)
|
|
5452
5555
|
).action(async (ref, opts) => {
|
|
5453
5556
|
try {
|
|
5454
|
-
const fmt = opts
|
|
5557
|
+
const fmt = await resolveOutput(workspaceUpdate, opts, {
|
|
5558
|
+
allowed: ["pretty", "json", "yaml"]
|
|
5559
|
+
});
|
|
5455
5560
|
if (fmt === "pretty") renderAiGatewayHeader();
|
|
5456
5561
|
const request = buildWorkspaceWriteRequest(opts);
|
|
5457
5562
|
if (Object.keys(request).length === 0) {
|
|
@@ -5492,6 +5597,83 @@ function registerAiGatewayCommand(program) {
|
|
|
5492
5597
|
};
|
|
5493
5598
|
workspace.command("archive <ref>").description("Archive a workspace (soft delete \u2014 there is no hard delete)").option("--force", "Skip confirmation prompt").addHelpText("after", examples("airs aigateway workspaces archive ws-produc-985697 --force")).action((ref, opts) => archiveWorkspace(ref, opts, false));
|
|
5494
5599
|
workspace.command("delete <ref>", { hidden: true }).description("Deprecated compatibility command for archive").option("--force", "Skip confirmation prompt").action((ref, opts) => archiveWorkspace(ref, opts, true));
|
|
5600
|
+
const scopes = aigateway.command("scopes").description("Manage SCM IAM scopes \u2014 the objects a workspace scope_name points at (/iam/v1)").action(() => scopes.outputHelp());
|
|
5601
|
+
const scopeList = scopes.command("list").description("List every IAM scope in the tenant (unbound scopes have no resources)").option("--output <format>", "Output format: pretty, table, markdown, csv, json, yaml").addHelpText(
|
|
5602
|
+
"after",
|
|
5603
|
+
examples("airs aigateway scopes list", "airs aigateway scopes list --output json")
|
|
5604
|
+
).action(async (opts) => {
|
|
5605
|
+
try {
|
|
5606
|
+
const fmt = await resolveOutput(scopeList, opts);
|
|
5607
|
+
if (fmt === "pretty") renderAiGatewayHeader();
|
|
5608
|
+
const service = await createService();
|
|
5609
|
+
renderScopeList(await service.listScopes(), fmt);
|
|
5610
|
+
} catch (err) {
|
|
5611
|
+
failWithGrantHint(err);
|
|
5612
|
+
}
|
|
5613
|
+
});
|
|
5614
|
+
const scopeGet = scopes.command("get <name>").description("Get one IAM scope by name").option("--output <format>", "Output format: pretty, table, markdown, csv, json, yaml").addHelpText("after", examples("airs aigateway scopes get ws_production_bx7qw0")).action(async (name, opts) => {
|
|
5615
|
+
try {
|
|
5616
|
+
const fmt = await resolveOutput(scopeGet, opts);
|
|
5617
|
+
if (fmt === "pretty") renderAiGatewayHeader();
|
|
5618
|
+
const service = await createService();
|
|
5619
|
+
renderScopeDetail(await service.getScope(name), fmt);
|
|
5620
|
+
} catch (err) {
|
|
5621
|
+
failWithGrantHint(err);
|
|
5622
|
+
}
|
|
5623
|
+
});
|
|
5624
|
+
const scopeCreate = scopes.command("create").description("Create an unbound IAM scope (step 1 of provisioning, on its own)").requiredOption("--name <name>", "Scope name, e.g. ws_production_bx7qw0").option("--description <text>", "Scope description").option("--output <format>", "Output format: pretty, json, yaml", "pretty").addHelpText(
|
|
5625
|
+
"after",
|
|
5626
|
+
examples(
|
|
5627
|
+
`airs aigateway scopes create --name ws_production_bx7qw0 --description 'All production applications'`
|
|
5628
|
+
)
|
|
5629
|
+
).action(async (opts) => {
|
|
5630
|
+
try {
|
|
5631
|
+
const fmt = await resolveOutput(scopeCreate, opts, { allowed: ["pretty", "json", "yaml"] });
|
|
5632
|
+
if (fmt === "pretty") renderAiGatewayHeader();
|
|
5633
|
+
const service = await createService();
|
|
5634
|
+
const scope = await service.createScope({
|
|
5635
|
+
name: opts.name,
|
|
5636
|
+
...opts.description !== void 0 ? { description: opts.description } : {}
|
|
5637
|
+
});
|
|
5638
|
+
ui.success(`IAM scope created: ${scope.name}`);
|
|
5639
|
+
ui.status(
|
|
5640
|
+
"The scope is not bound to anything yet \u2014 `workspaces create --existing-scope` or `scopes bind` finishes the job."
|
|
5641
|
+
);
|
|
5642
|
+
renderScopeDetail(scope, fmt);
|
|
5643
|
+
} catch (err) {
|
|
5644
|
+
failWithGrantHint(err);
|
|
5645
|
+
}
|
|
5646
|
+
});
|
|
5647
|
+
const scopeBind = scopes.command("bind <name>").description("Bind a workspace to an existing IAM scope (step 3 of provisioning, on its own)").requiredOption("--workspace <ref>", "Workspace slug, UUID, or unique display name").option("--output <format>", "Output format: pretty, json, yaml", "pretty").addHelpText(
|
|
5648
|
+
"after",
|
|
5649
|
+
examples("airs aigateway scopes bind ws_production_bx7qw0 --workspace ws-produc-985697")
|
|
5650
|
+
).action(async (name, opts) => {
|
|
5651
|
+
try {
|
|
5652
|
+
const fmt = await resolveOutput(scopeBind, opts, { allowed: ["pretty", "json", "yaml"] });
|
|
5653
|
+
if (fmt === "pretty") renderAiGatewayHeader();
|
|
5654
|
+
const service = await createService();
|
|
5655
|
+
const scope = await service.bindScope(name, opts.workspace);
|
|
5656
|
+
ui.success(`IAM scope ${scope.name} now binds ${scope.resources.length} resource(s)`);
|
|
5657
|
+
renderScopeDetail(scope, fmt);
|
|
5658
|
+
} catch (err) {
|
|
5659
|
+
failWithGrantHint(err);
|
|
5660
|
+
}
|
|
5661
|
+
});
|
|
5662
|
+
scopes.command("delete <name>").alias("rm").description("Delete an IAM scope by name (not live-verified upstream; the API may decline)").option("--force", "Skip confirmation prompt").addHelpText("after", examples("airs aigateway scopes delete ws_truffles_ggolfu --force")).action(async (name, opts) => {
|
|
5663
|
+
try {
|
|
5664
|
+
renderAiGatewayHeader();
|
|
5665
|
+
await confirmOrAbort(
|
|
5666
|
+
`Delete IAM scope ${name}? Workspaces bound to it lose their data-plane grant.`,
|
|
5667
|
+
Boolean(opts.force),
|
|
5668
|
+
{ action: `delete IAM scope ${name}` }
|
|
5669
|
+
);
|
|
5670
|
+
const service = await createService();
|
|
5671
|
+
await service.deleteScope(name);
|
|
5672
|
+
ui.success(`IAM scope deleted: ${name}`);
|
|
5673
|
+
} catch (err) {
|
|
5674
|
+
failWithGrantHint(err);
|
|
5675
|
+
}
|
|
5676
|
+
});
|
|
5495
5677
|
const telemetry = aigateway.command("telemetry").description("AI Gateway runtime telemetry (data plane)").action(() => telemetry.outputHelp());
|
|
5496
5678
|
registerAiGatewayTelemetryReads(telemetry);
|
|
5497
5679
|
const cost = addChartFilterOptions(
|
package/dist/index.d.ts
CHANGED
|
@@ -1666,6 +1666,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1666
1666
|
aiGwDataEndpoint: z.ZodOptional<z.ZodString>;
|
|
1667
1667
|
aiGwAdminEndpoint: z.ZodOptional<z.ZodString>;
|
|
1668
1668
|
aiGwTokenEndpoint: z.ZodOptional<z.ZodString>;
|
|
1669
|
+
iamEndpoint: z.ZodOptional<z.ZodString>;
|
|
1669
1670
|
aiGwInferenceEndpoint: z.ZodOptional<z.ZodString>;
|
|
1670
1671
|
aiGwInferenceApiKey: z.ZodOptional<z.ZodString>;
|
|
1671
1672
|
aiGwInferenceModel: z.ZodOptional<z.ZodString>;
|
|
@@ -1700,6 +1701,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1700
1701
|
aiGwDataEndpoint?: string | undefined;
|
|
1701
1702
|
aiGwAdminEndpoint?: string | undefined;
|
|
1702
1703
|
aiGwTokenEndpoint?: string | undefined;
|
|
1704
|
+
iamEndpoint?: string | undefined;
|
|
1703
1705
|
aiGwInferenceEndpoint?: string | undefined;
|
|
1704
1706
|
aiGwInferenceApiKey?: string | undefined;
|
|
1705
1707
|
aiGwInferenceModel?: string | undefined;
|
|
@@ -1730,6 +1732,7 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1730
1732
|
aiGwDataEndpoint?: string | undefined;
|
|
1731
1733
|
aiGwAdminEndpoint?: string | undefined;
|
|
1732
1734
|
aiGwTokenEndpoint?: string | undefined;
|
|
1735
|
+
iamEndpoint?: string | undefined;
|
|
1733
1736
|
aiGwInferenceEndpoint?: string | undefined;
|
|
1734
1737
|
aiGwInferenceApiKey?: string | undefined;
|
|
1735
1738
|
aiGwInferenceModel?: 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": "5.
|
|
4
|
+
"version": "5.11.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",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
},
|
|
60
60
|
"license": "MIT",
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@cdot65/prisma-airs-sdk": "0.
|
|
62
|
+
"@cdot65/prisma-airs-sdk": "0.31.0",
|
|
63
63
|
"@inquirer/prompts": "^8.3.0",
|
|
64
64
|
"chalk": "^5.6.2",
|
|
65
65
|
"commander": "^14.0.3",
|