Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ef102fb
chore: bump @cdot65/prisma-airs-sdk to ^0.9.0
cdot65 May 23, 2026
7b50e93
feat(config): add PANW_DLP_ENDPOINT to schema and loader
cdot65 May 23, 2026
5fdc8a6
refactor(airs): add getOrCreateManagementClient factory for shared to…
cdot65 May 23, 2026
d2ace0d
feat(cli): add buildMergePatch util for --set/--clear DLP patches
cdot65 May 23, 2026
94a1281
feat(cli): add parseBody util for --body/--body-file DLP inputs
cdot65 May 23, 2026
1e0c699
feat(airs/dlp): add service-interface types and barrel
cdot65 May 23, 2026
32b5f32
feat(airs/dlp): add SdkDataFilteringProfilesService
cdot65 May 23, 2026
aab923c
feat(airs/dlp): add SdkDataPatternsService (full CRUD + soft-delete)
cdot65 May 23, 2026
a567b6f
feat(airs/dlp): add SdkDataProfilesService (no delete; patch profile_…
cdot65 May 23, 2026
4c430fb
feat(airs/dlp): add SdkDictionariesService (multipart, 200/204 replac…
cdot65 May 23, 2026
361aa37
feat(cli/renderer): add dlpFilteringProfiles + dlpPatterns renderer n…
cdot65 May 23, 2026
6daa387
feat(cli/renderer): add dlpProfiles + dlpDictionaries (incl. 204 fall…
cdot65 May 23, 2026
91f8249
feat(cli): add dlp filtering-profiles list/get/replace commands
cdot65 May 23, 2026
dde73e5
feat(cli): add dlp patterns CRUD commands
cdot65 May 23, 2026
d341eff
feat(cli): add dlp profiles commands + stub delete UX sugar
cdot65 May 23, 2026
88bf849
feat(cli): add dlp dictionaries commands (multipart + 204 fallback)
cdot65 May 23, 2026
7375c0b
feat(cli): register dlp command group on runtime
cdot65 May 23, 2026
7137f64
chore: add changeset for dlp commands
cdot65 May 23, 2026
895def2
docs(readme): document dlp commands and PANW_DLP_ENDPOINT
cdot65 May 23, 2026
05082b9
docs: document dlp namespace in CLAUDE.md and MIGRATION.md
cdot65 May 23, 2026
c9b75a9
docs(mkdocs): add dlp command walkthroughs + nav
cdot65 May 23, 2026
48748e7
fix(cli/dlp): correct string-escape in patch help text
cdot65 May 23, 2026
51f1d41
chore(deps): bump @cdot65/prisma-airs-sdk to ^0.9.1
cdot65 May 23, 2026
d436682
chore: bump @cdot65/prisma-airs-sdk to ^0.9.2
cdot65 May 23, 2026
434f6e3
docs(runtime/dlp): refresh wire-output snippets from live tenant
cdot65 May 23, 2026
2a493dc
Merge remote-tracking branch 'origin/main' into cdot65/dlp-commands
cdot65 May 23, 2026
9734b2f
chore(changeset): rename 0020-sdk-092-bump → 0021 (avoid collision wi…
cdot65 May 23, 2026
f6879af
chore(changeset): remove stale 0004 + 0006 entries from accidental sweep
cdot65 May 23, 2026
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
9 changes: 9 additions & 0 deletions .changeset/0019-dlp-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@cdot65/prisma-airs-cli": minor
---

Add `airs runtime dlp` command group for full DLP CRUD across four subclients:
filtering-profiles (list/get/replace), patterns (full CRUD + soft-delete),
profiles (no delete — patch profile_status), and dictionaries (multipart upload,
200/204 replace handling). Bumps `@cdot65/prisma-airs-sdk` pin to `^0.9.0`.
Adds optional `PANW_DLP_ENDPOINT` env var (defaults to SDK built-in).
5 changes: 5 additions & 0 deletions .changeset/0021-sdk-092-bump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cdot65/prisma-airs-cli": patch
---

Bump @cdot65/prisma-airs-sdk to ^0.9.2 (DLP nested helper nullable sweep — unblocks `runtime dlp patterns list` and `runtime dlp profiles list` against live tenants).
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@ SCAN_CONCURRENCY=5
# MEMORY_ENABLED=true
# MEMORY_DIR=~/.prisma-airs/memory
# MAX_MEMORY_CHARS=3000

# ── DLP API (Data Loss Prevention) ────────────────────────────────
# Optional — overrides default DLP base URL (api.dlp.paloaltonetworks.com)
PANW_DLP_ENDPOINT=
13 changes: 13 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ src/
│ │ ├── backup.ts # Backup core logic (backupTargets, createRedTeamService, toBackupData)
│ │ ├── restore.ts # Restore core logic (restoreTargets, prepareTargetPayload)
│ │ ├── profiles-cleanup.ts # Delete old profile revisions, keep only latest per name
│ │ ├── dlp/ # DLP CLI commands (4 subgroups + aggregator + shared patch/parseBody utils)
│ │ ├── runtime.ts # Runtime scanning + config management + topics + audit (profiles)
│ │ ├── audit.ts # Profile-level multi-topic evaluation (registered under runtime profiles)
│ │ ├── redteam.ts # Red team operations (scan, targets CRUD + backup/restore, prompt-sets CRUD, prompts CRUD, properties)
Expand Down Expand Up @@ -99,6 +100,7 @@ src/
│ ├── runtime.ts # SdkRuntimeService — sync scan, async bulk scan, poll results, CSV export
│ ├── management.ts # SdkManagementService — topic CRUD, profile CRUD, API keys, customer apps, deployment/DLP profiles, scan logs
│ ├── promptsets.ts # SdkPromptSetService — custom prompt set CRUD via RedTeamClient
│ ├── dlp/ # DLP namespace: filtering-profiles, patterns, profiles, dictionaries SDK service wrappers
│ ├── redteam.ts # SdkRedTeamService — red team scan CRUD, polling, reports
│ ├── modelsecurity.ts # SdkModelSecurityService — security groups, rules, scans, labels
│ └── types.ts # ScanResult, ScanService, ManagementService, PromptSetService, RedTeamService, ModelSecurityService
Expand Down Expand Up @@ -192,6 +194,10 @@ These four commands compose into an autoresearch-style optimization loop: an age
- `airs runtime deployment-profiles {list}` — deployment profile listing (`--unactivated` filter)
- `airs runtime dlp-profiles {list}` — DLP profile listing
- `airs runtime scan-logs {query}` — scan log querying (`--interval`/`--unit hours`/`--filter`)
- `airs runtime dlp filtering-profiles {list, get, replace}` — read + full-replace
- `airs runtime dlp patterns {list, create, get, replace, patch, delete}` — full CRUD + soft-delete
- `airs runtime dlp profiles {list, create, get, replace, patch, delete*}` — no real delete; patch profile_status
- `airs runtime dlp dictionaries {list, create, get, replace, patch, delete}` — multipart upload, 200/204 fallback

### Red Team (`src/airs/redteam.ts`, `src/airs/promptsets.ts`)
- `SdkRedTeamService` wraps `RedTeamClient` for scan CRUD, polling, reports, **target CRUD**
Expand All @@ -205,6 +211,13 @@ These four commands compose into an autoresearch-style optimization loop: an age
- CLI top-level commands: `scan`, `status <jobId>`, `report <jobId>`, `list`, `abort <jobId>`, `categories`
- CLI subcommand groups: `targets {list,get,create,update,delete,probe,profile,update-profile,validate-auth,metadata,init,templates,backup,restore}`, `prompt-sets {list,get,create,update,archive,download,upload}`, `prompts {list,get,add,update,delete}`, `properties {list,create,values,add-value}`

### DLP (`src/airs/dlp/`)
- **Shape**: thin SDK wrappers; one class per resource (filtering-profiles, patterns, profiles, dictionaries); all instantiate via `getOrCreateManagementClient()` for shared OAuth token cache
- **Merge-patch semantics**: JSON Merge Patch (RFC 7396) — `null` clears, omit means leave alone. CLI `patch` exposes `--set k=v` (with coercion of `"true"/"false"/numbers/JSON literals`; quote `'"5"'` to force string) and `--clear key` (sets `null`). `--body-file` for nested fields; mutually exclusive with `--set/--clear`.
- **Multipart upload (dictionaries only)**: `create`/`replace` send `json` (metadata) + `file` parts. `--file` required; metadata via flags OR `--metadata-file`.
- **200/204 replace fallback (dictionaries only)**: PUT can return 200 with body or 204 No Content (region-dependent). On 204 the SDK re-GETs; if that fails, the service returns `{ kind: 'fallback', id }` sentinel and the CLI prints `(state not echoed by region)`.
- **No-DELETE for filtering-profiles and profiles**: API doesn't expose DELETE for either. `profiles delete <id>` is a stub that prints the patch idiom and exits 2. `filtering-profiles` has no `delete` subcommand at all.

### Model Security (`src/airs/modelsecurity.ts`)
- `SdkModelSecurityService` wraps `ModelSecurityClient` for security groups, rules, scans, labels, PyPI auth
- snake_case (SDK) → camelCase normalization via `normalizeGroup()`, `normalizeRule()`, etc.
Expand Down
10 changes: 10 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Migration: daystrom → prisma-airs-cli

## SDK 0.9.0 (2026-05-23)

The CLI now exposes `airs runtime dlp` (filtering-profiles, patterns, profiles,
dictionaries) backed by the SDK's new `client.dlp.*` namespace. Existing
`airs runtime dlp-profiles list` (read-only DLP profile references) is unchanged.

New optional env: `PANW_DLP_ENDPOINT` (defaults to api.dlp.paloaltonetworks.com).

## daystrom → prisma-airs-cli Rename

This project was renamed from `daystrom` to `prisma-airs-cli` in March 2026.

## What Changed
Expand Down
132 changes: 132 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,105 @@ airs redteam report <job-id>
airs model-security scans create --config scan-config.json
```

## DLP Management

Manage Data Loss Prevention resources across filtering profiles, patterns, profiles, and dictionaries. Each subclient supports different operation patterns:

- **Filtering profiles** — read-only + full replace
- **Patterns** — full CRUD with soft-delete via patch
- **Profiles** — full CRUD, use patch to soft-delete via `profile_status: "deleted"`
- **Dictionaries** — create, replace, and delete with multipart upload support

### Filtering Profiles

Read-only access with full-replace support:

```bash
# List all filtering profiles
airs runtime dlp filtering-profiles list --output json

# Get a specific filtering profile
airs runtime dlp filtering-profiles get <id>

# Replace a filtering profile
airs runtime dlp filtering-profiles replace <id> --body-file profile.json
```

### Patterns

Full CRUD with soft-delete:

```bash
# List patterns
airs runtime dlp patterns list

# Get a pattern
airs runtime dlp patterns get <id>

# Create a new pattern
airs runtime dlp patterns create --body-file pattern.json

# Update a pattern
airs runtime dlp patterns patch <id> --set name="Updated Name"

# Soft-delete a pattern
airs runtime dlp patterns patch <id> --set is_archived=true

# Hard delete a pattern
airs runtime dlp patterns delete <id>
```

### Profiles

Full CRUD with soft-delete via `profile_status`:

```bash
# List profiles
airs runtime dlp profiles list

# Get a profile
airs runtime dlp profiles get <id>

# Create a profile
airs runtime dlp profiles create --body-file profile.json

# Update a profile
airs runtime dlp profiles patch <id> --body-file - <<EOF
{ "name": "my-profile", "profile_type": "advanced", "description": "Updated description" }
EOF

# Soft-delete (set profile_status to "deleted")
airs runtime dlp profiles patch <id> --body-file - <<EOF
{ "profile_status": "deleted" }
EOF

# Hard delete a profile
airs runtime dlp profiles delete <id>
```

### Dictionaries

Multipart upload support for dictionary management:

```bash
# List dictionaries
airs runtime dlp dictionaries list

# Get a dictionary
airs runtime dlp dictionaries get <id>

# Create a dictionary with file upload
airs runtime dlp dictionaries create --name "Allowlist" --category Confidential \
--region us --file keywords.txt

# Replace a dictionary (multipart upload)
airs runtime dlp dictionaries replace <id> --file keywords.txt --name "Allowlist" \
--category Confidential --region us

# Delete a dictionary
airs runtime dlp dictionaries delete <id>
```

## Commands

| Command | Description |
Expand All @@ -63,6 +162,28 @@ airs model-security scans create --config scan-config.json
| `runtime deployment-profiles` | Deployment profile listing |
| `runtime dlp-profiles` | DLP profile listing |
| `runtime scan-logs` | Scan log querying |
| `runtime dlp filtering-profiles` | DLP filtering profile listing and full-replace |
| `runtime dlp filtering-profiles list` | List all filtering profiles |
| `runtime dlp filtering-profiles get` | Get a specific filtering profile |
| `runtime dlp filtering-profiles replace` | Replace a filtering profile |
| `runtime dlp patterns` | DLP pattern CRUD with soft-delete |
| `runtime dlp patterns list` | List all patterns |
| `runtime dlp patterns get` | Get a specific pattern |
| `runtime dlp patterns create` | Create a new pattern |
| `runtime dlp patterns patch` | Update a pattern or soft-delete via `is_archived` |
| `runtime dlp patterns delete` | Hard delete a pattern |
| `runtime dlp profiles` | DLP profile CRUD with soft-delete via `profile_status` |
| `runtime dlp profiles list` | List all profiles |
| `runtime dlp profiles get` | Get a specific profile |
| `runtime dlp profiles create` | Create a new profile |
| `runtime dlp profiles patch` | Update a profile or soft-delete via `profile_status: "deleted"` |
| `runtime dlp profiles delete` | Hard delete a profile |
| `runtime dlp dictionaries` | DLP dictionary management with multipart upload |
| `runtime dlp dictionaries list` | List all dictionaries |
| `runtime dlp dictionaries get` | Get a specific dictionary |
| `runtime dlp dictionaries create` | Create a dictionary with file upload |
| `runtime dlp dictionaries replace` | Replace a dictionary with multipart upload |
| `runtime dlp dictionaries delete` | Delete a dictionary |
| `redteam scan` | Adversarial scanning (STATIC, DYNAMIC, CUSTOM) |
| `redteam targets` | Red team target CRUD |
| `redteam prompt-sets` | Custom prompt set management |
Expand All @@ -76,6 +197,17 @@ airs model-security scans create --config scan-config.json

Credentials are configured via environment variables or `~/.prisma-airs/config.json`. See [`.env.example`](.env.example) for the full list.

| Variable | Purpose | Required |
|----------|---------|----------|
| `PANW_AI_SEC_API_KEY` | Scanning API authentication | Yes (for scanning) |
| `PANW_MGMT_CLIENT_ID` | Management API OAuth client ID | Yes (for management) |
| `PANW_MGMT_CLIENT_SECRET` | Management API OAuth client secret | Yes (for management) |
| `PANW_MGMT_TSG_ID` | Management API tenant security group ID | Yes (for management) |
| `PANW_DLP_ENDPOINT` | DLP API base URL override | No (defaults to `api.dlp.paloaltonetworks.com`) |
| `LLM_PROVIDER` | LLM provider for profile audits | Yes (for audit) |
| `ANTHROPIC_API_KEY` | Claude API key | Yes (if using Claude) |
| `GOOGLE_API_KEY` | Google Gemini API key | Yes (if using Gemini) |

**Required for scanning:** `PANW_AI_SEC_API_KEY`
**Required for management:** `PANW_MGMT_CLIENT_ID`, `PANW_MGMT_CLIENT_SECRET`, `PANW_MGMT_TSG_ID`
**Required for profile audits:** one LLM provider key + scanning + management credentials
Expand Down
Loading
Loading