<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: acidnyan</title>
    <description>The latest articles on DEV Community by acidnyan (@acidnyan).</description>
    <link>https://dev.to/acidnyan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4208805%2F5910d296-e229-4b40-9621-bd2dd0be7130.png</url>
      <title>DEV Community: acidnyan</title>
      <link>https://dev.to/acidnyan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/acidnyan"/>
    <language>en</language>
    <item>
      <title>Zero-Trust Task Delegation Across Different Owners' AI Agents (Why I Built ACP After PHP2Shell &amp; CVE-2026-115419)</title>
      <dc:creator>acidnyan</dc:creator>
      <pubDate>Mon, 26 Oct 2026 13:27:02 +0000</pubDate>
      <link>https://dev.to/acidnyan/zero-trust-task-delegation-across-different-owners-ai-agents-why-i-built-acp-after-php2shell--1pfg</link>
      <guid>https://dev.to/acidnyan/zero-trust-task-delegation-across-different-owners-ai-agents-why-i-built-acp-after-php2shell--1pfg</guid>
      <description>&lt;h2&gt;
  
  
  Why Collaborating Across Different Owners' Agents Is Dangerous
&lt;/h2&gt;

&lt;p&gt;Delegating a coding or research task from your local &lt;strong&gt;Claude Code&lt;/strong&gt; or &lt;strong&gt;Codex CLI&lt;/strong&gt; to an autonomous agent owned by a friend, contractor, or external partner sounds great in theory.&lt;/p&gt;

&lt;p&gt;In practice, almost every existing multi-agent framework and wire protocol (including standard MCP or Google A2A setups) assumes a &lt;strong&gt;single trust boundary&lt;/strong&gt;. The moment you connect agents owned by two different people across the internet, you hit three critical security walls:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Raw API Key Exfiltration&lt;/strong&gt;: If a worker process receives &lt;code&gt;OPENAI_API_KEY&lt;/code&gt;, &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;, or &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; in its environment variables, any RCE or process memory disclosure exposes your raw credentials. Last week's &lt;strong&gt;PHP2Shell (&lt;code&gt;CVE-2026-109618&lt;/code&gt; / &lt;code&gt;CVE-2026-109619&lt;/code&gt;)&lt;/strong&gt; advisories proved how frontier AI models can chain memory bugs to dump secrets straight out of process memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Session State Bleed &amp;amp; Isolation Spoofing&lt;/strong&gt;: Earlier this month, &lt;strong&gt;AWS Strands Agents (&lt;code&gt;CVE-2026-115419&lt;/code&gt;)&lt;/strong&gt; suffered an A2A server concurrency flaw where state bled across concurrent requests. Worse, when a remote worker claims it executed your task inside an isolated Docker container, the requester normally has no cryptographic way to verify that claim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inbound Ports &amp;amp; NAT Traversal&lt;/strong&gt;: Opening inbound ports or sharing a VPN mesh with an external party expands your attack surface unnecessarily.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To solve this, I built &lt;strong&gt;ACP (Agent Collaboration Platform)&lt;/strong&gt; — an Apache-2.0 TypeScript reference implementation and zero-trust governance overlay on top of A2A and MCP for &lt;strong&gt;cross-owner&lt;/strong&gt; agent collaboration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/acidnyan/agent-collab-platform" rel="noopener noreferrer"&gt;https://github.com/acidnyan/agent-collab-platform&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Red-Team Security Proofs (&lt;code&gt;SECURITY_PROOF.md&lt;/code&gt;)&lt;/strong&gt;: &lt;a href="https://github.com/acidnyan/agent-collab-platform/blob/main/SECURITY_PROOF.md" rel="noopener noreferrer"&gt;https://github.com/acidnyan/agent-collab-platform/blob/main/SECURITY_PROOF.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How ACP Works: 5 Zero-Trust Guarantees
&lt;/h2&gt;

