Streambert Electron Session Architecture Isolation: Multi-Partition Browser Security

Streambert isolates its main UI, video player, and trailer preview into three separate Chromium sessions using Electron's session.fromPartition() API, ensuring security through sandboxing while enabling specialized ad-blocking and media interception per context.

The truelockmc/streambert repository implements a sophisticated Electron session architecture that separates concerns across distinct browser partitions. This isolation strategy prevents cross-context contamination while allowing the app to apply aggressive content policies—such as header stripping and URL interception—only where needed. By leveraging lazy initialization and persistent storage policies, Streambert maintains performance without sacrificing the security boundaries between general browsing and untrusted media streams.

Understanding the Three-Partition Architecture

Streambert creates three distinct session partitions, each serving a specific functional domain within the application:

  • defaultSession – Handles general web browsing, settings, library views, and TMDB API requests. This session operates in-memory and clears all data when the app quits.
  • persist:player – Dedicated to video playback. This persistent session stores cookies, cache, and shader data on disk while applying aggressive ad-blocking and media URL interception for .m3u8 and .vtt streams.
  • persist:trailer – Manages trailer preview windows with a narrower scope. Like the player session, it persists data to disk but only blocks ad hosts without intercepting media streams.

This separation ensures that malicious scripts or tracking mechanisms encountered during video playback remain confined to the player partition and cannot access the main window's state or credentials.

Lazy Session Initialization and Setup

Rather than allocating resources at startup, Streambert defers session creation until actually needed. In index.js, the application listens for the did-attach-webview event to trigger lazy initialization:

// index.js – lines 49-57
mainWindow.webContents.on('did-attach-webview', (_, wc) => {
  if (!sessionsConfigured) {
    sessionsConfigured = true;
    const playerSession  = session.fromPartition('persist:player');
    const trailerSession = session.fromPartition('persist:trailer');
    setupSession(playerSession, trailerSession);
  }
  // …track webview IDs for later cleanup
});

Source: index.js:49-57

The setupSession() function configures both partitions simultaneously, applying shared policies like custom User-Agent strings while preparing individual webRequest handlers for each context.

Per-Session Security Policies and Header Manipulation

Stripping Security Headers for Embedded Content

To prevent content security policy (CSP) and framing restrictions from breaking embedded video players, Streambert strips critical headers from responses within the player and trailer sessions. The setupSession() function in index.js registers an onHeadersReceived handler that removes X-Frame-Options and Content-Security-Policy headers:

