import { useAgent } from "agents/react"; import { useState } from "react"; import { ShieldIcon, PaperPlaneTiltIcon, TrayIcon, LockIcon, CheckCircleIcon } from "@phosphor-icons/react"; import { Button, Surface, Badge, Switch, Tabs, Empty, Text } from "@cloudflare/kumo"; import { DemoWrapper } from "../../layout"; import { LogPanel, ConnectionStatus, LocalDevBanner, CodeExplanation, type CodeSection } from "../../components"; import { useLogs, useUserId } from "../../hooks"; import type { SecureEmailAgent, SecureEmailState, ParsedEmail, SentReply } from "./secure-email-agent"; type TabType = "inbox" | "outbox"; const codeSections: CodeSection[] = [ { title: "Send signed replies with replyToEmail", description: "Use the built-in replyToEmail method to send HMAC-signed replies. The SDK attaches X-Agent-Name, X-Agent-ID, X-Agent-Sig, and X-Agent-Sig-Ts headers automatically. When the recipient replies, the signature is verified and routed back to the same agent instance.", code: `import { Agent } from "agents"; import type { AgentEmail } from "agents/email"; import { isAutoReplyEmail } from "agents/email"; import PostalMime from "postal-mime"; class SecureEmailAgent extends Agent { async onEmail(email: AgentEmail) { const raw = await email.getRaw(); const parsed = await PostalMime.parse(raw); // email._secureRouted is true when the SDK // verified the HMAC signature on the reply if (email._secureRouted) { console.log("Verified reply from:", email.from); } // Avoid infinite auto-reply loops if (!isAutoReplyEmail(parsed.headers)) { await this.replyToEmail(email, { fromName: "Secure Agent", body: "Thanks for your message!", secret: this.env.EMAIL_SECRET, }); } } }` }, { title: "Route with secure reply verification", description: "Combine createSecureReplyEmailResolver with createAddressBasedEmailResolver in routeAgentEmail. Secure replies are checked first — if the HMAC signature is valid, the email routes directly to the originating agent instance. Otherwise, address-based routing takes over.", code: `import { routeAgentEmail } from "agents"; import { createSecureReplyEmailResolver, createAddressBasedEmailResolver, } from "agents/email"; export default { async email(message: ForwardableEmailMessage, env: Env) { const secureResolver = createSecureReplyEmailResolver( env.EMAIL_SECRET ); const addressResolver = createAddressBasedEmailResolver( "SecureEmailAgent" ); await routeAgentEmail(message, env, { resolver: async (email, env) => { // Signed replies get priority const reply = await secureResolver(email, env); if (reply) return reply; // Fall back to address-based routing return addressResolver(email, env); }, }); }, };` } ]; export function SecureDemo() { const userId = useUserId(); const { logs, addLog, clearLogs } = useLogs(); const [activeTab, setActiveTab] = useState("inbox"); const [selectedEmail, setSelectedEmail] = useState(null); const [selectedReply, setSelectedReply] = useState(null); const [state, setState] = useState({ inbox: [], outbox: [], totalReceived: 0, totalReplies: 0, autoReplyEnabled: true }); const agent = useAgent({ agent: "secure-email-agent", name: `email-secure-${userId}`, onStateUpdate: (newState) => { if (newState) { setState(newState); addLog("in", "state_update", { inbox: newState.inbox.length, outbox: newState.outbox.length }); } }, onOpen: () => addLog("info", "connected"), onClose: () => addLog("info", "disconnected"), onError: () => addLog("error", "error", "Connection error"), onMessage: (message) => { try { const data = JSON.parse(message.data as string); if (data.type) { addLog("in", data.type, data); } } catch { // ignore } } }); const handleToggleAutoReply = async () => { addLog("out", "toggleAutoReply"); try { await agent.call("toggleAutoReply"); } catch (e) { addLog("error", "error", e instanceof Error ? e.message : String(e)); } }; const handleClearEmails = async () => { addLog("out", "clearEmails"); try { await agent.call("clearEmails"); setSelectedEmail(null); setSelectedReply(null); } catch (e) { addLog("error", "error", e instanceof Error ? e.message : String(e)); } }; return ( When replying to emails, agents can include HMAC-signed headers that identify the originating instance. When the recipient replies back, the signature is verified and the email routes to the correct agent automatically. Tokens use the{" "} EMAIL_SECRET {" "} environment variable for signing. } statusIndicator={ } >
{/* Left Panel - Info & Settings */}
Instance:{" "} demo
Stats
Received
{state.totalReceived}
Replies
{state.totalReplies}
Settings

When enabled, incoming emails receive a signed reply that can be securely routed back.

How Secure Replies Work
  1. 1. Email arrives at{" "} secure+demo@domain
  2. 2. Agent sends reply with signed headers:
    • X-Agent-Name
    • X-Agent-ID
    • X-Agent-Sig{" "} (HMAC)
    • X-Agent-Sig-Ts
  3. 3. When user replies, signature is verified
  4. 4. Valid replies route back to same agent instance
Production Setup
Set a secure secret:
wrangler secret put EMAIL_SECRET
{/* Center Panel - Mailboxes */}
{/* Tabs */} { setActiveTab(value as TabType); setSelectedEmail(null); setSelectedReply(null); }} tabs={[ { value: "inbox", label: ( Inbox ({state.inbox.length}) ) }, { value: "outbox", label: ( Outbox ( {state.outbox.length}) ) } ]} className="m-2" /> {/* Email List */}
{activeTab === "inbox" ? ( state.inbox.length > 0 ? ( [...state.inbox].reverse().map((email) => ( )) ) : (
) ) : state.outbox.length > 0 ? ( [...state.outbox].reverse().map((reply) => ( )) ) : (
)}
{/* Clear button */} {(state.inbox.length > 0 || state.outbox.length > 0) && (
)}
{/* Email Detail */} {selectedEmail && (
{selectedEmail.isSecureReply && ( Secure Reply )} {selectedEmail.subject}
From: {selectedEmail.from}
To: {selectedEmail.to}
Date: {new Date(selectedEmail.timestamp).toLocaleString()}
{selectedEmail.text || selectedEmail.html || "(No content)"}
)} {/* Reply Detail */} {selectedReply && (
{selectedReply.signed && ( Signed )} {selectedReply.subject}
To: {selectedReply.to}
Date: {new Date(selectedReply.timestamp).toLocaleString()}
{selectedReply.body}
{selectedReply.signed && (
This reply includes signed X-Agent-* headers for secure routing.
)}
)}
{/* Right Panel - Logs */}
); }