<?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>Forem: Mukesh Chandnani</title>
    <description>The latest articles on Forem by Mukesh Chandnani (@faalantir).</description>
    <link>https://forem.com/faalantir</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3638060%2F27384b0a-d08d-45b2-929a-79bfa3ae14e4.png</url>
      <title>Forem: Mukesh Chandnani</title>
      <link>https://forem.com/faalantir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/faalantir"/>
    <language>en</language>
    <item>
      <title>How to Secure LangChain Agents with Cryptographic Signatures (Tutorial)</title>
      <dc:creator>Mukesh Chandnani</dc:creator>
      <pubDate>Mon, 01 Dec 2025 00:27:26 +0000</pubDate>
      <link>https://forem.com/faalantir/how-to-secure-langchain-agents-with-cryptographic-signatures-tutorial-44ee</link>
      <guid>https://forem.com/faalantir/how-to-secure-langchain-agents-with-cryptographic-signatures-tutorial-44ee</guid>
      <description>&lt;h2&gt;
  
  
  🚀 The Problem: Agents are "Anonymous Ghosts"
&lt;/h2&gt;

&lt;p&gt;Building an autonomous agent in LangChain is magical. You give it a tool like transfer_money, and it just works.&lt;/p&gt;

&lt;p&gt;But that magic is also a security nightmare.&lt;/p&gt;

&lt;p&gt;If your LLM hallucinates or gets prompt-injected, it can call that tool instantly. The API receiving the request has no idea if it was a valid user intent or a rogue agent. The request is just anonymous JSON.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We need Attribution. We need the agent to SIGN its work.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🖼️ Visual Guide
&lt;/h3&gt;

&lt;p&gt;Prefer a visual explanation? I broke this architecture down into a &lt;strong&gt;&lt;a href="https://www.linkedin.com/posts/mukeshchandnani_agent-identity-protocol-activity-7400704806878826496-rs5v?utm_source=share&amp;amp;utm_medium=member_desktop&amp;amp;rcm=ACoAAAG1OCgBsv29z2k-yn7cUNlD46U9QGvqxGw" rel="noopener noreferrer"&gt;6-slide carousel on LinkedIn&lt;/a&gt;&lt;/strong&gt;. It covers the "Why" and "How" in under a minute.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 The Solution: The Identity Layer
&lt;/h2&gt;

&lt;p&gt;I built the &lt;a href="https://github.com/faalantir/mcp-agent-identity" rel="noopener noreferrer"&gt;Agent Identity Protocol (AIP)&lt;/a&gt; to solve this. It is an open-source tool that gives your agent a local crypto wallet.&lt;/p&gt;

&lt;p&gt;Instead of just executing a tool blindly, we force the agent to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate a signature&lt;/strong&gt; for the specific action payload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pass that signature&lt;/strong&gt; to the API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify&lt;/strong&gt; it before money moves.&lt;/p&gt;

&lt;p&gt;This creates a &lt;strong&gt;Non-Repudiable Audit Trail&lt;/strong&gt;. You know exactly which agent authorized the action, and you can prove the message wasn't tampered with.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 The Pattern (Code Tutorial)
&lt;/h2&gt;

&lt;p&gt;Here is how to implement this pattern in Python using standard LangChain tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: The "Secure Tool" Pattern&lt;/strong&gt;&lt;br&gt;
We wrap our sensitive logic in a secure function that requires a signature before execution.&lt;/p&gt;

&lt;p&gt;from langchain.tools import tool&lt;br&gt;
from pydantic import BaseModel, Field&lt;/p&gt;

&lt;h2&gt;
  
  
  --- The Identity Layer (Your Tool) ---
&lt;/h2&gt;

&lt;p&gt;class AgentIdentityClient:&lt;br&gt;
    """Wraps your local Agent Identity Protocol."""&lt;br&gt;
    def sign_action(self, action_description: str) -&amp;gt; str:&lt;br&gt;
        # In a real app, this calls your MCP server (Agent Identity Protocol)&lt;br&gt;
        print(f"🔐 AIP: Agent is signing action: '{action_description}'...")&lt;br&gt;
        # Simulating a return of a cryptographic signature&lt;br&gt;
        return "7f8a9d001...[cryptographic_signature]...e4f"&lt;/p&gt;

&lt;p&gt;identity_layer = AgentIdentityClient()&lt;/p&gt;

&lt;h2&gt;
  
  
  --- The Secure Tool ---
&lt;/h2&gt;

&lt;p&gt;class TransferInput(BaseModel):&lt;br&gt;
    amount: int = Field(description="Amount to transfer in USD")&lt;br&gt;
    to_user: str = Field(description="The recipient's username")&lt;/p&gt;

&lt;p&gt;@tool("secure_transfer", args_schema=TransferInput)&lt;br&gt;
def secure_transfer(amount: int, to_user: str) -&amp;gt; str:&lt;br&gt;
    """&lt;br&gt;
    Transfers money securely. &lt;br&gt;
    REQUIRES a cryptographic signature from Agent Identity Protocol.&lt;br&gt;
    """&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 1. Construct the payload
payload = f"TRANSFER_USD:{amount}:TO:{to_user}"

# 2. Force the Agent to Sign (The Handshake)
try:
    signature = identity_layer.sign_action(payload)
except Exception as e:
    return f"❌ Authorization Failed: Could not sign request."

# 3. Execute with Proof
# In a real app, we send the signature to the Bank API to be verified
print(f"🏦 BANK: Verifying signature... VALID.")
print(f"💰 BANK: Transferred ${amount} to {to_user} (SECURE).")

return f"✅ Transfer Complete. Audit ID: {signature[:10]}..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 2: The "Unsafe" Comparison&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without this Identity Layer, most custom tools look like this. If the LLM hallucinates, the money moves instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚫 THE UNSAFE WAY (How most agents are built)
&lt;/h2&gt;

&lt;p&gt;@tool&lt;br&gt;
def unsafe_transfer(amount: int, to_user: str):&lt;br&gt;
    """Transfers money immediately without security checks."""&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# DANGER: If the LLM hallucinates, this runs instantly.&lt;br&gt;
print(f"⚠️ BANK WARNING: Executing UNVERIFIED transaction of ${amount} to {to_user}!")&lt;br&gt;
print(f"💸 BANK: Money moved without proof.")

&lt;p&gt;return "Transfer complete."&lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  📦 How to try it yourself&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;You can run this example locally in 2 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install the MCP Server&lt;/strong&gt; (via Smithery or Source).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clone the repo:&lt;/strong&gt; &lt;a href="https://github.com/faalantir/mcp-agent-identity" rel="noopener noreferrer"&gt;https://github.com/faalantir/mcp-agent-identity&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run the demo:&lt;/strong&gt; &lt;code&gt;python examples/langchain-python/secure_tool.py&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤝 Join the Discussion
&lt;/h2&gt;

&lt;p&gt;Agent identity shouldn't be an afterthought. If we want agents to do real work, they need real IDs.&lt;/p&gt;

&lt;p&gt;If you are building production agents, I'd love your feedback on the security model. &lt;a href="https://github.com/faalantir/mcp-agent-identity" rel="noopener noreferrer"&gt;Check out the Repo here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>langchain</category>
      <category>python</category>
    </item>
  </channel>
</rss>