// index.js – lines 24-32
function setupSession(playerSession, trailerSession) {
  // Common UA for both sessions
  const UA = 'Mozilla/5.0 (Windows NT 10.0; … Chrome/124.0.0.0 Safari/537.36';
  playerSession.setUserAgent(UA);
  trailerSession.setUserAgent(UA);

  // Strip X-Frame-Options & CSP from all responses
  const stripHeaders = (details, cb) => {
    const hdr = { ...details.responseHeaders };
    for (const k of Object.keys(hdr)) {
      const low = k.toLowerCase();
      if (low === 'x-frame-options' || low === 'content-security-policy')
        delete hdr[k];
    }
    cb({ responseHeaders: hdr });
  };
  playerSession.webRequest.onHeadersReceived({ urls: ['*://*/*'] }, stripHeaders);
  trailerSession.webRequest.onHeadersReceived({ urls: ['*://*/*'] }, stripHeaders);

Source: index.js:24-32

Differentiated Ad-Blocking and Media Interception

The architecture applies distinct filtering rules based on session purpose. The trailer session blocks only known ad hosts, while the player session extends this to intercept streaming manifests and subtitle files:

// index.js – lines 38-46
trailerSession.webRequest.onBeforeRequest({ urls: BLOCKED_HOSTS }, (_, cb) => cb({ cancel: true }));

playerSession.webRequest.onBeforeRequest(
  { urls: [...BLOCKED_HOSTS, '*://*/*.m3u8*', '*://*/*.vtt*'] },
  (details, cb) => {
    // block non-media URLs, record stats, otherwise forward to renderer
  }
);

Source: index.js:38-46

Intercepted media URLs are forwarded to the renderer process, where src/ipc/subtitles.js extracts language metadata from .vtt files without exposing the main browsing context to potentially malicious streaming domains.

Cache Management and Storage Isolation

Session-Scoped Caching Strategies

Each partition maintains independent cache quotas and storage policies. The default session implements long-lived caching for TMDB images to reduce API load:

// index.js – lines 33-42
session.defaultSession.webRequest.onHeadersReceived(
  { urls: ['*://image.tmdb.org/*'] },
  (details, cb) => {
    const h = { ...details.responseHeaders };
    h['cache-control'] = ['public, max-age=604800, immutable']; // 7 days
    delete h['pragma']; delete h['expires'];
    cb({ responseHeaders: h });
  },
);

Source: index.js:33-42

Automated Cleanup Workflows

When playback stops, Streambert aggressively purges the player session to free memory and remove tracking artifacts. The player-stopped IPC event triggers targeted cache clearing:

// index.js – lines 47-55
ipcMain.on('player-stopped', () => {
  // …destroy webContents…
  const ps = session.fromPartition('persist:player');
  ps.clearCache().catch(() => {});
  ps.clearStorageData({ storages: ['shadercache', 'cachestorage'] }).catch(() => {});
  if (typeof global.gc === 'function') global.gc();
});

Source: index.js:47-55

For global maintenance, src/ipc/downloads.js provides utilities to clear all sessions simultaneously:

// src/ipc/downloads.js – lines 891-894
const sessions = [
  session.defaultSession,
  session.fromPartition('persist:player'),
  session.fromPartition('persist:trailer'),
];
await Promise.all(sessions.map(s => s.clearCache()));
await Promise.all(sessions.map(s => s.clearStorageData({ storages: ['shadercache','serviceworkers','cachestorage'] })));

Source: downloads.js:891-894

Practical Implementation: Creating an Isolated Player Session

To implement similar isolation in your own Electron application, acquire partition-specific sessions and configure request handlers before attaching webviews:

const { session } = require('electron');

// 1️⃣  Acquire (or create) the player partition
const playerSession = session.fromPartition('persist:player');

// 2️⃣  Set a custom User-Agent
playerSession.setUserAgent(
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
);

// 3️⃣  Block ads & intercept media URLs
playerSession.webRequest.onBeforeRequest(
  { urls: ['*://*/*.m3u8*', '*://*/*.vtt*', '*://adservice.google.com/*'] },
  (details, cb) => {
    const isMedia = details.url.includes('.m3u8') || details.url.includes('.vtt');
    if (!isMedia) return cb({ cancel: true });   // block ads
    cb({});                                     // allow media
  }
);

// 4️⃣  Clear caches when playback finishes
(async () => {
  await playerSession.clearCache();
  await playerSession.clearStorageData({ storages: ['shadercache', 'cachestorage'] });
})();

This pattern ensures that media-heavy operations remain isolated from your application's main browser context, exactly as implemented in the Streambert electron session architecture isolation strategy.

Summary

  • Three isolated partitions (default, persist:player, persist:trailer) prevent cross-context security breaches while optimizing cache strategies per use case.
  • Lazy initialization in index.js defers session creation until the first webview attaches, conserving resources during startup.
  • Partition-specific webRequest handlers enable surgical header manipulation and URL interception without affecting the main UI's security posture.
  • Automated cleanup workflows in both index.js and src/ipc/downloads.js prevent memory bloat by clearing shader caches, HTTP caches, and service workers when playback ends or on user request.
  • Persistent vs. in-memory storage policies balance performance (surviving navigation) against privacy (clearing sensitive data on exit).

Frequently Asked Questions

What is Electron session isolation and why does Streambert use it?

Electron session isolation refers to the practice of creating separate session partitions using session.fromPartition(), where each partition maintains independent cookies, caches, and storage contexts. Streambert uses this architecture to sandbox the video player and trailer preview from the main application window, ensuring that ad trackers, malicious scripts, or caching issues in media streams cannot compromise the main UI or access sensitive user data.

Why does Streambert implement lazy session initialization?

Streambert defers session creation until the did-attach-webview event fires (lines 49-57 in index.js) to avoid allocating unnecessary Chromium processes and storage directories during application startup. This approach improves cold-start performance and ensures that persistent partitions are only created when the user actually initiates video playback or trailer viewing.

How does Streambert prevent ads from affecting the main UI?

By routing video content through the persist:player and persist:trailer partitions while keeping general browsing in the defaultSession, Streambert confines ad-blocking filters and header-stripping policies to isolated contexts. The onBeforeRequest handlers in these specific sessions block tracking hosts and intercept media URLs, ensuring that advertisement networks never load in the same session context as the user's library or settings data.

Can users manually clear data from specific Streambert sessions?

Yes, through the download manager IPC handlers in src/ipc/downloads.js, the application exposes functionality to selectively clear cache and storage data from individual partitions. While the UI typically triggers automatic cleanup via the player-stopped event, manual clearing operations can target specific sessions (player, trailer, or default) without affecting the others, allowing granular privacy control.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →