Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/0185-docs-accuracy-salvage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cdot65/prisma-airs-sdk': patch
---

Docs accuracy fixes: correct the Scan API auth description (API key HMAC and/or bearer token; lowercase `x-pan-token` / `x-payload-hash` headers), fill in the OAuth `TOKEN_ENDPOINT` defaults and EU regional endpoint overrides, replace the fictional `ListingOptions` (`sort`/`filters`) with the real per-service pagination contracts (Management `offset/limit`, Model Security / Red Team `skip/limit/search`, DLP `page/size`), fix Red Team examples (enum casing, `updatePrompt` uses `prompt` not `content`, valid `goal_type`), flesh out the developer vocabulary, and add a Runnable Examples guide page.
34 changes: 22 additions & 12 deletions docs-site/docs/developer/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@ The SDK covers four service domains. They split across exactly two authenticatio

| Domain | Entry point | Auth | Base URL constant |
| -------------- | --------------------- | ------------------------- | ------------------------------- |
| Scan API | `init()` + `Scanner` | API key (HMAC-SHA256) | `DEFAULT_ENDPOINT` |
| Scan API | `init()` + `Scanner` | API key HMAC and/or bearer token | `DEFAULT_ENDPOINT` |
| Management API | `ManagementClient` | OAuth2 client_credentials | `DEFAULT_MGMT_ENDPOINT` (+ DLP) |
| Model Security | `ModelSecurityClient` | OAuth2 client_credentials | `DEFAULT_MODEL_SEC_*_ENDPOINT` |
| Red Team | `RedTeamClient` | OAuth2 client_credentials | `DEFAULT_RED_TEAM_*_ENDPOINT` |

Only the scan service uses the API key. Everything else (management CRUD, DLP, model security, red
teaming) authenticates with OAuth2 client_credentials. The Management client additionally talks to a
separate DLP base URL (`DEFAULT_DLP_ENDPOINT`) reusing the same OAuth credentials.
Only the scan service uses `init()` and the `ApiKeyAuth` adapter. It accepts an API key, a
pre-obtained bearer token, or both; it does not fetch OAuth2 tokens. Everything else (management
CRUD, DLP, model security, red teaming) authenticates with OAuth2 client_credentials. The Management
client additionally talks to a separate DLP base URL (`DEFAULT_DLP_ENDPOINT`) reusing the same OAuth
credentials.

