Skip to main content

Overview

Session Isolation is ContextFort’s core security feature that prevents agents from accessing your personal accounts. When an agent enters a website, ContextFort automatically swaps your human cookies with agent-specific cookies, ensuring complete session separation.
Critical Security Feature: Without session isolation, agents could access your Gmail, bank accounts, or any logged-in service.

The Session Swap Process

  1. Agent Detected: ContextFort detects agent mode activation (⌛ emoji in tab group)
  2. Capture Human Session: All cookies for the domain are captured and stored as “human profile”
  3. Clear Domain Cookies: All cookies are removed from the browser
  4. Restore Agent Session: If an agent profile exists, those cookies are restored
  5. Page Reload: Tab reloads with agent session active

Capturing Cookies

ContextFort captures all cookies for a domain, including subdomain cookies:
chrome-extension/background.js
import psl from 'psl';

function getRootDomain(hostname) {
  const parsed = psl.parse(hostname);
  return parsed.domain;
}

async function captureCookies(domain) {
  const rootDomain = getRootDomain(domain);
  const cookies = await chrome.cookies.getAll({ domain: rootDomain });
  const subdomainCookies = await chrome.cookies.getAll({ domain: '.' + rootDomain });

  // Merge and deduplicate
  const allCookies = [...cookies];
  for (const cookie of subdomainCookies) {
    const exists = allCookies.some(c =>
      c.name === cookie.name && c.domain === cookie.domain && c.path === cookie.path
    );
    if (!exists) {
      allCookies.push(cookie);
    }
  }
  return allCookies;
}
Why capture subdomain cookies? Many services use multiple subdomains (e.g., www.example.com, api.example.com, auth.example.com). All must be captured for complete session isolation.

Clearing Cookies

chrome-extension/background.js
async function clearCookies(domain) {
  const cookies = await captureCookies(domain);
  for (const cookie of cookies) {
    const protocol = cookie.secure ? 'https://' : 'http://';
    const cookieDomain = cookie.domain.startsWith('.') 
      ? cookie.domain.slice(1) 
      : cookie.domain;
    const url = `${protocol}${cookieDomain}${cookie.path}`;
    await chrome.cookies.remove({ url, name: cookie.name });
  }
}

Restoring Cookies

chrome-extension/background.js
async function restoreCookies(cookies) {
  for (const cookie of cookies) {
    const { hostOnly, session, storeId, ...cookieData } = cookie;
    const protocol = cookie.secure ? 'https://' : 'http://';
    const cookieDomain = cookie.domain.startsWith('.') 
      ? cookie.domain.slice(1) 
      : cookie.domain;
    const url = `${protocol}${cookieDomain}${cookie.path}`;

    await chrome.cookies.set({
      url,
      ...cookieData,
      expirationDate: session ? undefined : cookieData.expirationDate
    });
  }
}

Session Profiles

Storage Structure

Session profiles are stored in Chrome’s local storage:
{
  "sessionProfiles": {
    "example.com": {
      "human": {
        "domain": "example.com",
        "capturedAt": "2025-02-28T12:34:56.789Z",
        "cookies": [
          {
            "name": "session_id",
            "value": "abc123xyz",
            "domain": ".example.com",
            "path": "/",
            "secure": true,
            "httpOnly": true,
            "sameSite": "lax",
            "expirationDate": 1740000000
          }
        ]
      },
      "agent": {
        "domain": "example.com",
        "capturedAt": "2025-02-28T13:00:00.000Z",
        "cookies": [
          {
            "name": "session_id",
            "value": "def456uvw",
            "domain": ".example.com",
            "path": "/",
            "secure": true,
            "httpOnly": true,
            "sameSite": "lax",
            "expirationDate": 1740000000
          }
        ]
      }
    }
  }
}

Profile Management

chrome-extension/background.js
async function saveSessionProfile(domain, profileType, sessionData) {
  const result = await chrome.storage.local.get(['sessionProfiles']);
  const profiles = result.sessionProfiles || {};
  if (!profiles[domain]) profiles[domain] = {};
  profiles[domain][profileType] = sessionData;
  await chrome.storage.local.set({ sessionProfiles: profiles });
}
chrome-extension/background.js
async function loadSessionProfile(domain, profileType) {
  const result = await chrome.storage.local.get(['sessionProfiles']);
  const profiles = result.sessionProfiles || {};
  if (profiles[domain] && profiles[domain][profileType]) {
    return profiles[domain][profileType];
  }
  return null;
}
chrome-extension/background.js
async function deleteSessionProfile(domain, profileType) {
  const result = await chrome.storage.local.get(['sessionProfiles']);
  const profiles = result.sessionProfiles || {};

  if (profiles[domain] && profiles[domain][profileType]) {
    delete profiles[domain][profileType];
    if (!profiles[domain].human && !profiles[domain].agent) {
      delete profiles[domain]; // Clean up empty domain
    }
    await chrome.storage.local.set({ sessionProfiles: profiles });
    return true;
  }
  return false;
}

Login Flow for New Domains

When an agent visits a domain with no saved agent profile:

In-Page Notification

