Security model
Agentarivm starts coding agents on your machine over the network. That makes it, honestly named, a remote-code-execution control plane — and the whole design follows from taking that seriously.
The core rule
Section titled “The core rule”The mobile app is an unprivileged client. It must never receive:
- GitHub private keys or long-lived automation credentials,
- Claude tokens,
- shell or SSH credentials,
- direct access to the agent engine’s loopback API,
- arbitrary filesystem access.
A local manager service running on your machine owns all credentials, repositories, worktrees, agent calls, git operations, and GitHub API operations. The phone asks; the manager decides and acts.
What that looks like in practice
Section titled “What that looks like in practice”Two credentials per device, doing different jobs. At pairing, a device receives a client certificate from the manager’s own private CA and a device token. The certificate decides who may open a connection at all — a stranger who finds the port is refused during the TLS handshake, before reaching any route. The token authorises each request, is stored only as a hash, and dies instantly on revocation. The two are bound: a token copied off one phone is useless on another, because the second phone cannot produce the first one’s private key.
A private CA, on purpose. A publicly-trusted certificate is trusted because ~150 certificate authorities can vouch for the name — any of which can be made to issue for it. The manager’s CA vouches for one server and a handful of devices, and nothing else on earth trusts it. For a system with a closed set of clients, that is the stronger property, not a compromise.
Allowlists everywhere. Repositories, base branches, models, effort levels, issue actors, session actions — the app chooses from lists the manager holds. There is no endpoint that accepts an arbitrary path, an arbitrary shell command, or a raw terminal.
Argument arrays, never shell strings. Every subprocess — git, gh, claude — is invoked with an argument array. Nothing is ever interpolated into a command string, and issue titles, bodies, branch names and GitHub usernames are treated as untrusted input throughout.
Path containment. Every worktree path is canonicalised and checked to remain inside the configured worktree root before anything touches it.
Agents cannot merge. Sessions open draft pull requests and are explicitly forbidden from merging. Merging happens from the app, behind a biometric gate, and the manager re-reads mergeability, checks and the head commit from GitHub immediately before acting — if the branch moved after you reviewed it, the merge is refused.
Labels are not authorisation until a person is. The issue automation starts sessions only for labels applied by GitHub accounts on an explicit allowlist — which is empty by default, and empty means nobody.
Audit trail. Session creation, stop, merge, cleanup, pairing and revocation are all recorded as events. Logs redact authorization headers, tokens and credential paths.
What is exposed to the network
Section titled “What is exposed to the network”With TLS on and client certificates required, an unpaired stranger probing the port can reach exactly two things:
| Endpoint | Why it is open |
|---|---|
/api/v1/health |
Liveness. It reveals nothing a stranger could not learn by watching the port answer. |
/api/v1/pair |
A never-paired phone has no certificate yet; this is the one door in. It is protected by a one-time code minted on the machine’s own terminal, and rate-limited. |
Everything else requires a valid client certificate and a valid device token.
What the manager itself never holds
Section titled “What the manager itself never holds”The manager’s service definition deliberately carries no credential. GitHub authentication lives in gh’s own store; the Claude subscription token lives with the process that launches the agents. agentarivm doctor checks that the credential is in place and correctly protected — without ever reading its value.