Skip to main content
The palyra-browserd binary is a specialized microservice responsible for orchestrating headless Chromium instances. It provides a high-level gRPC interface (BrowserService) that abstracts complex browser interactions into atomic agent-friendly actions like clicking, typing, and observing page state. It is designed to run either as a sidecar to the main palyrad daemon or as a standalone service.

Service Architecture

The architecture is built around a central BrowserRuntimeState which manages the lifecycle of multiple browser sessions, each potentially backed by a distinct Chromium process or tab.

Component Overview

ComponentResponsibility
BrowserServiceImplImplements the gRPC service defined in browser.proto. Handles request authorization and dispatches to the runtime.
BrowserRuntimeStateThe “brain” of the service. Manages the session registry, configuration budgets, and the state store.
HeadlessBrowserIntegration with the headless_chrome crate to control the underlying Chromium engine.
PersistedStateStoreHandles encrypted storage of browser profiles and session snapshots to disk.
ChromiumSessionProxyA per-session SOCKS5 proxy used to enforce egress security and target validation.

System Data Flow

The following diagram illustrates how a request from the palyra-daemon (or CLI) flows through palyra-browserd to the Chromium engine. Request Execution Flow Sources: crates/palyra-browserd/src/transport/grpc/service.rs#14-14, crates/palyra-browserd/src/engine/chromium.rs#71-75, crates/palyra-browserd/src/security/target_validation.rs#184-187

gRPC API (browser.proto)

The service communicates via Protobuf over gRPC, typically listening on port 7543.

Key RPC Methods

Session Lifecycle and Budgets

Sessions are identified by ULIDs and are governed by a SessionBudget. This budget prevents runaway agents from consuming excessive memory or performing too many actions.
Budget FieldDefault ValueDescription
max_navigation_timeout_ms15,000msMax time for a page load.
max_screenshot_bytes256 KBCap on image data returned.
max_actions_per_session256Total interactions allowed.
max_tabs_per_session32Concurrent tabs per session.
Sources: crates/palyra-browserd/src/lib.rs#85-104, crates/palyra-browserd/src/transport/grpc/service.rs#107-161

Chromium Integration and Security

palyra-browserd uses the headless_chrome crate but wraps it in several security layers to ensure agent safety.

Target Validation and Egress Control

Every network request made by the browser is intercepted via a local SOCKS5 proxy (ChromiumSessionProxy). This proxy performs “Target Validation” to prevent SSRF (Server-Side Request Forgery) and unauthorized access to local infrastructure.

Download Handling

Downloads are strictly sandboxed. When an agent triggers a download (e.g., via Click), the file is captured into a DownloadSandboxSession.
  1. Quarantine: Files are initially placed in a quarantine directory.
  2. Validation: The service checks DOWNLOAD_ALLOWED_EXTENSIONS (e.g., .pdf, .csv, .json) and DOWNLOAD_ALLOWED_MIME_TYPES. crates/palyra-browserd/src/lib.rs#153-162
  3. Storage: If valid, the file is moved to an allowlist directory within a TempDir unique to the session. crates/palyra-browserd/src/domain/downloads.rs#20-36

Implementation Detail: State Persistence

palyra-browserd supports persistent profiles, allowing agents to maintain login sessions across restarts. State Persistence Architecture State is encrypted using CHACHA20_POLY1305 with a key derived from PALYRA_BROWSERD_STATE_ENCRYPTION_KEY. The PersistedStateStore manages the profiles.enc registry and individual session blobs. Sources: crates/palyra-browserd/src/lib.rs#123-133, crates/palyra-browserd/src/transport/grpc/service.rs#75-91, crates/palyra-browserd/src/support/tests.rs#3-7

CLI Interaction

The palyra-cli provides a comprehensive interface for managing browserd. Sources: crates/palyra-cli/src/commands/browser.rs#160-230, crates/palyra-cli/src/args/browser.rs#4-63