Skip to content
Pagr

Security model

The cloud can ask your Mac to do nine things. Here they are.

Pagr is split in two on purpose: a hosted control plane that understands your messages, and an open-source bridge on your Mac that only accepts a short list of typed, signed commands. This page describes the boundary precisely.

  1. 01
    iMessage
    your phone
  2. 02
    Pagr control plane
    hosted · intent, routing, policy
  3. 03
    Bridge
    your Mac · open source
  4. 04
    Claude Code / Codex
    your Mac · your login

Guarantees

Typed commands only

The cloud can send exactly nine command types. Each one is a schema the bridge validates before it runs, and the list is in the public repo.

No remote shell

There is no shell.exec, no arbitrary file read or write, no process spawn. If a capability is not in the schema, the bridge cannot be asked to do it.

Code and credentials stay local

Pagr does not need to upload or persist a copy of your repository in its own cloud. Your Claude and Codex logins never leave your Mac; the bridge does not even read them.

Ed25519 device keys in Keychain

Pairing generates a keypair on your Mac. The private key lives in macOS Keychain. Every command the cloud sends is signed, bound to your device, expires, and cannot be replayed.

Outbound only

The bridge opens one outbound TLS WebSocket to Pagr's gateway. It listens on no ports.

Open source, Apache-2.0

Everything that runs on your machine is public. Read it, build it yourself, and pin the version you trust.

Command surface
9 typed commands · zod schemas · public repo
Remote shell
None. No exec, no file read, no file write, no spawn
Device identity
Ed25519 keypair, private key in macOS Keychain
Command auth
Server-signed · device-bound · expiring · nonce, no replay
Approval binding
Provider request ID + SHA-256 of the exact preview
Network
One outbound TLS WebSocket. No inbound port
Repository copies
None held or persisted in the Pagr cloud
Provider credentials
Stay on your Mac. The bridge does not read them
Bridge licence
Apache-2.0 · build it yourself · pin the version you trust
Revocation
Revoke a device from the dashboard; the bridge drops immediately

The complete command list

Defined as zod schemas in the public repo. If it is not in this table, the bridge cannot be asked to do it. There is no shell.exec, no file read, no file write, no process spawn.

CommandWhat it does
device.probeHealth and capability report from the bridge.
project.listRegistered project IDs and display names. Never paths.
project.removeForget a registered project.
agent.start_sessionStart Claude or Codex in a registered project with an instruction.
agent.send_instructionSteer or queue an instruction into a live session.
agent.stop_sessionStop a session.
agent.get_statusStatus for one session or all of them.
agent.respond_to_approvalAllow or deny one pending request, bound to its ID and a hash of the preview you saw.
settings.sync_public_policyPush your approval policy — auto-allow tier, timeout — to the device.
packages/protocol/src/schemas.ts on GitHub ↗

Device identity and signing

When you run pagr connect, the bridge generates an Ed25519 keypair locally. The private key is stored in macOS Keychain and never leaves the device; the public key is registered with your account during pairing.

The bridge opens a single outbound TLS WebSocket to Pagr’s gateway and proves its identity with a challenge signed by that key. It listens on no ports. Every command the gateway sends is signed by the server, bound to your device ID, carries an expiry and a nonce, and is rejected if it is malformed, expired, replayed, or addressed to another device.

Approvals are bound twice: to the provider’s request ID and to a SHA-256 hash of the exact preview shown to you. If the underlying request changed after you were asked, the bridge refuses to apply your answer.

You can revoke any device from the dashboard; the bridge disconnects immediately.

Approval tiers

tier A

Low risk

Reads, tests, formatting, edits inside the project. Can be auto-approved if you turn that on. Off by default.

tier B

Needs you

Migrations, package installs, network calls, git operations on normal branches. Always asks over iMessage with a meaningful preview.

tier C

Production-level

Production hints, secrets, pushes to protected branches, writes outside the project, destructive or cost-bearing actions. The message names it a production-level action and then takes the same reply as Tier B — so with the default settings, whoever holds the phone can approve one. Turn off “Approve high-risk actions by text” and approving needs a signed link and a fresh sign-in; denying by text always works.

What this does not claim

We avoid the phrase “your code never leaves your machine,” because Claude Code and Codex transmit code to Anthropic and OpenAI as part of doing their job, under their terms. The precise claim is: Pagr does not need to upload or persist a copy of your repository in its own cloud.

Pagr is not affiliated with Anthropic, OpenAI, or Apple, and does not claim any official partnership or marketplace listing that has not actually been granted.

Reporting a vulnerability

Email security@pagr.dev or follow the process in the bridge repo’s SECURITY.md. Please do not open public issues for security reports.