Skip to content

Commit 235dfd4

Browse files
authored
Merge pull request #1398 from jroberts2600/feature/panw-prisma-airs-enhancements
feat: add support for linked Security Profile API keys, additional tests
2 parents 7921321 + 0e2aa41 commit 235dfd4

File tree

3 files changed

+319
-18
lines changed

3 files changed

+319
-18
lines changed

plugins/panw-prisma-airs/intercept.ts

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import { getText, post } from '../utils';
99
const AIRS_URL =
1010
'https://service.api.aisecurity.paloaltonetworks.com/v1/scan/sync/request';
1111

12-
const fetchAIRS = async (payload: any, apiKey: string, timeout?: number) => {
12+
const fetchAIRS = async (payload: any, apiKey: string) => {
1313
const opts = {
1414
headers: { 'x-pan-token': apiKey },
1515
};
16-
return post(AIRS_URL, payload, opts, timeout);
16+
return post(AIRS_URL, payload, opts);
1717
};
1818

1919
export const handler: PluginHandler = async (
@@ -26,31 +26,54 @@ export const handler: PluginHandler = async (
2626
process.env.AIRS_API_KEY ||
2727
'';
2828

29+
// Return verdict=true with error for missing credentials to allow traffic flow
30+
if (!apiKey || apiKey.trim() === '') {
31+
return {
32+
verdict: true,
33+
error:
34+
'AIRS_API_KEY is required but not configured. Please add your API key in the Portkey dashboard.',
35+
data: null,
36+
};
37+
}
38+
2939
let verdict = true;
3040
let data: any = null;
3141
let error: any = null;
3242

3343
try {
3444
const text = getText(ctx, hook); // prompt or response
3545

36-
const payload = {
37-
tr_id:
38-
typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
39-
? crypto.randomUUID()
40-
: Math.random().toString(36).substring(2) + Date.now().toString(36),
41-
ai_profile: {
42-
profile_name: params.profile_name ?? 'dev-block-all-profile',
43-
},
46+
// Extract Portkey's trace ID from request headers to use as AIRS tr_id (AI Session ID)
47+
const traceId =
48+
ctx?.request?.headers?.['x-portkey-trace-id'] ||
49+
(typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
50+
? crypto.randomUUID()
51+
: Math.random().toString(36).substring(2) + Date.now().toString(36));
52+
53+
const payload: any = {
54+
tr_id: traceId, // Use Portkey's trace ID as AIRS AI Session ID
4455
metadata: {
4556
ai_model: params.ai_model ?? 'unknown-model',
4657
app_user: params.app_user ?? 'portkey-gateway',
58+
app_name: params.app_name ? `Portkey-${params.app_name}` : 'Portkey',
4759
},
4860
contents: [
4961
{ [hook === 'beforeRequestHook' ? 'prompt' : 'response']: text },
5062
],
5163
};
5264

53-
const res: any = await fetchAIRS(payload, apiKey, params.timeout);
65+
// Only include ai_profile if profile_name or profile_id is provided
66+
if (params.profile_name || params.profile_id) {
67+
payload.ai_profile = {};
68+
if (params.profile_name) {
69+
payload.ai_profile.profile_name = params.profile_name;
70+
}
71+
if (params.profile_id) {
72+
payload.ai_profile.profile_id = params.profile_id;
73+
}
74+
}
75+
76+
const res: any = await fetchAIRS(payload, apiKey);
5477

5578
if (!res || typeof res.action !== 'string') {
5679
throw new Error('Malformed AIRS response');

plugins/panw-prisma-airs/manifest.json

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"id": "panwPrismaAirs",
33
"name": "PANW Prisma AIRS Guardrail",
4-
"description": "Blocks prompt/response when Palo Alto Networks Prisma AI Runtime Security returns action=block.",
4+
"description": "Palo Alto Networks Prisma AI Runtime Security provides real-time scanning for prompt injections, malicious content, PII leakage, and policy violations. Blocks requests or responses when action=block is returned.",
55
"credentials": {
66
"type": "object",
77
"properties": {
88
"AIRS_API_KEY": {
99
"type": "string",
1010
"label": "AIRS API Key",
11-
"description": "The API key for Palo Alto Networks Prisma AI Runtime Security",
11+
"description": "API key for Palo Alto Networks Prisma AI Runtime Security. Find your API key in Strata Cloud Manager.",
1212
"encrypted": true
1313
}
1414
},
@@ -20,14 +20,69 @@
2020
"name": "PANW Prisma AIRS Guardrail",
2121
"type": "guardrail",
2222
"supportedHooks": ["beforeRequestHook", "afterRequestHook"],
23+
"description": [
24+
{
25+
"type": "subHeading",
26+
"text": "Scan prompts and responses for security threats using Prisma AIRS profiles linked to your API key."
27+
}
28+
],
2329
"parameters": {
2430
"type": "object",
2531
"properties": {
26-
"profile_name": { "type": "string" },
27-
"ai_model": { "type": "string" },
28-
"app_user": { "type": "string" }
32+
"profile_name": {
33+
"type": "string",
34+
"label": "Profile Name",
35+
"description": [
36+
{
37+
"type": "subHeading",
38+
"text": "AI security profile name from Prisma AIRS. Leave empty to use the profile linked to your API key in Strata Cloud Manager."
39+
}
40+
]
41+
},
42+
"profile_id": {
43+
"type": "string",
44+
"label": "Profile ID",
45+
"description": [
46+
{
47+
"type": "subHeading",
48+
"text": "AI security profile ID. Can be used instead of or in addition to profile_name."
49+
}
50+
]
51+
},
52+
"ai_model": {
53+
"type": "string",
54+
"label": "AI Model",
55+
"description": [
56+
{
57+
"type": "subHeading",
58+
"text": "The AI model being used (e.g., gpt-4, claude-3-5-sonnet). Used for tracking and reporting."
59+
}
60+
],
61+
"default": "unknown-model"
62+
},
63+
"app_user": {
64+
"type": "string",
65+
"label": "Application User",
66+
"description": [
67+
{
68+
"type": "subHeading",
69+
"text": "User identifier for tracking purposes. Useful for audit logs and user-level analytics."
70+
}
71+
],
72+
"default": "portkey-gateway"
73+
},
74+
"app_name": {
75+
"type": "string",
76+
"label": "Application Name",
77+
"description": [
78+
{
79+
"type": "subHeading",
80+
"text": "Custom application name for tracking. Will be prefixed with 'Portkey-' (e.g., 'Portkey-chatbot')."
81+
}
82+
]
83+
}
2984
},
30-
"required": ["profile_name"]
85+
"required": []
3186
}
3287
}
3388
]

0 commit comments

Comments
 (0)