All endpoint paths, base URLs, content/batch limits, header names, and retry config live in one
place: [`src/constants.ts`](../reference/api/index.md). A few load-bearing values:
place:
[`src/constants.ts`](https://github.com/cdot65/prisma-airs-sdk/blob/main/src/constants.ts). A few
load-bearing values:

```ts
export const MAX_NUMBER_OF_RETRIES = 5;
Expand Down Expand Up @@ -160,10 +164,20 @@ snapshot (`hasToken`, `isValid`, `isExpired`, `isExpiringSoon`, `expiresInMs`, `
optional `onTokenRefresh` callback fires after each successful refresh. Token-fetch failures throw
`AISecSDKException` with `ErrorType.OAUTH_ERROR`.

## Shared listing / pagination
## Listing and pagination shapes

Every list endpoint across the OAuth domains accepts the same base options, defined once in
`src/listing.ts`:
The OAuth domains do not all expose the same pagination contract. The SDK keeps the wire shape close
to each service while sharing helpers where the APIs match:

- **Management API** resource lists use `offset` / `limit` and return fields such as `next_offset`
where the endpoint supports it. `ProfilesClient.list()` defaults to `offset: 0` and `limit: 100`.
- **Model Security and Red Team** list endpoints use `skip` / `limit` / `search`, defined in
`src/listing.ts` and serialized by the internal `serializeListing()` helper. Sub-clients extend
that base shape with endpoint-specific filters such as Red Team `status` or `target_type`.
- **DLP** list endpoints use Spring-style `page` / `size` options and return `Page<T>` envelopes
from `src/models/dlp-page.ts`.

The shared Model Security / Red Team base options are:

```ts
interface ListingOptions {
Expand All @@ -173,10 +187,6 @@ interface ListingOptions {
}
```

The internal `serializeListing()` helper turns those into a string-keyed params record. Sub-clients
extend `ListingOptions` with endpoint-specific filters and merge their own params on top of the
serialized base — keeping pagination semantics uniform while allowing per-endpoint filtering.

## Validation strategy: Zod with `.passthrough()`

Validation happens at three distinct boundaries:
Expand Down
37 changes: 31 additions & 6 deletions docs-site/docs/developer/vocabulary.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,25 @@ Use these terms exactly when discussing the SDK's design — they have specific

## Domain concepts

Reserved for AIRS domain terms (Scan, Profile, Topic, Job, Target, Custom Attack, EULA, Instance, …). Fill in as decisions crystallize.
- **Scan** — an AI Runtime Security inspection request. Synchronous scans return a verdict inline;
asynchronous scans return a receipt and are later queried by scan or report ID.
- **Security profile** — the named or UUID-addressed AIRS runtime policy referenced by scan calls
and managed through `ManagementClient.profiles`.
- **Custom topic** — a reusable topic guardrails definition managed through `ManagementClient.topics`.
- **DLP resource** — data filtering profiles, data patterns, data profiles, and dictionaries exposed
under `ManagementClient.dlp`.
- **Model Security scan** — a Model Security data-plane scan for model artifacts and related
evaluation, file, label, and violation data.
- **Security group / rule instance** — Model Security management objects that configure which
platform-provided security rules run. Security rules themselves are read-only in the SDK.
- **Target** — an AI Red Teaming management-plane object describing how the service calls the model,
API, or application under test.
- **Scan job** — an AI Red Teaming data-plane run against a target. Jobs are asynchronous and expose
statuses such as `QUEUED`, `RUNNING`, `COMPLETED`, and `FAILED`.
- **Custom attack** — a Red Teaming prompt-set workflow for user-authored prompts, CSV uploads, and
prompt properties.
- **EULA / instance** — Red Teaming management-plane resources for tenant EULA acceptance and
instance, device, and registry-credential management.

## Architecture concepts

Expand All @@ -24,7 +42,10 @@ interface RequestSpec<TResponse> {
path: string;
params?: Record<string, string | string[]>;
body?: unknown;
responseSchema?: z.ZodType<TResponse>;
contentType?: string;
formData?: FormData;
responseSchema?: z.ZodType<TResponse, any, any>;
allowEmptyBody?: boolean;
numRetries: number;
auth: AuthAdapter;
}
Expand Down Expand Up @@ -65,18 +86,22 @@ A build-time script that diffs Zod schemas in `src/models/` against the authorit

### Listing

A paginated, filterable list request. Owns serialization of `skip` / `limit` / `search` / `sort` / typed filter args into URL search params, and exposes an `async *` iterator (`listAll`) that walks pages. Each list endpoint declares its filter shape; the module owns wire-format mechanics. Replaces ad-hoc per-client query-string building.
A paginated, filterable list request for Model Security and Red Team endpoints that use
`skip` / `limit` / `search`. The internal `serializeListing()` helper turns those fields into URL
search params; individual sub-clients add endpoint-specific filters such as `status`,
`target_type`, or `job_type`.

```ts
interface ListingOptions<TFilters = {}> {
interface ListingOptions {
skip?: number;
limit?: number;
search?: string;
sort?: { field: string; order: 'asc' | 'desc' };
filters?: TFilters;
}
```

Management API list endpoints use `offset` / `limit`, and DLP endpoints use `page` / `size`, so the
SDK documents those separately instead of forcing every service through `ListingOptions`.

### RESPONSE_VALIDATION error

`AISecSDKException` with `ErrorType.RESPONSE_VALIDATION` is thrown when the backend returns a 2xx with a body that does not match the declared response schema (or is not valid JSON). Distinct from `SERVER_SIDE_ERROR` (5xx) and `CLIENT_SIDE_ERROR` (4xx) so callers can route SDK-bug-vs-backend-bug-vs-client-bug differently.
8 changes: 6 additions & 2 deletions docs-site/docs/getting-started/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Falls back to `PANW_MGMT_*` variables if service-specific ones are not set.
| `PANW_MODEL_SEC_TSG_ID` | Falls back to MGMT | — |
| `PANW_MODEL_SEC_DATA_ENDPOINT` | No | `https://api.sase.paloaltonetworks.com/aims/data` |
| `PANW_MODEL_SEC_MGMT_ENDPOINT` | No | `https://api.sase.paloaltonetworks.com/aims/mgmt` |
| `PANW_MODEL_SEC_TOKEN_ENDPOINT` | Falls back to MGMT | |
| `PANW_MODEL_SEC_TOKEN_ENDPOINT` | Falls back to MGMT | `https://auth.apps.paloaltonetworks.com/oauth2/access_token` |

## Red Team API

Expand All @@ -78,7 +78,7 @@ Falls back to `PANW_MGMT_*` variables if service-specific ones are not set.
| `PANW_RED_TEAM_DATA_ENDPOINT` | No | `https://api.sase.paloaltonetworks.com/ai-red-teaming/data-plane` |
| `PANW_RED_TEAM_MGMT_ENDPOINT` | No | `https://api.sase.paloaltonetworks.com/ai-red-teaming/mgmt-plane` |
| `PANW_RED_TEAM_NETWORK_BROKER_ENDPOINT` | No | `https://api.sase.paloaltonetworks.com/ai-red-teaming/data-plane/network-broker` |
| `PANW_RED_TEAM_TOKEN_ENDPOINT` | Falls back to MGMT | |
| `PANW_RED_TEAM_TOKEN_ENDPOINT` | Falls back to MGMT | `https://auth.apps.paloaltonetworks.com/oauth2/access_token` |

## Regional Endpoints

Expand All @@ -92,6 +92,10 @@ export PANW_AI_SEC_API_ENDPOINT=https://service-sg.api.aisecurity.paloaltonetwor

# EU
export PANW_MGMT_ENDPOINT=https://api.eu.sase.paloaltonetworks.com/aisec
export PANW_MODEL_SEC_DATA_ENDPOINT=https://api.eu.sase.paloaltonetworks.com/aims/data
export PANW_MODEL_SEC_MGMT_ENDPOINT=https://api.eu.sase.paloaltonetworks.com/aims/mgmt
export PANW_RED_TEAM_DATA_ENDPOINT=https://api.eu.sase.paloaltonetworks.com/ai-red-teaming/data-plane
export PANW_RED_TEAM_MGMT_ENDPOINT=https://api.eu.sase.paloaltonetworks.com/ai-red-teaming/mgmt-plane

# UK
export PANW_MGMT_ENDPOINT=https://api.uk.sase.paloaltonetworks.com/aisec
Expand Down
4 changes: 2 additions & 2 deletions docs-site/docs/getting-started/environment-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ All fall back to the corresponding `PANW_MGMT_*` variable if not set.
| `PANW_MODEL_SEC_TSG_ID` | `PANW_MGMT_TSG_ID` | — | Tenant Service Group ID |
| `PANW_MODEL_SEC_DATA_ENDPOINT` | — | `https://api.sase.paloaltonetworks.com/aims/data` | Data plane base URL |
| `PANW_MODEL_SEC_MGMT_ENDPOINT` | — | `https://api.sase.paloaltonetworks.com/aims/mgmt` | Management plane base URL |
| `PANW_MODEL_SEC_TOKEN_ENDPOINT` | `PANW_MGMT_TOKEN_ENDPOINT` | | OAuth2 token endpoint |
| `PANW_MODEL_SEC_TOKEN_ENDPOINT` | `PANW_MGMT_TOKEN_ENDPOINT` | `https://auth.apps.paloaltonetworks.com/oauth2/access_token` | OAuth2 token endpoint |

## Red Team API

Expand All @@ -52,7 +52,7 @@ All fall back to the corresponding `PANW_MGMT_*` variable if not set.
| `PANW_RED_TEAM_DATA_ENDPOINT` | — | `https://api.sase.paloaltonetworks.com/ai-red-teaming/data-plane` | Data plane base URL |
| `PANW_RED_TEAM_MGMT_ENDPOINT` | — | `https://api.sase.paloaltonetworks.com/ai-red-teaming/mgmt-plane` | Management plane base URL |
| `PANW_RED_TEAM_NETWORK_BROKER_ENDPOINT` | — | `https://api.sase.paloaltonetworks.com/ai-red-teaming/data-plane/network-broker` | Network broker base URL |
| `PANW_RED_TEAM_TOKEN_ENDPOINT` | `PANW_MGMT_TOKEN_ENDPOINT` | | OAuth2 token endpoint |
| `PANW_RED_TEAM_TOKEN_ENDPOINT` | `PANW_MGMT_TOKEN_ENDPOINT` | `https://auth.apps.paloaltonetworks.com/oauth2/access_token` | OAuth2 token endpoint |

## Debugging

Expand Down
117 changes: 117 additions & 0 deletions docs-site/docs/guides/examples.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
id: examples
title: Runnable Examples
description: How to run the SDK example scripts for scanning, management, DLP, model security, red teaming, and validation workflows.
---

# Runnable Examples

The repository includes runnable TypeScript examples in `docs-site/examples/`. They exercise the
same public SDK APIs documented in the guides and can be run with `tsx` from the repository root.

## Setup

Install dependencies and create an environment file:

```bash
npm install
cp .env.example .env
```

Fill in the credentials required by the workflow you want to run:

- Scan examples require `PANW_AI_SEC_API_KEY` or `PANW_AI_SEC_API_TOKEN`, plus
`PANW_AI_SEC_PROFILE_NAME`.
- Management examples require `PANW_MGMT_CLIENT_ID`, `PANW_MGMT_CLIENT_SECRET`, and
`PANW_MGMT_TSG_ID`.
- Model Security and Red Team examples can use their service-specific `PANW_MODEL_SEC_*` /
`PANW_RED_TEAM_*` credentials or fall back to `PANW_MGMT_*`.
- Validation scripts marked as mock-backed do not require live AIRS credentials.

Run examples with:

```bash
npx tsx --env-file=.env docs-site/examples/<script>.ts
```

## AI Runtime Security Scan Examples

| Script | What it demonstrates |
| --- | --- |
| `basic-scan.ts` | Calls `init()`, creates `Content`, and runs `Scanner.syncScan()` with metadata. |
| `async-scan.ts` | Submits a batch with `Scanner.asyncScan()`; batch size is capped at five items. |
| `query-results.ts` | Fetches async scan results and threat reports by scan ID or report ID. |

```bash
npx tsx --env-file=.env docs-site/examples/basic-scan.ts
npx tsx --env-file=.env docs-site/examples/async-scan.ts
npx tsx --env-file=.env docs-site/examples/query-results.ts
```

## Management and DLP Examples

| Script | What it demonstrates |
| --- | --- |
| `mgmt-auth.ts` | Constructs `ManagementClient` and triggers OAuth on the first API call. |
| `mgmt-profiles.ts` | Lists and works with AI security profiles. |
| `mgmt-topics.ts` | Uses custom topic management APIs. |
| `mgmt-dashboard.ts` | Reads runtime dashboard application and violation data. |
| `mgmt-dlp-data-filtering-profiles.ts` | Lists and replaces DLP data filtering profiles. |
| `mgmt-dlp-data-patterns.ts` | Creates, reads, replaces, patches, and deletes DLP data patterns. |
| `mgmt-dlp-data-profiles.ts` | Works with DLP data profiles and merge-patch updates. |
| `mgmt-dlp-dictionaries.ts` | Uses DLP dictionary CRUD with multipart keyword uploads. |

```bash
npx tsx --env-file=.env docs-site/examples/mgmt-auth.ts
npx tsx --env-file=.env docs-site/examples/mgmt-profiles.ts
npx tsx --env-file=.env docs-site/examples/mgmt-topics.ts
npx tsx --env-file=.env docs-site/examples/mgmt-dashboard.ts
npx tsx --env-file=.env docs-site/examples/mgmt-dlp-data-filtering-profiles.ts
npx tsx --env-file=.env docs-site/examples/mgmt-dlp-data-patterns.ts
npx tsx --env-file=.env docs-site/examples/mgmt-dlp-data-profiles.ts
npx tsx --env-file=.env docs-site/examples/mgmt-dlp-dictionaries.ts
```

## Model Security and Red Team Examples

| Script | What it demonstrates |
| --- | --- |
| `model-security-scans.ts` | Lists Model Security scans and related data-plane resources. |
| `red-team-scans.ts` | Lists Red Team scan jobs and categories. |
| `red-team-targets.ts` | Works with Red Team targets and profile helpers. |
| `red-team-network-broker.ts` | Lists, reads, and inspects stats for Red Team network broker channels. |

```bash
npx tsx --env-file=.env docs-site/examples/model-security-scans.ts
npx tsx --env-file=.env docs-site/examples/red-team-scans.ts
npx tsx --env-file=.env docs-site/examples/red-team-targets.ts
npx tsx --env-file=.env docs-site/examples/red-team-network-broker.ts
```

## Mock-Backed Validation Scripts

These scripts spin up local mock servers or validate schemas directly, so they can run without live
tenant credentials:

| Script | What it validates |
| --- | --- |
| `profiles-get-validation.ts` | `profiles.get()` and `profiles.getByName()` behavior. |
| `profiles-crud-validation.ts` | Management profile create, list, get, update, delete, and force-delete flow. |
| `oauth-lifecycle-validation.ts` | OAuth token caching, refresh, 401/403 retry, callbacks, and token state inspection. |
| `red-team-mgmt-validation.ts` | Red Team target and custom attack schemas plus management-plane workflows. |

```bash
npx tsx --env-file=.env docs-site/examples/profiles-get-validation.ts
npx tsx --env-file=.env docs-site/examples/profiles-crud-validation.ts
npx tsx --env-file=.env docs-site/examples/oauth-lifecycle-validation.ts
npx tsx --env-file=.env docs-site/examples/red-team-mgmt-validation.ts
```

## Related Pages

- [Quick Start](../getting-started/quick-start)
- [Environment Variables](../getting-started/environment-variables)
- [Scan API](./scan-api)
- [Management API](./management-api)
- [Model Security API](./model-security-api)
- [Red Team API](./red-team-api)
17 changes: 9 additions & 8 deletions docs-site/docs/guides/red-team-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ const { data } = await client.scans.list();

// With filters
const filtered = await client.scans.list({
status: 'completed',
job_type: 'static',
status: 'COMPLETED',
job_type: 'STATIC',
target_id: 'target-uuid',
skip: 0,
limit: 10,
Expand Down Expand Up @@ -200,8 +200,8 @@ const categories = await client.scans.getCategories();
```ts
// List attacks for a static scan
const attacks = await client.reports.listAttacks('job-uuid', {
status: 'failed',
severity: 'high',
status: 'FAILED',
severity: 'HIGH',
category: 'prompt-injection',
skip: 0,
limit: 20,
Expand Down Expand Up @@ -237,7 +237,8 @@ const policy = await client.reports.getDynamicRuntimePolicy('job-uuid');

// List goals
const goals = await client.reports.listGoals('job-uuid', {
goal_type: 'security',
goal_type: 'AGENT',
status: 'SUCCESSFUL',
skip: 0,
limit: 10,
});
Expand Down Expand Up @@ -325,8 +326,8 @@ const target = await client.targets.create(

```ts
const targets = await client.targets.list({
target_type: 'api',
status: 'active',
target_type: 'API',
status: 'ACTIVE',
skip: 0,
limit: 10,
});
Expand Down Expand Up @@ -570,7 +571,7 @@ const p = await client.customAttacks.getPrompt('prompt-set-uuid', 'prompt-uuid')

// Update a prompt
const updated = await client.customAttacks.updatePrompt('prompt-set-uuid', 'prompt-uuid', {
content: 'Updated prompt text',
prompt: 'Updated prompt text',
});

// Delete a prompt
Expand Down
13 changes: 8 additions & 5 deletions docs-site/docs/guides/scan-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ The Scan API only _references_ a profile by name or ID — it never creates one.
:::
## Authentication

Two auth methods (mutually exclusive):
The Scan API is the only AIRS service in this SDK that does **not** use the OAuth2
`client_credentials` flow. Configure it with an API key, a pre-obtained bearer token, or both:

1. **API Key** — sets `X-Pan-Token` header + HMAC-SHA256 `X-Payload-Hash`
2. **Bearer Token** — sets `Authorization: Bearer <token>` header
1. **API key** — sets the `x-pan-token` header and, when the request has a body, an
HMAC-SHA256 `x-payload-hash` header.
2. **Bearer token** — sets the `Authorization: Bearer <token>` header.

The Scan API uses **API key auth only** — it does _not_ use the OAuth2 flow that the Management, Model Security, and Red Team APIs require.
`init()` requires at least one of `apiKey` or `apiToken`. If you provide both, the request carries
both the bearer token and the API-key HMAC headers.

## Initialization

Expand All @@ -45,7 +48,7 @@ init();
// Or explicit
init({
apiKey: 'your-api-key',
// apiToken: 'your-bearer-token', // alternative
// apiToken: 'your-bearer-token', // optional; can also be used without apiKey
// apiEndpoint: 'https://custom.endpoint.com', // optional
// numRetries: 3, // 0-5, default 5
});
Expand Down
Loading
Loading