Custom Target Adapters
A custom target adapter is a Python script that enables AI Red Teaming to
communicate with AI targets that the built-in connectors do not support.
| Where Can I Use This? | What Do I Need? |
- Prisma AIRS (AI Red Teaming)
|
|
What Is a Custom Target Adapter?
A custom target adapter is a lightweight Python script that extends AI Red
Teaming's connectivity to Applications, Agents, or Models not supported by its
built-in connectors. For each red-team prompt, AI Red Teaming passes your script the
prompt and your configuration. Your script calls the target, reads the reply, and
returns the text to AI Red Teaming. Your adapter code and credentials run on your
own infrastructure inside an adapter sidecar, alongside the Network Channel
client you deploy. No user code and credentials execute in the AI Red Teaming.
Adapters replace bespoke proxy solutions with a standardized and reusable interface.
A bespoke proxy is a custom-built intermediary server designed for a specific
company or user to handle web traffic, rather than a generic or pre-packaged
commercial proxy.
The following table compares a bespoke proxy approach with a custom target
adapter:
| Without Adapters (Bespoke Proxy) | With a Custom Adapter |
| Each target requires a separate custom-built proxy that you
develop and maintain. | You write Python functions to a standard interface. Function
signatures, inputs, and return types are already defined for
you. |
| You deploy and host the proxy yourself. | The adapter sidecar is bundled in the Network Channel Helm chart
and is deployed with a single helm upgrade. |
| Manual coordination is required to verify the proxy is
running. | The Network Channel heartbeat tells AI Red Teaming the connection
is live. |
| You manually configure the endpoint URL, authentication method,
request and response format in the web interface for each
target. | Your script defines the authentication, request structure, and
response parsing. No manual configuration in the web interface is
required. |
| Every proxy is purpose-built for a single target and cannot be
shared or reused across other targets. | You write one adapter and reuse it across multiple targets, each
with its own configuration. |
Use a custom adapter when your target requires any of the following:
- Your target uses a custom request or response format, such as a custom JSON
structure, multi-step API calls, or cryptographically signed requests.
- Your target requires a value generated fresh for each request, such as a UUID,
timestamp, or nonce in the request body or headers.
- Your target requires a session created before the conversation begins, with the
session ID carried across turns.
- Your target uses non-standard authentication, such as a custom token exchange,
signed requests, or a multi-step login flow. Standard OAuth does not require an
adapter.
- Your target uses a protocol the built-in connectors do not support, such as
GraphQL, non-standard WebSocket framing, a multi-call REST flow, an SDK, or a
custom streaming pattern.
Use a built-in connector if the only difference from a standard integration is a
header value or base URL, or if your target uses standard OAuth.
Adapter Functions
| Function | When It Runs | Purpose |
| call_target(context,
inference_input) | Every turn | Full-control alternative to
pre_process/post_process. You
make the call and return the reply directly. Use this for non-HTTP
transports such as WebSocket, GraphQL, and SDK-based clients. If
defined, call_target takes precedence over
pre_process/post_process. |
| authenticate(context) | On demand; result is cached and auto-refreshed | Obtains auth credentials. The platform caches the result and
exposes it to other functions as
context.auth. |
| session_pre_process(context) | First turn of every conversation, including single-turn
scans | Initializes a server-side session. The return value is available
as context.session for all turns in the
conversation. |
Configure Variable Overrides for Variables and Secret
Instead of hard-coding values that change per environment or account, declare them as
variables or secret. Your script reads them by key at runtime.
| Type | What It Stores | Visibility |
| Variables | Non-sensitive values such as URLs, IDs, and model names. For
example, read using context.vars["key"]. | Visible in the web interface. |
| Secret | Sensitive values such as API keys, client secrets, and passwords.
For example, read using
context.secrets["key"]. | Masked in the web interface and scrubbed from logs. |
When you attach an adapter to a target, you can override any
variable or secret for that target. For example, a different
base_url for staging or a different account's
api_key. At scan time, the target's overrides take precedence;
values you do not override fall back to the adapter default. Your script reads
context.vars and context.secrets and receives
the resolved value.
Runtime Limits
The adapter runtime enforces the following limits on every call. Design your
functions to complete within these limits. A turn fails if your function raises an
exception or times out.
| Runtime Limit | Value | Notes |
| Overall execution time per call | 110 s | Your functions must complete within this window. |
| HTTP timeout for target calls | 100 s | Applies to context.http calls. |
| Carried state size (auth and session combined) | 64 KB | Serialized. Oversized session state ends the
conversation. |
| Cold start | ~50–200 ms | The script is loaded fresh per request. |
| Available packages | stdlib, httpx,
websockets | Contact AI Red Teaming to request additional packages. |
A turn succeeds only when your function returns cleanly. A raised exception or
timeout marks the turn as failed. Avoid unbounded loops, and set explicit timeouts
on calls that context.http does not cover.
How an Adapter Runs
AI Red Teaming loads and runs your adapter script on every turn:
- AI Red Teaming sends your script and configuration through the encrypted Network
Channel tunnel to the adapter sidecar on your infrastructure.
- The sidecar loads your script fresh and calls your functions, passing a
context object that contains your configuration, secrets,
authentication state, session state, and a ready-to-use HTTP client.
- Your code calls the target and returns the reply text.
- The sidecar returns the reply, any error signals, and your
print() output to AI Red Teaming.
Your script is stateless. Module-level globals and
variables are discarded between turns.
The only state carried across turns
is:
- auth state (returned by authenticate(), available as
context.auth), and
- session state (returned by session_pre_process(),
available as context.session).
To pass a value between turns, return it as
session_state.
How to Set Up a Custom Target Adapter
To implement a custom target adapter in your environment, complete the following
steps in order:
- Set up prerequisites. Upgrade the Network
Channel Helm chart to v1.4.0 or later, enable the adapter sidecar, and configure
a Network Channel for your private endpoint.
An active Network Channel is required to host and
execute adapter
code.
- Build the adapter script. Write your Python adapter
using Pattern A (pre_process and post_process)
for standard HTTP targets, or Pattern B (call_target) for
WebSocket, GraphQL, or SDK-based targets. Optionally add
authenticate() and
session_pre_process().
- Test and activate the adapter. Upload the
script in the AI Red Teaming Web Interfaces (), run Validate to confirm the adapter runs correctly, then select
Create
Adapter
to make it available to targets.
- Attach the adapter to a target. On a new
or existing target, set the
Connection
Method
to
Custom
Adapter,
select the adapter and Network Channel, and optionally configure per-target
variable overrides.
- Run a
scan. Select the target and start a scan. AI Red Teaming routes each
red-team prompt through the adapter sidecar to your target and collects the
results.