> For clean Markdown of this page, append .md to its URL. For the complete documentation index, see https://www.superagent.sh/llms.txt.


Put Context Guardrails between Resend and your agent so phishing, prompt injection, and malicious attachments never enter agent context.

# Quarantine hostile email before agents read it

Treat every inbound email as untrusted until it clears Context Guardrails.
Resend receives the message, your webhook fetches the raw email, and Superagent
checks the sender, body, attachments, and links before your application passes
anything to an agent.

Use this verdict policy:

- `safe` — deliver to the agent
- `caution` — hold for review
- `suspicious` or `dangerous` — quarantine

## Prerequisites

- A Resend account with a receiving domain
- A Next.js application with a public webhook route
- `RESEND_API_KEY`, `RESEND_WEBHOOK_SECRET`, and `SUPERAGENT_API_KEY` stored in
  the application environment
- An existing queue or function that delivers approved email to your agent

## 1. Receive email with Resend

Open the **Receiving** tab in Resend and copy the account's `.resend.app`
address, or configure a custom domain with its required MX record.

Create a webhook in Resend:

1. Open **Webhooks** and select **Add Webhook**.
2. Enter your application's HTTPS route, such as
   `https://app.example.com/api/webhooks/resend`.
3. Subscribe to `email.received`.
4. Copy the webhook signing secret into `RESEND_WEBHOOK_SECRET`.

The `email.received` payload contains message metadata and an `email_id`. Fetch
the stored raw message before scanning so Context Guardrails can inspect the
original headers, MIME structure, attachments, HTML, text, and links.

## 2. Verify and scan the raw email

Create `app/api/webhooks/resend/route.ts`:

```typescript-example
import { Resend } from "resend";
import { NextResponse } from "next/server";

const resend = new Resend(process.env.RESEND_API_KEY);

export async function POST(request: Request) {
  const payload = await request.text();

  let event;
  try {
    event = resend.webhooks.verify({
      payload,
      headers: {
        id: request.headers.get("svix-id") ?? "",
        timestamp: request.headers.get("svix-timestamp") ?? "",
        signature: request.headers.get("svix-signature") ?? "",
      },
      webhookSecret: process.env.RESEND_WEBHOOK_SECRET!,
    });
  } catch {
    return new Response("Invalid webhook signature", { status: 400 });
  }

  if (event.type !== "email.received") {
    return NextResponse.json({ status: "ignored" });
  }

  const { data: email, error } = await resend.emails.receiving.get(
    event.data.email_id,
  );
  const downloadUrl = email?.raw?.download_url;
  if (error || !downloadUrl) {
    return NextResponse.json(
      { error: "Raw email is unavailable" },
      { status: 502 },
    );
  }

  const rawResponse = await fetch(downloadUrl);
  if (!rawResponse.ok) {
    return NextResponse.json(
      { error: "Raw email download failed" },
      { status: 502 },
    );
  }
  const rawEmail = await rawResponse.arrayBuffer();

  const scanResponse = await fetch(
    "https://superagent.sh/api/v1/context/email?mode=full&details=true",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.SUPERAGENT_API_KEY}`,
        "Content-Type": "message/rfc822",
      },
      body: rawEmail,
      signal: AbortSignal.timeout(90_000),
    },
  );
  if (!scanResponse.ok) {
    return NextResponse.json(
      { error: "Email guardrail scan failed" },
      { status: 502 },
    );
  }

  const artifact = (await scanResponse.json()).data;

  if (
    artifact.verdict === "suspicious" ||
    artifact.verdict === "dangerous"
  ) {
    return NextResponse.json({
      status: "quarantined",
      identifier: artifact.identifier,
      verdict: artifact.verdict,
    });
  }

  if (artifact.verdict === "caution") {
    return NextResponse.json({
      status: "review",
      identifier: artifact.identifier,
    });
  }

  // This is the only branch that may enqueue rawEmail for your agent.
  return NextResponse.json({
    status: "approved",
    emailId: event.data.email_id,
    identifier: artifact.identifier,
  });
}
```

Webhook verification must use `request.text()` before JSON parsing. Resend
signatures are calculated from the untouched body, so parsing and serializing
the payload before verification invalidates the signature.

`mode=full` waits for the completed scan. If the receiving platform cannot
wait up to 90 seconds, persist the verified `email_id`, enqueue processing,
return `202`, and run the raw-email fetch and scan in a worker.

## 3. Deliver only approved email to the agent

Replace the final `approved` response with the application's existing queue or
agent handoff. Pass `rawEmail` only from that branch.

Keep the other outcomes separate:

- Send `caution` to a review queue.
- Store the scan identifier and verdict for quarantined messages.
- Return `2xx` for reviewed and quarantined messages so Resend does not retry
  content you intentionally withheld.
- Return a retryable error only when signature verification succeeded but the
  raw email or guardrail service was temporarily unavailable.

The agent should never summarize, reply to, follow links from, or call tools
with an email before the `safe` verdict.

## 4. Test the complete email boundary

1. Send a Resend webhook test and confirm the signature verifies.
2. Send a normal email and confirm it returns `approved`.
3. Send a test message containing an instruction aimed at the agent and confirm
   it returns `suspicious` or `dangerous`.
4. Confirm the unsafe message never enters the agent queue, logs, or prompt.
5. Inspect the Context Guardrails result for sender authentication, MIME,
   attachment, and outbound-link evidence.

## Next steps

- [Protect email and messages](https://www.superagent.sh/docs/security-workers/agent-guardrails/email-and-messages)
- [Understand Context Guardrails](https://www.superagent.sh/docs/security-workers/agent-guardrails/context)
- [Use the Context Guardrails API](https://www.superagent.sh/docs/api/context-guardrails)

---
Source: https://www.superagent.sh/docs/use-cases/quarantine-hostile-email-before-agent-delivery
Index: https://www.superagent.sh/llms.txt
