Security

A tool that drives your logged-in browser deserves a paranoid design. reins keeps the attack surface small by having no cloud half at all: the pieces only ever talk to each other, on your machine.

Network surface

  • Everything binds 127.0.0.1; neither the daemon nor the extension is reachable from the network.
  • /rpc and the other daemon endpoints validate the Host header, so web pages can't reach the daemon even through rebound DNS.
  • The daemon accepts extension WebSocket connections only from exact allowlisted chrome-extension://<id> origins. Browsers stamp that header themselves; pages and other extensions can't forge it. Dev builds are added explicitly with reins allow <id>.

Visibility and control

  • Chrome shows its native "is being debugged" banner whenever the extension is attached to a tab, so you always know when an agent is acting.
  • The toolbar popup's Disconnect toggle severs the daemon connection instantly.
  • Nothing happens in the background: the extension only acts on explicit commands sent through the CLI on your machine.

Per-site permissions

  • Every host resolves to a tier — deny, read, or full — and the extension enforces it before any command touches a tab. The check runs inside the extension, so nothing speaking the protocol — the CLI, the daemon, or any other local client — can skip or loosen it.
  • Grants happen only in the extension popup, a user gesture an agent can't perform from the shell. The CLI (reins policy) can view and tighten the policy, never loosen it.
  • The shipped default is full everywhere — today's behavior — so tightening is opt-in. deny also redacts the site's tabs from reins tabs.

The full model — tiers, wildcard rules, matching precedence — is on the Site permissions page.

Trust boundary

The tiers contain the agent you invited in; they are not a defense against other software on your machine. Anything already running as your OS user sits inside the trust boundary — it could talk to the daemon or rewrite the policy store directly, and no browser automation tool's permission model survives local malware. The honest write-up — what the tiers protect against, what they can't, prompt injection, and a hardening checklist — is the threat model (SECURITY.md).

Audit trail

  • Every command the daemon executes — and every one the policy blocks — appends one structured line (timestamp, command, browser, tab, host, tier, outcome, duration) to ~/.reins/logs/audit-YYYY-MM-DD.jsonl. reins audit renders the trail; --denied shows only what policy blocked.
  • Value-bearing params — typed text, fill values, eval code, CDP payloads — are redacted before the line is written, so the trail never stores what the agent typed, only that it typed.
  • Audit files are pruned after 30 days. Writes are best-effort: a full disk never blocks a command.

Data handling

  • Page content and tab metadata are read via the Chrome DevTools Protocol only when your local daemon asks, and are sent only to that daemon over localhost.
  • No analytics, no telemetry, no tracking, no remote servers, no remote code.
  • The only stored state is the extension's own settings (auto-connect, cached daemon port, connection status) and your site-permission policy, kept in chrome.storage on your device.

The full policy lives at reins.tech/privacy. The code is MIT-licensed and auditable at github.com/karnstack/reins.