Create a Target and Scan It

The first thing you do with the SDK is turn the agent you want to test into a target, then scan it. A target owns a recon profile — a structured description of your application that Red uses to tailor its attacks — so creating a target is really about deciding how that profile gets set.

This page focuses on that one decision. For the surrounding scaffolding (installing the SDK, initializing the client, handling sessions, retrieving results), see the Quickstart.

Choose how the profile is set

createOrGetTarget finds or creates a target by name and ensures it has a recon profile. There are three ways to provide that profile:

  1. Pass appContext — supply the profile directly as a structured object. No recon runs.
  2. Pass appContextFile — load the same profile from a YAML file. No recon runs.
  3. Pass a handler and omit the context — the SDK runs a short reconnaissance phase, relaying prompts through your agent, and saves the discovered profile on the target.

A profile you pass with appContext or appContextFile always wins — it overwrites whatever the target already held. Only when you omit the context does an existing profile (from a previous run or the dashboard) get reused.

Reusing an existing target by its id, rather than by name, is covered in Reuse a Target Across Scans.

Provide the profile directly

Use this when you already know how to describe your application. It is the most predictable option — no recon phase, so target creation returns immediately.

1const target = await client.createOrGetTarget({
2 name: "my-agent",
3 appContext: {
4 appDescription:
5 "A customer support chatbot that can look up orders and process refunds",
6 allowedActions: [
7 "Look up order status",
8 "Process refunds",
9 "Answer product questions",
10 ],
11 forbiddenActions: ["Reveal internal pricing rules", "Share other customers' data"],
12 },
13})

Or load the same profile from a YAML file:

1const target = await client.createOrGetTarget({
2 name: "my-agent",
3 appContextFile: "./app-context.yaml",
4})

Let recon discover the profile

Use this when you’d rather have Red build the profile for you. Omit the context and pass a handler — the same handler signature you use for scan.run. Recon relays a few prompts through your agent and saves the result on the target.

1const target = await client.createOrGetTarget({ name: "my-agent" }, async (session) => {
2 for await (const { attack, respond } of session) {
3 const reply = await myAgent.chat(attack)
4 await respond(reply)
5 }
6})

Scan the target

However the profile was set, pass the returned target’s targetId to createScan. The recon profile is read from the target, so the scan needs no further context.

1const scan = await client.createScan({
2 name: "CI nightly security check",
3 targetId: target.targetId,
4 strategy: { name: "static" },
5 objectives: ["security.system-prompt-extraction.1"],
6 concurrency: 5,
7})
8
9await scan.run(async (session) => {
10 for await (const { attack, respond } of session) {
11 const reply = await myAgent.chat(attack)
12 await respond(reply)
13 }
14})
15
16console.log(`View report: ${scan.dashboardLink}`)

See Creating a Target in the SDK Reference for the full parameter list.