Skip to main content

Overview

Session sharing is PassAgent’s flagship feature. It lets you share access to any web service — Netflix, Spotify, GitHub, anything — without revealing your password. Instead of giving someone your credentials, PassAgent creates a live cloud browser session, logs in on your behalf (optionally via AI), and gives the recipient a view-only or interactive link to the already-authenticated session. The recipient sees the logged-in service in their browser. They never see, intercept, or extract the password. When the session expires, the cloud browser is destroyed and all session data is gone.

Use cases

Share streaming services

Let a friend watch Netflix for 4 hours without sharing your password. The session is domain-locked — they cannot navigate away from Netflix.

Delegate account access

Give a contractor temporary access to your project dashboard. Enable view-only mode so they can see but not modify anything.

Demo an account

Show a client their account setup without handing over credentials. Watermark the session to deter screenshots.

Emergency access

Provide a family member access to a utility account during a crisis without any password exchange.

Session lifecycle

How it works

1

Owner creates a session share

From the vault, the owner selects a credential and chooses duration (15 min, 1 hour, 4 hours, or 8 hours), login method (AI agent or manual), and options like view-only mode and watermarking. The client decrypts the credential and sends the plaintext username/password to the server over HTTPS for the login step only.
2

Cloud browser session created

PassAgent provisions a Hyperbrowser cloud browser session with disableRecording: true for security. The session returns a livePreviewUrl — a public, token-authenticated URL that renders the browser viewport in an iframe. Up to 3 retry attempts are made with exponential backoff (2s, 4s, 6s delays).
3

AI agent logs in (or owner logs in manually)

If the AI agent method is selected, the LoginAgent uses a Claude-powered perceive-reason-act loop to fill the login form. The agent takes screenshots, reads the DOM, and executes up to 12 steps. If CAPTCHA or 2FA is detected, the session falls back to manual mode. If manual mode is selected, the owner is shown the live browser to log in themselves.
4

Security controls applied

After login, PassAgent applies domain locking (restricts navigation to the service’s domain), tab restriction (prevents opening new tabs), and optionally view-only mode and watermarking. The session status transitions to active.
5

Viewer accesses the session

The owner shares a link (/s/{shareToken}). The viewer clicks it, and PassAgent serves the Hyperbrowser live preview URL in an embedded iframe. A viewer token is issued with a 5-minute TTL, renewed by heartbeat.
6

Session expires or is revoked

When the duration elapses, the owner revokes, or the CDP heartbeat detects a dead connection, PassAgent terminates the provider session via API, closes the Playwright browser, and cleans up Redis state.

AI login agent

The LoginAgent class in lib/session-sharing/login-agent.ts automates the login process using the same architecture as PassAgent’s password reset agent. Login strategy:
  1. Navigate to the service URL
  2. Detect the login form (email/username + password fields)
  3. Enter the username, then the password (using [PASSWORD] placeholder in AI responses)
  4. Click the login/sign-in button or press Enter
  5. Detect success (dashboard/home page), failure (incorrect credentials), CAPTCHA, or 2FA
Provider fallback: If the Hyperbrowser HyperAgent is available, it attempts login first. On failure, the system falls back to the manual Claude-powered loop with claude-sonnet-4-20250514 and a maximum of 12 steps.
OutcomeNext action
successSession goes active, security controls applied
failedSession terminated, owner notified
captchaFalls back to manual login (owner completes CAPTCHA)
2fa_requiredFalls back to manual login (owner enters 2FA code)
max_stepsFalls back to manual login

Security controls

Domain locking

After login, lockToSingleTab() restricts the browser to the service’s domain using four enforcement layers:
Every 2 seconds, PassAgent evaluates window.location.href via Playwright and compares the hostname against the allowed domain using base domain extraction. If a violation is detected, the page is redirected back to the last known good URL. This catches address bar navigation, bookmarks, and JS redirects.
A context.on('page') handler automatically closes any new tabs the viewer opens. The event fires before the new page loads.
JavaScript injected into the page overrides window.open (returns null), intercepts link clicks to non-allowed domains (preventDefault), blocks form submissions to external domains, wraps location.assign and location.replace, and blocks Ctrl+T/Cmd+T/Ctrl+N/Ctrl+L keyboard shortcuts.
The restriction script is re-injected on every load event to handle SPA navigations and page reloads. A __passagentTabLock guard prevents double-injection.

View-only mode

When enabled, injectReadOnlyMode() creates a transparent overlay at z-index 2147483646 that blocks all pointer events. Keyboard input is intercepted on keydown, keypress, and keyup with preventDefault(). A “View Only” badge appears in the top-right corner. A MutationObserver prevents removal of the overlay by the page’s own scripts.

Watermarking

injectWatermark() renders a semi-transparent diagonal text pattern across the viewport at 6% opacity. The watermark text includes “PassAgent Session” and a truncated session ID. Pointer events pass through (pointer-events: none), and a MutationObserver prevents removal. The watermark deters screenshot sharing.

CDP heartbeat

Cloud browser providers terminate sessions after detecting inactivity. PassAgent maintains a CDP heartbeat every 20 seconds via page.evaluate(() => Date.now()), which generates real Chrome DevTools Protocol traffic. After 3 consecutive heartbeat failures, the session is considered dead and is cleaned up automatically.
The active session store uses globalThis to survive Next.js Hot Module Reloading. Without this, dev-mode file edits would drop all CDP connections and kill active sessions.

Duration and cost

DurationLabelEstimated cost
15 minQuick share~$0.03
60 min1 hour~$0.11
240 min4 hours~$0.41
480 min8 hours~$0.82
Costs are estimated at $0.17/minute (Hyperbrowser default rate) and can be overridden via the HYPERBROWSER_COST_PER_MIN_CENTS environment variable. The GET /api/session-sharing/estimate endpoint returns cost estimates for all supported providers.

Viewer tokens and tracking

Each viewer receives a unique token with a 5-minute TTL stored in Redis at session_viewer:{token}. The token is renewed by periodic heartbeat calls from the viewer’s browser. Viewer counts are tracked atomically using Redis INCR/DECR to prevent race conditions from concurrent access.

Auto-logout

When a session ends, PassAgent navigates the browser to the service’s known logout URL before termination. The logout-urls.ts registry maps 40+ services (Netflix, Spotify, GitHub, Slack, Amazon, etc.) to their logout endpoints. For unknown services, a fallback sequence tries common paths: /logout, /signout, /sign-out, /log-out, /api/auth/logout, and /api/logout.

Scheduled sessions

Sessions can be scheduled for future start times. Credentials are encrypted with SERVER_ENCRYPTION_KEY (AES-256-GCM) and stored in Redis with a TTL matching the scheduled time plus a 10-minute buffer. A cron job picks up scheduled sessions and starts the login process at the appropriate time.

API endpoints

MethodEndpointDescription
POST/api/session-sharingCreate a new session share (step-up auth required)
GET/api/session-sharingList your session shares
GET/api/session-sharing/estimateGet cost estimates for a duration
GET/api/session-sharing/[id]Get session details
GET/api/session-sharing/[id]/statusPoll session status
GET/api/session-sharing/[id]/eventsGet session event log
POST/api/session-sharing/heartbeatViewer heartbeat (renews token)
GET/api/session-sharing/viewerViewer access (returns live URL)
GET/api/session-sharing/access/[token]Token-based viewer entry point
GET/api/session-sharing/analyticsSession usage analytics
Session sharing requires HYPERBROWSER_API_KEY to be set in your environment. Without it, the Hyperbrowser provider cannot be initialized and session creation will fail.