&lt;p&gt;ACP treats both the remote agent and the message relay as untrusted by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Owner A: Requester]                         [Untrusted Blind Relay]                         [Owner B: Worker]
Claude Code / Codex  ---&amp;gt;  ACP Gateway A  ===(Ed25519 + RFC 8785 JCS)===&amp;gt;  HTTPS/SSE Queue  &amp;lt;===  ACP Gateway B
                                                                          (Outbound Poll Only)         |
                                                                                                +------+------+
                                                                                                |             |
                                                                                        Credential Proxy   Isolated Worker
                                                                                        (Holds raw keys)   (acp_cred_... handle only,
                                                                                                            shell: false)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Zero Raw Keys in Worker Memory (&lt;code&gt;CredentialProxy&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Worker subprocesses and sandboxes never receive raw API keys (&lt;code&gt;OPENAI_API_KEY&lt;/code&gt;, &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt;, &lt;code&gt;GITHUB_TOKEN&lt;/code&gt;, etc.). &lt;code&gt;sanitizedEnvironment&lt;/code&gt; strips host secrets before spawn.&lt;br&gt;
Instead, the host's local &lt;code&gt;CredentialProxy&lt;/code&gt; issues a short-lived, task-scoped capability handle (&lt;code&gt;acp_cred_...&lt;/code&gt;) and injects upstream headers only on validated requests. When the task finishes, the handle is immediately revoked. Even a full worker memory dump yields zero bytes of raw secret material.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Zero Open Inbound Ports (Outbound-Only Blind Relay)
&lt;/h3&gt;

&lt;p&gt;Neither the requester nor the worker opens an inbound port. Both sides stay behind NAT/firewalls and make outbound HTTPS/SSE calls to a blind relay.&lt;br&gt;
Every inbox poll requires a signed &lt;code&gt;RelayAuth&lt;/code&gt; header (&lt;code&gt;Ed25519&lt;/code&gt; over &lt;code&gt;agentDid + timestamp + nonce&lt;/code&gt;), preventing cross-session snooping and replay attacks.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Ed25519 + RFC 8785 (JCS) Canonical Signatures
&lt;/h3&gt;

&lt;p&gt;Every &lt;code&gt;TaskContract&lt;/code&gt;, attenuated &lt;code&gt;CapabilityGrant&lt;/code&gt;, and &lt;code&gt;TaskReceipt&lt;/code&gt; is canonicalized using &lt;a href="https://www.rfc-editor.org/rfc/rfc8785" rel="noopener noreferrer"&gt;RFC 8785 JSON Canonicalization Scheme (JCS)&lt;/a&gt; and signed with &lt;code&gt;did:key&lt;/code&gt; (&lt;code&gt;Ed25519&lt;/code&gt;). Any 1-byte modification to budgets (&lt;code&gt;maxTokens&lt;/code&gt;, &lt;code&gt;maxCostUsd&lt;/code&gt;, &lt;code&gt;maxDurationSeconds&lt;/code&gt;), scopes, or SHA-256 artifact hashes is deterministically rejected.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. No Shell Interpolation + Cryptographically Verified Isolation
&lt;/h3&gt;

&lt;p&gt;Command workers run strictly via &lt;code&gt;spawn(..., { shell: false })&lt;/code&gt; with inputs passed over &lt;code&gt;stdin&lt;/code&gt; and temporary files — eliminating shell metacharacter injection (&lt;code&gt;$(...)&lt;/code&gt;, backticks, &lt;code&gt;;&lt;/code&gt;).&lt;br&gt;
Furthermore, the worker's signed &lt;code&gt;TaskReceipt&lt;/code&gt; binds the actual &lt;code&gt;effectiveIsolationLevel&lt;/code&gt; (&lt;code&gt;subprocess&lt;/code&gt;, &lt;code&gt;container&lt;/code&gt;, etc.). If a contract requires &lt;code&gt;container&lt;/code&gt; isolation and a worker attempts to downgrade to &lt;code&gt;subprocess&lt;/code&gt;, verification fails automatically.&lt;/p&gt;
&lt;h3&gt;
  
  
  5. BYOK Cost Isolation
&lt;/h3&gt;

&lt;p&gt;Each owner's agent uses its own local LLM/API keys within the signed budget constraints of the &lt;code&gt;TaskContract&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Don't Trust Claims — Run the Red-Team Security Proof Suite
&lt;/h2&gt;

&lt;p&gt;In 2026, saying &lt;em&gt;"trust me, I designed it securely"&lt;/em&gt; is not enough for open-source agent infrastructure.&lt;/p&gt;

&lt;p&gt;ACP includes an executable red-team adversarial test suite (&lt;code&gt;conformance/security-proofs.test.ts&lt;/code&gt;) that actively attacks the production codebase and proves every attack is blocked in under 5 seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/acidnyan/agent-collab-platform.git
&lt;span class="nb"&gt;cd &lt;/span&gt;agent-collab-platform
pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm build
pnpm &lt;span class="nb"&gt;test&lt;/span&gt;:security-proof
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What &lt;code&gt;pnpm test:security-proof&lt;/code&gt; Actively Tests
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proof Category&lt;/th&gt;
&lt;th&gt;Simulated Red-Team Attack&lt;/th&gt;
&lt;th&gt;Verified Outcome&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Proof 1: Secret Exfiltration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Worker dumps &lt;code&gt;process.env&lt;/code&gt;, inspects VM globals, or reuses another task's / expired &lt;code&gt;acp_cred_...&lt;/code&gt; handle&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0 bytes&lt;/strong&gt; of raw secrets exposed; unauthorized handles rejected (&lt;code&gt;401&lt;/code&gt;/&lt;code&gt;403&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Proof 2: RCE &amp;amp; Shell Injection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Payloads with &lt;code&gt;$(touch /tmp/pwn)&lt;/code&gt;, &lt;code&gt;; rm -rf /&lt;/code&gt;, &lt;code&gt;../../etc/passwd&lt;/code&gt;, and &lt;code&gt;__proto__&lt;/code&gt; pollution&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;shell: false&lt;/code&gt; prevents execution; path traversal &amp;amp; schema violations rejected (&lt;code&gt;100%&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Proof 3: Cross-Session Bleed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Polling another agent's relay inbox or lying about &lt;code&gt;effectiveIsolationLevel&lt;/code&gt; (&lt;code&gt;subprocess&lt;/code&gt; vs &lt;code&gt;container&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Rejected by &lt;code&gt;RelayAuth&lt;/code&gt; Ed25519 check and receipt isolation gate (&lt;code&gt;100%&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Proof 4: OOM / DoS &amp;amp; SSRF&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;gt;1MB relay payloads, queue flooding, nonce replay, and SSRF targets (&lt;code&gt;http://169.254.169.254&lt;/code&gt;, &lt;code&gt;127.0.0.1&lt;/code&gt;, &lt;code&gt;file://&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Oversized payloads/queues rejected (&lt;code&gt;413&lt;/code&gt;/&lt;code&gt;429&lt;/code&gt;); private IP &amp;amp; non-HTTPS URLs blocked (&lt;code&gt;100%&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Proof 5: 1-Byte Tampering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Modifying 1 byte of a signed &lt;code&gt;TaskContract&lt;/code&gt; budget, &lt;code&gt;TaskReceipt&lt;/code&gt; artifact hash, or &lt;code&gt;RelayAuth&lt;/code&gt; timestamp&lt;/td&gt;
&lt;td&gt;Cryptographically rejected via Ed25519 + RFC 8785 JCS (&lt;code&gt;100%&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Try a 30-Second Live Collaboration Across Two Terminals
&lt;/h2&gt;

&lt;p&gt;A public blind relay is running on Cloudflare Workers + Durable Objects at &lt;code&gt;https://acp-relay.agent-collab.workers.dev&lt;/code&gt; (or you can run the offline local relay included in the repo).&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminal 1 (Worker waiting for tasks)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node cli/acp-cli.mjs demo:worker &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--relay&lt;/span&gt; https://acp-relay.agent-collab.workers.dev &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--adapter&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--command&lt;/span&gt; &lt;span class="s2"&gt;"node -e &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;const fs=require('fs');const env=JSON.parse(fs.readFileSync(0,'utf8'));console.log(JSON.stringify({summary:'Processed task safely',output:{taskId:env.taskId}}))&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prints a signed &lt;code&gt;acp-invite:...&lt;/code&gt; token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminal 2 (Requester delegating a task)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node cli/acp-cli.mjs demo:delegate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--invite&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;paste-acp-invite-token-here&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"Security architecture review"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--input&lt;/span&gt; &lt;span class="s1"&gt;'{"target":"relay-auth"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository also includes &lt;code&gt;AGENTS.md&lt;/code&gt; and &lt;code&gt;SKILL.md&lt;/code&gt; at the root, so you can point Claude Code, Codex CLI, or Cursor at the repository and ask your agent in natural language to act as a worker or delegate a task using an invite token.&lt;/p&gt;




&lt;h2&gt;
  
  
  Feedback Welcome
&lt;/h2&gt;

&lt;p&gt;I would love brutal feedback from security engineers and agent builders — especially if you can find a way to bypass any of the checks in &lt;a href="https://github.com/acidnyan/agent-collab-platform/blob/main/conformance/security-proofs.test.ts" rel="noopener noreferrer"&gt;&lt;code&gt;conformance/security-proofs.test.ts&lt;/code&gt;&lt;/a&gt;!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/acidnyan/agent-collab-platform" rel="noopener noreferrer"&gt;https://github.com/acidnyan/agent-collab-platform&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threat Model &amp;amp; Proofs&lt;/strong&gt;: &lt;a href="https://github.com/acidnyan/agent-collab-platform/blob/main/SECURITY_PROOF.md" rel="noopener noreferrer"&gt;https://github.com/acidnyan/agent-collab-platform/blob/main/SECURITY_PROOF.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>typescript</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
