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.
- 01iMessageyour phone
- 02Pagr control planehosted · intent, routing, policy
- 03Bridgeyour Mac · open source
- 04Claude Code / Codexyour 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.
| Command | What it does |
|---|---|
| device.probe | Health and capability report from the bridge. |
| project.list | Registered project IDs and display names. Never paths. |
| project.remove | Forget a registered project. |
| agent.start_session | Start Claude or Codex in a registered project with an instruction. |
| agent.send_instruction | Steer or queue an instruction into a live session. |
| agent.stop_session | Stop a session. |
| agent.get_status | Status for one session or all of them. |
| agent.respond_to_approval | Allow or deny one pending request, bound to its ID and a hash of the preview you saw. |
| settings.sync_public_policy | Push your approval policy — auto-allow tier, timeout — to the device. |
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
Low risk
Reads, tests, formatting, edits inside the project. Can be auto-approved if you turn that on. Off by default.
Needs you
Migrations, package installs, network calls, git operations on normal branches. Always asks over iMessage with a meaningful preview.
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.