Releases: cdot65/prisma-airs-sdk
Release list
v0.12.0
New Features — Dashboard Apps Enumeration
Adds mgmt.dashboard.applicationsOverview(opts?) — the canonical apps-list source backing the SCM AI Security > Runtime > API Applications view (endpoint /v1/mgmt/dashboard/v2/apps/applicationsoverview).
Enumerate from applicationsOverview rather than customerApps.list to see every dashboard bucket: id is the registered customer_appId UUID, name is the scan-payload value. Pair with dashboard.application(...) and dashboard.applicationViolationBreakdown(...) to drill in.
timeInterval?: 1 | 7 | 30 | 60;timeUnit?: 'days' | 'day' | 'hour';limit/offsetpagination. Defaults(30, days).- New exports:
DashboardApplicationsOverviewQuery,DashboardApplicationsOverview,DashboardApplicationsOverviewItem,DashboardApplicationSessionsBucket,DashboardPagination+ schemas.
Full notes: docs/about/release-notes.md (#177)
v0.11.0 — Dashboard client + delete-body fixes
New Features
mgmt.dashboard— per-app token consumption + violations (#175) — addsDashboardClientcovering SCM AI Security > Runtime > API Applications. Newapplication({ appId, appName, timeInterval?, timeUnit? })returnstoken_stats(avg daily + monthly total withK/Mscale),session_stats, attached profiles, cloud, source. NewapplicationViolationBreakdown(...)returns per-detector severity counts +total_violating. 10 detectors observed live; schemas use.passthrough()+.nullable().optional()for forward-compat.
Bug Fixes
- Tolerate plain-string DELETE response bodies on management endpoints (#172) — DELETE on profiles, topics, api-keys, customer-apps returned
application/jsonwith a JSON-encoded plain-string body; SDK now normalizes to{ message: <string> }instead of throwingAISEC_RESPONSE_VALIDATION.customerApps.deletereturn type changes fromCustomerApp→ newCustomerAppDeleteResponse. Closes #164, #165, #166, #167. - Tolerate empty 2xx bodies on red-team mutations (#173) —
targets.delete,customAttacks.deletePrompt,customAttacks.createPropertyNameaccept empty bodies viaallowEmptyBody: true. Return types widened toBaseResponse | undefined. Closes #168.
Tests
- Lock
getPropertyNamesdata shape asstring[](#174) — regression test pins SDK contract; addresses #169 (root cause was CLI-side, not SDK).
Full notes: docs/about/release-notes.md
v0.10.0 — service-name: api default header
New Default — service-name: api Header on Every Request
The SDK now sends service-name: api on every outbound HTTP request. Fixes #162: on tenants whose downstream services require the header, DLP GET /v2/api/data-patterns/{id} and GET /v2/api/data-profiles/{id} returned HTTP 400 for every id. Verified live (2026-05-27): adding service-name: api alone flips both endpoints from 400 → 200.
Surface
src/http/request.ts— header added to default headers map; every request throughrequest()(Runtime, Management, DLP, Red-Team, Model Security) carries it- Regression tests in
test/http/request.spec.ts,test/management/dlp/data-{patterns,profiles}.spec.ts
Not in this release
POST /v2/api/data-profiles and PUT/PATCH on DLP profiles/patterns continue to return 400 "Invalid Request Body" — separate server-side validation issue, independent of service-name. Tracking separately.
Minor (not patch) to flag the new default request header as behavior-affecting for proxies/log scrapers.
Full Changelog
v0.9.2
Bug Fixes — DLP Nested Helper Schemas
Follow-up to v0.9.1. The earlier sweep widened top-level Response fields but missed nested helpers — live api.dlp.paloaltonetworks.com still returned null on inner fields and failed Zod.
Schema changes (all backward compatible)
DataPatternMatchingRulesSchema— 5 fields →.nullish(). Primary fix fordata-patterns listZod failures.ExpressionTreeNodeSchema(recursive viaz.lazy) —operator_type,rule_item,sub_expressions→.nullish(). Primary fix fordata-profiles listZod failures.ExpressionTreeNodeTS interface widened to allownull.DetectionRuleItemSchema— 23 inner fields →.nullish().MultiProfileDataNodeSchema, bothDetectionRulevariants →.nullish().MetadataCriterionSchema,DataPatternDetectionConfigSchema.supported_confidence_levels,DataPatternTagsSchema→.nullish().- 8 nested helpers on
DataFilteringProfile(AppExclusion,URLExclusion,Exclusions,SourceAttributes,DestinationAttributes,ExceptionRuleDTO,DataFilteringRuleDTO,DataFilteringDetails) →.nullish(). DictionaryMetaDataDTOSchema,DictionaryTagsSchema,ResourceModelExtensionSchema→.nullish().
Side-effect (acceptable)
Shared helpers also slightly relax request schemas — SDK user code wouldn't intentionally serialize null on these inner fields. Top-level *RequestSchema files remain strict.
Test coverage
9 new test cases. All 1255 tests pass.
Closes #160.
v0.9.1 — DLP nullable hotfix
Hotfix for #158 — live api.dlp.paloaltonetworks.com responses failing Zod validation because .optional() rejects null and the API emits null (not undefined) for unset fields. Surfaced via prisma-airs-cli PR #78 smoke test.
Bug Fixes — DLP Response Schemas
AuditResponseSchema: all 4 fields →.nullish();created_at/updated_atwidened toz.union([z.string(), z.number()]).nullish()(API has been observed emitting epoch-ms integers).DataFilteringProfileResponseSchema,DataPatternResponseSchema,DataProfileResponseSchema,DictionaryResponseSchema,DlpReportSchema: every top-level.optional()→.nullish().- Request schemas unchanged (API tolerates omit on write; SDK should not emit explicit nulls on PUT/POST).
- Patch request schemas unchanged (
jsonNullable()already handles JSON Merge Patch null semantics).
Test coverage
10 new null-acceptance + numeric-timestamp acceptance tests across the 5 DLP response specs. Full suite: 1246 / 1246 pass.
PR: #159
v0.9.0 — DLP service coverage
New Features — DLP (Data Loss Prevention) Service Coverage
This release adds first-class support for the Palo Alto Networks DLP API under a new client.dlp namespace. Four subclients with full CRUD coverage, sharing the existing PANW_MGMT_* OAuth credentials but routing to a dedicated dlpEndpoint (default https://api.dlp.paloaltonetworks.com).
Subclients
client.dlp.dataFilteringProfiles— full CRUD on/v2/api/data-filtering-profilesclient.dlp.dataPatterns— full CRUD on/v2/api/data-patterns, including JSON Merge Patch (application/merge-patch+json) for partial updatesclient.dlp.dataProfiles— full CRUD on/v2/api/data-profileswith a discriminatedDetectionRuleunion (basic/expression_tree/multi_profile) and a recursiveExpressionTreeNodeclient.dlp.dictionaries— full CRUD on/v2/api/dictionarieswith multipart form-data upload (metadata + keyword file) and 200/204-tolerant PUT semantics
Shared infrastructure
DEFAULT_DLP_ENDPOINT+DLP_*_PATHconstants insrc/constants.ts- New
dlpEndpointconstructor option onManagementClient pageSchema<T>()factory for Spring-stylePage<T>paginated responsesjsonNullable()helper for Merge Patch fields (omit = unchanged,null= clear)AuditResponseSchema(created/updated audit envelope)request()extensions:contentType,formData(multipart bypass),allowEmptyBody(PUT 204)
Models
Zod schemas with .passthrough() for forward-compat, full enum coverage, and nullable handling for Merge Patch.
Tooling
- Preflight script now consumes
specs/dlp/*.yamlvia aDLP_SPEC_WHITELISTand ~24 known-divergence allowlist entries - Live-audit probes round-trip a real DLP API where credentials are present
Examples & docs
- Four runnable examples under
examples/mgmt-dlp-*.ts - Four documentation pages under
docs/services/dlp/with required-field tables, two contrived-but-realistic use-case walkthroughs each, and assertion-style validation
Test coverage
1236 tests / 61 files (up from 970 / 50).
v0.8.3 — Fix: downloadTemplate returns CSV string
Fix: downloadTemplate no longer crashes on CSV responses
RedTeamCustomAttacksClient.downloadTemplate() was routing through the shared request() helper, which unconditionally JSON.parse()s 2xx response bodies. The endpoint returns text/csv, so against real API responses it threw Response body is not valid JSON.
This release makes downloadTemplate() bypass request() (mirroring how uploadPromptsCsv already bypasses for FormData), reads the response as text, and returns string instead of unknown.
Changes
RedTeamCustomAttacksClient.downloadTemplate(): bypassesrequest(), returnsPromise<string>.- Existing test only passed because the shared
mockFetchJSON-stringified the payload, masking the bug. Replaced with a real CSV mock; added a 4xx error-path test.
Closes #77.
v0.8.2 — Fix: empty response bodies parse to {} instead of throwing
Patch release
Fix for a runtime validation error introduced when v0.8.0 turned on Zod `.parse()` for all responses.
What changed
`request()` now hydrates empty 2xx bodies as `{}` instead of `undefined` before schema validation. Endpoints where the AIRS API returns no body for empty results (notably `/v1/mgmt/scanlogs` queries with no logs in the requested time range) now parse cleanly through schemas with all-optional fields.
Schemas with required fields still fail validation on empty bodies — but the error message now points at the specific missing field rather than the cryptic root-level `expected object, received undefined`.
Symptom this fixes
Before:
```
AISEC_RESPONSE_VALIDATION:Response did not match schema: [
{
"code": "invalid_type",
"expected": "object",
"received": "undefined",
"path": [],
"message": "Required"
}
]
```
After: `scanLogs.query()` (and similar all-optional schemas) returns `{}` for empty result sets.
PR
- #137 fix: hydrate empty 2xx body as {}
v0.8.1 — Fix: TopicArray.topic accepts null
Patch release
Fix for a runtime validation regression introduced when v0.8.0 turned on Zod `.parse()` for management responses.
What changed
`TopicArraySchema.topic` now accepts `null` (matches live API behavior). The AIRS API serializes `"topic": null` when an action bucket within a topic guardrail has no topics — common pattern. Without this fix, v0.8.0 rejected any `/v1/mgmt/profiles/tsg` response containing such a bucket with `AISecSDKException(RESPONSE_VALIDATION)`.
Type signature change
`TopicArray.topic: TopicObject[]` → `TopicObject[] | null`. Consumers reading this field need to handle the null case.
Verification
Confirmed against a live profile-list response with 4 affected profiles. Two regression tests added in `test/models/mgmt-security-profile.spec.ts`.
PR
- #135 fix: TopicArraySchema.topic accepts null
v0.8.0 — Unified request pipeline + runtime Zod validation
Highlights
This release is a transport-layer overhaul plus targeted type tightening to match real API behavior. Public-facing constructors and methods are unchanged, but the runtime now validates every response against Zod schemas and four response types have stricter signatures.
What changed
Internal architecture
- Single
request()helper across all four service domains (scan, management, model-security, red-team) - Two pluggable auth adapters:
OAuthAuth(token-based, owns 401/403 free-retry) andApiKeyAuth(HMAC body signing for scan) - New
Listingmodule for canonical pagination/search params - Two legacy HTTP helpers deleted (
http-client.ts,management-http-client.ts)
Public API
- Runtime Zod validation now ON for every response. New
ErrorType.RESPONSE_VALIDATIONthrown on backend response shape mismatches. ScanResponse.timeout/error/errorsnow required (?removed)CustomTopic.revision/description/examplesnow required (response type only — request input unchanged)tool_detected.input_detectedandoutput_detectedreshaped from flag-style to{ detection_entries: ToolDetectionEntry[] }(verified against live API)tool_detected.summaryreshaped from{ verdict, action }to{ detections, threats }(top-levelcategory/actiononScanResponseare unchanged)- New exports:
ToolDetectionFlags,ToolDetectionEntry,ToolDetectionDetails,ListingOptions
Tooling
- OpenAPI schema pre-flight check (
scripts/preflight-schemas.ts) runs in CI on every PR — fails on unacknowledged drift - 36 documented divergences in
scripts/preflight/allowlist.tscovering fields the API returns that the upstream OpenAPI doesn't list
Migration
If you read flags directly off tool_detected.input_detected / output_detected, walk detection_entries instead:
// before
const hadInjection = response.tool_detected?.input_detected?.injection;
// after
const hadInjection = response.tool_detected?.input_detected?.detection_entries?.some(
(e) => e.detections?.injection === true,
);If you read tool_detected.summary.verdict / .action, those moved out — use top-level response.category / response.action.
If you catch AISecSDKException, add a branch for ErrorType.RESPONSE_VALIDATION.
PRs in this release
- #115 unified request pipeline foundations
- #116 gitignore cleanup
- #119 OpenAPI pre-flight (warn-only)
- #121 management migration
- #123 model-security + Listing
- #125 red-team migration
- #127 scan migration + delete legacy HTTP helpers
- #130 fix(scan): reshape IODetected/ScanSummary
- #131 fix(mgmt): tighten CustomTopic required fields
- #132 preflight allowlist + flip CI gate to strict
Test count
983 → 1037 (+54)
Pre-flight drift
81 raw findings → 0 unacknowledged (36 explicitly allowlisted)