<?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: Baptiste Le Bouquin</title>
    <description>The latest articles on DEV Community by Baptiste Le Bouquin (@raknaos).</description>
    <link>https://dev.to/raknaos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4114622%2F237cf8c8-193e-4bca-bfa5-5d3530a06261.webp</url>
      <title>DEV Community: Baptiste Le Bouquin</title>
      <link>https://dev.to/raknaos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/raknaos"/>
    <language>en</language>
    <item>
      <title>Handing Real Logins to Headless AI Agents: Building the Lightpanda Session Bridge</title>
      <dc:creator>Baptiste Le Bouquin</dc:creator>
      <pubDate>Mon, 07 Sep 2026 22:00:10 +0000</pubDate>
      <link>https://dev.to/raknaos/handing-real-logins-to-headless-ai-agents-building-the-lightpanda-session-bridge-17je</link>
      <guid>https://dev.to/raknaos/handing-real-logins-to-headless-ai-agents-building-the-lightpanda-session-bridge-17je</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; When autonomous AI agents need to interact with modern web dashboards, handing them passwords or session tokens in prompts is a security disaster. I built &lt;a href="https://github.com/Raknaos/lightpanda-session-bridge" rel="noopener noreferrer"&gt;&lt;strong&gt;Lightpanda Session Bridge&lt;/strong&gt;&lt;/a&gt; — an open-source MV3 Chrome extension and a hardened loopback relay that safely replicates your live browser session into a local &lt;a href="https://lightpanda.io" rel="noopener noreferrer"&gt;Lightpanda&lt;/a&gt; headless runtime via CDP. Zero credentials typed, zero secrets exposed to LLMs.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;If you build AI agents that do real work on the modern web, you know the exact wall every developer hits: &lt;strong&gt;authentication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The moment your agent needs to check an AWS billing console, inspect private logs on a SaaS dashboard, or pull data from an internal portal, the demo breaks down. Modern apps don’t live on basic auth; they sit behind Google OAuth, SSO federations, hardware passkeys, and biometric 2FA prompts. &lt;/p&gt;

&lt;p&gt;A headless browser cannot tap your security key, answer your phone's authenticator app, or blink at a FaceID prompt. &lt;/p&gt;

&lt;p&gt;Faced with this, most builders resort to terrible compromises:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hardcoding passwords into agent prompts or &lt;code&gt;.env&lt;/code&gt; files&lt;/strong&gt; (which leak into LLM context logs, chat histories, and traces).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy-pasting session cookies manually into configs&lt;/strong&gt; (which expire quickly and offer zero scoping or SSRF protection).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Driving the user’s primary browser via raw CDP&lt;/strong&gt; (which disrupts real work, risks hijacking other tabs, and introduces scary blast radiuses).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;strong&gt;Lightpanda Session Bridge&lt;/strong&gt; is built on a different philosophy: &lt;strong&gt;keep the authentication ritual with the human, and hand the agent an isolated, authenticated runtime.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-----------------------------------------------------------------------+
|  HUMAN BROWSER (Chrome / Edge / Comet)                                |
|  User logs in via Passkey / Google OAuth / 2FA                        |
|                                                                       |
|  [ 🐼 Sync Tab ] ---&amp;gt; Extension MV3 extracts strictly scoped cookies   |
+---------------------------------------+-------------------------------+
                                        | POST 127.0.0.1:8765
                                        | (with X-Bridge-Token + CORS check)
                                        v
+-----------------------------------------------------------------------+
|  LOCAL BRIDGE RELAY (relay/server.py)                                 |
|  - Loopback-only (127.0.0.1)                                          |
|  - IdP &amp;amp; Private IP blocking (anti-SSRF + DNS cache)                  |
|  - Cookie normalization (__Host-, __Secure-, RFC 6265bis)             |
+---------------------------------------+-------------------------------+
                                        | WebSocket CDP Protocol
                                        v
+-----------------------------------------------------------------------+
|  HEADLESS RUNTIME (Lightpanda in WSL2 @ :9222)                        |
|  - Isolated V8 / Zig engine                                           |
|  - Instant DOM / JS evaluation                                        |
|                                                                       |
|  AI Agent reads data via SDK (lightpanda_client.py)                   |
+-----------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Session Transfer Beats Credential Sharing
&lt;/h2&gt;