chrome-extension/content.js
function showLoginRequiredNotification(domain, phase = 1) {
  const notification = document.createElement('div');
  notification.id = 'contextfort-login-notification';
  notification.style.cssText = `
    position: fixed;
    bottom: 20px;
    right: 20px;
    min-width: 360px;
    background: #1a1a1a;
    border-radius: 12px;
    padding: 20px;
    z-index: 2147483647;
  `;

  if (phase === 1) {
    // Phase 1: Initial prompt
    message.innerHTML = `
      No saved agent session for <strong>${domain}</strong><br><br>
      Your session has been cleared. You need to login manually for the agent to use this site.
    `;
    // Show "Ok, I'll log in" button
  } else {
    // Phase 2: After user acknowledges
    message.innerHTML = `
      Please login, then click "I've Logged In".<br><br>
      Or click "Restore My Session" to get your cookies back.
    `;
    // Show "I've Logged In" and "Restore My Session" buttons
  }
}

Login Flow Steps

1

Agent attempts to access domain

Agent navigates to example.com where user is logged in
2

Human cookies captured

ContextFort captures all human cookies and clears them from browser
3

Login prompt appears

In-page notification appears: “No saved agent session for example.com”
4

User logs in manually

User enters agent credentials and completes login flow
5

User clicks 'I've Logged In'

New agent cookies are captured and saved as agent profile
6

Page reloads with agent session

Agent can now continue with isolated session

Restore Human Session

If the user decides not to create an agent profile, they can restore their human session:
chrome-extension/background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'RESTORE_BUTTON_CLICKED') {
    const domain = message.domain;
    const tabId = sender.tab.id;

    (async () => {
      const humanSession = await loadSessionProfile(domain, 'human');
      if (humanSession) {
        await clearCookies(domain);
        await restoreCookies(humanSession.cookies);
        await chrome.tabs.reload(tabId);
      }
    })();
  }
});

Swapping Back to Human Session

When the agent stops (⌛ → ✅ transition), ContextFort swaps all domains back to human sessions:
chrome-extension/background.js
async function swapAllDomainsToHuman(tabId, groupId) {
  console.log("swapping all domains to human");
  const swappedDomains = swappedDomainsPerSession.get(groupId);
  if (!swappedDomains || swappedDomains.size === 0) return true;
  
  for (const domain of swappedDomains) {
    // Save current agent session
    const agentSession = await captureFullSession(domain);
    if (agentSession) await saveSessionProfile(domain, 'agent', agentSession);
    
    // Restore human session
    const humanSession = await loadSessionProfile(domain, 'human');
    await clearCookies(domain);
    if (humanSession) await restoreCookies(humanSession.cookies);
  }

  // Reload current tab if it's on a swapped domain
  const tab = await chrome.tabs.get(tabId);
  const currentDomain = getRootDomain(new URL(tab.url).hostname);
  if (currentDomain && swappedDomains.has(currentDomain)) {
    await chrome.tabs.reload(tabId);
  }
  
  swappedDomainsPerSession.delete(groupId);
  return true;
}

Domain Tracking

ContextFort tracks which domains have been swapped per session:
chrome-extension/background.js
const swappedDomainsPerSession = new Map();
// Example:
// swappedDomainsPerSession = Map {
//   123 => Set { "example.com", "api.example.com", "docs.example.com" },
//   456 => Set { "github.com" }
// }
Each tab group (agent session) has its own set of swapped domains. This allows multiple agent sessions to run simultaneously with different session profiles.

Managing Session Profiles

View and manage all saved session profiles in the Dashboard:

View All Profiles

chrome.runtime.sendMessage(
  { type: 'VIEW_STORED_SESSIONS' },
  (profiles) => {
    console.log('All session profiles:', profiles);
  }
);

Delete a Profile

chrome.runtime.sendMessage(
  {
    type: 'DELETE_SESSION_PROFILE',
    domain: 'example.com',
    profileType: 'agent'
  },
  (success) => {
    console.log('Profile deleted:', success);
  }
);

Security Considerations

Cookie Encryption

All session profiles are stored in Chrome’s local storage, which is encrypted at rest by Chrome’s built-in encryption.

No Cloud Sync

Session profiles are NEVER synced to cloud or transmitted externally. All data stays on your local machine.

Isolation Guarantee

Once swapped, agents cannot access human cookies unless explicitly restored by the user.

Per-Domain Profiles

Each domain has separate human and agent profiles, ensuring no cross-contamination.
Cookie Expiration: If agent cookies expire, the agent will be logged out and require re-authentication. ContextFort does not refresh expired cookies automatically.

Troubleshooting

Agent session not persisting

Problem: Agent gets logged out on every page reload Solution: Ensure you clicked “I’ve Logged In” after manually logging in. This saves the agent profile.

Human session lost after agent stops

Problem: After agent stops, human session is not restored Solution: This can happen if human cookies expired or were cleared externally. Use “Restore My Session” during the login prompt to preserve your human session.

Multiple domains require login

Problem: Agent visits 5 different sites and all require manual login Solution: This is expected behavior on first use. ContextFort will save all 5 agent profiles for future sessions.

Next Steps

Blocking Rules

Configure URL and domain blocking to prevent context mixing

Visibility

Monitor all agent sessions and cookie swaps in real-time

Screenshots

See when screenshots are captured during session swaps

Dashboard

Manage session profiles in the Dashboard UI

Build docs developers (and LLMs) love