&lt;p&gt;Passwords and API tokens are the wrong unit of trust for agents. They grant permanent, unrestricted access. Once an LLM agent has your password, you have zero guarantee where that string will travel — subagent handoffs, external telemetry, debug dumps, or third-party inference providers.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;session cookie&lt;/strong&gt; is fundamentally safer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is &lt;strong&gt;ephemeral&lt;/strong&gt; and expires automatically.&lt;/li&gt;
&lt;li&gt;It can be &lt;strong&gt;instantly revoked&lt;/strong&gt; from your main browser simply by logging out.&lt;/li&gt;
&lt;li&gt;It is &lt;strong&gt;strictly scoped&lt;/strong&gt; to a single target origin.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the bridge, you authenticate once in your familiar browser. When you click &lt;strong&gt;Sync&lt;/strong&gt;, the extension packages only the cookies relevant to that specific origin and pushes them into an isolated headless browser instance. &lt;/p&gt;

&lt;p&gt;The LLM never sees your credentials. The relay never logs a cookie value. The machine gets straight to work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: The Three Layers
&lt;/h2&gt;

&lt;p&gt;The architecture is purposely minimal, robust, and audit-friendly:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Chrome Extension (Manifest V3)
&lt;/h3&gt;

&lt;p&gt;Designed with a clean, dark Quota Glass interface. It requires only standard scoped permissions (&lt;code&gt;activeTab&lt;/code&gt;, &lt;code&gt;cookies&lt;/code&gt;, &lt;code&gt;storage&lt;/code&gt;). When clicked, it captures cookies for the active domain, normalizes them, and prepares a transfer envelope.&lt;/p&gt;

&lt;p&gt;On first launch, it executes an &lt;strong&gt;auto-pairing handshake&lt;/strong&gt; (&lt;code&gt;/v1/bootstrap&lt;/code&gt;) with the local relay, storing a shared cryptographic token in local isolated storage without requiring manual copy-pasting.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Hardened Loopback Relay (&lt;code&gt;relay/server.py&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Listening exclusively on &lt;code&gt;127.0.0.1:8765&lt;/code&gt;, the relay is the security gateway. It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enforces strict origin matching.&lt;/li&gt;
&lt;li&gt;Translates browser cookie structures into Lightpanda-compliant DevTools protocol messages (including converting lowercase &lt;code&gt;sameSite&lt;/code&gt; tags like &lt;code&gt;lax&lt;/code&gt; to Lightpanda's PascalCase &lt;code&gt;Lax&lt;/code&gt; to avoid &lt;code&gt;-31998 InvalidEnumTag&lt;/code&gt; CDP crashes).&lt;/li&gt;
&lt;li&gt;Normalizes &lt;code&gt;__Host-&lt;/code&gt; and &lt;code&gt;__Secure-&lt;/code&gt; cookie prefixes per RFC 6265bis.&lt;/li&gt;
&lt;li&gt;Forwards cookies over CDP WebSockets to the headless engine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Lightpanda Headless Engine
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://lightpanda.io" rel="noopener noreferrer"&gt;Lightpanda&lt;/a&gt; is an ultra-fast, open-source headless browser built in Zig with V8, purpose-built for AI automation. Running Lightpanda in WSL2 isolates it from your Windows host environment while keeping execution blindingly fast with tiny memory footprints compared to full Chromium.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Security Checklist: Defending Against SSRF &amp;amp; Local Leaks
&lt;/h2&gt;

&lt;p&gt;Treating a local HTTP relay as a trusted boundary is how local privilege escalation happens. Because the relay accepts cookies, I designed it as an adversarial SSRF surface from day one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Zero Logging:&lt;/strong&gt; Cookie names and values are never printed to stdout, logged to disk, or saved in history.&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Loopback Only:&lt;/strong&gt; Hardcoded binding to &lt;code&gt;127.0.0.1&lt;/code&gt;. No routable network interfaces exposed.&lt;/li&gt;
&lt;li&gt;🚫 &lt;strong&gt;Strict Identity-Provider (IdP) Blacklisting:&lt;/strong&gt; The relay automatically rejects transfers intended for identity roots — &lt;code&gt;accounts.google.com&lt;/code&gt;, &lt;code&gt;login.microsoftonline.com&lt;/code&gt;, &lt;code&gt;appleid.apple.com&lt;/code&gt;, &lt;code&gt;github.com&lt;/code&gt;, and &lt;code&gt;auth0.com&lt;/code&gt; cannot be targeted.&lt;/li&gt;
&lt;li&gt;🛑 &lt;strong&gt;SSRF IP &amp;amp; DNS Verification:&lt;/strong&gt; Target domains must resolve to valid public IPv4/IPv6 addresses. Localhost aliases, &lt;code&gt;127.0.0.0/8&lt;/code&gt;, private subnets (&lt;code&gt;10.0.0.0/8&lt;/code&gt;, &lt;code&gt;192.168.0.0/16&lt;/code&gt;), and wildcard DNS tools like &lt;code&gt;nip.io&lt;/code&gt; are categorically dropped. DNS lookups are pinned with a 60-second cache to prevent time-of-check to time-of-use (TOCTOU) rebinding.&lt;/li&gt;
&lt;li&gt;🔑 &lt;strong&gt;Origin-Restricted Handshake:&lt;/strong&gt; Web pages or rogue local CLI scripts attempting to query &lt;code&gt;/v1/bootstrap&lt;/code&gt; receive an immediate &lt;code&gt;403 Forbidden&lt;/code&gt;. Only callers presenting a legitimate &lt;code&gt;chrome-extension://&lt;/code&gt; Origin header can receive the pairing secret.&lt;/li&gt;
&lt;li&gt;🧪 &lt;strong&gt;Live Verified:&lt;/strong&gt; Backed by 9 automated security test suites, validating private IP rejections, CDP payload structures, and token enforcement.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How AI Agents Interact With The Session
&lt;/h2&gt;

&lt;p&gt;Once the session is synced into Lightpanda, your agent script uses the bundled lightweight Python SDK (&lt;code&gt;lightpanda_client.py&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;lightpanda_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LightpandaClient&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Connect to Lightpanda CDP runtime
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LightpandaClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cdp_ws&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ws://127.0.0.1:9222/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Attach to or spawn the target page (already carrying the synced session)
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach_or_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://app.example.com/dashboard&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Evaluate JavaScript inside the authenticated session context
&lt;/span&gt;&lt;span class="n"&gt;dashboard_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;(() =&amp;gt; {
    return {
        user: document.querySelector(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.user-profile&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)?.textContent?.trim(),
        quotaRemaining: document.querySelector(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.quota-display&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)?.textContent?.trim(),
        csrfToken: document.querySelector(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;meta[name=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;csrf-token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)?.content
    };
})()&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent operating as: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dashboard_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Remaining quota: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dashboard_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;quotaRemaining&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent never asked for a password. The user never risked account takeover.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quickstart (Under 3 Minutes)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clone &amp;amp; Install Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Raknaos/lightpanda-session-bridge.git
&lt;span class="nb"&gt;cd &lt;/span&gt;lightpanda-session-bridge
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Launch Lightpanda &amp;amp; The Bridge Relay
&lt;/h3&gt;

&lt;p&gt;In two PowerShell terminals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;/scripts/start-lightpanda.ps1&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c"&gt;# Runs Lightpanda CDP on 127.0.0.1:9222 (WSL2)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;/scripts/start-relay.ps1&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c"&gt;# Starts relay on 127.0.0.1:8765&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Load the Extension
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;code&gt;chrome://extensions&lt;/code&gt; in Chrome, Comet, or Edge.&lt;/li&gt;
&lt;li&gt;Toggle &lt;strong&gt;Developer Mode&lt;/strong&gt; on.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Load unpacked&lt;/strong&gt; and select the repository's &lt;code&gt;extension/&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Open the popup once while the relay runs — it auto-pairs instantly.&lt;/li&gt;
&lt;li&gt;Navigate to any authenticated site, click the 🐼 icon, and hit &lt;strong&gt;Sync Session&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Honest Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Human-in-the-loop:&lt;/strong&gt; You must click &lt;strong&gt;Sync&lt;/strong&gt; once per session. This is an intentional security design choice, but it means this is built for supervised agent workflows, not headless server farms starting from scratch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local machine only:&lt;/strong&gt; The relay strictly refuses remote connections. Your agent script and your browser must reside on the same workstation or dev environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zig / WSL2 dependency:&lt;/strong&gt; Lightpanda currently runs most smoothly on Linux/WSL2; the PowerShell scripts manage this automatically for Windows setups.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It Out &amp;amp; Contribute
&lt;/h2&gt;

&lt;p&gt;The project is fully open-source under the MIT license:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/Raknaos/lightpanda-session-bridge" rel="noopener noreferrer"&gt;Raknaos/lightpanda-session-bridge&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;Project Landing Page:&lt;/strong&gt; &lt;a href="https://raknaos.github.io/lightpanda-session-bridge/" rel="noopener noreferrer"&gt;raknaos.github.io/lightpanda-session-bridge&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🏷️ &lt;strong&gt;Release v0.3.4 (Zip Packaged):&lt;/strong&gt; &lt;a href="https://github.com/Raknaos/lightpanda-session-bridge/releases/tag/v0.3.4" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building autonomous agents that need to navigate authenticated environments safely, take it for a spin and star the repo! Feedback, issues, and PRs are warmly welcome.&lt;/p&gt;

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