C3 Mobile / Core concepts
Updated 2026-07-24
Security model
C3 Mobile's core promise: your hub, your network, and push infrastructure never see content. Prompts, terminal output, commands, and push payloads are protected end to end between your phone and each bridge.
NOTE — > C3 Mobile is beta software and its protocol has not yet completed independent cryptographic review. The design is documented and testable, but treat "end-to-end encrypted" as an engineering claim, not an audited guarantee.
Message protection
Every command and event travels as a sealed envelope:
- XChaCha20-Poly1305 authenticated encryption, with keys derived per phone↔bridge pair (X25519 key agreement + HKDF-SHA256).
- Context binding — the authenticated data ties each packet to its exact message subject, protocol version, hub/host/phone identities, channel epoch, direction, kind, and sequence number. A valid ciphertext replayed on a different subject, session, or position is rejected.
- Fresh channels — each connection derives ephemeral channel keys, re-keyed on reconnect and every 15 minutes; command and event directions use independent keys, and sequence counters are monotonic with replay windows.
- Padding — ciphertext is padded into coarse size buckets so lengths leak little about content.
- Expiry — inputs expire in ~5 seconds, mutations in ~10, reads in ~30. Delayed messages die instead of executing late.
Establishing trust
- Transport pinning — the phone validates your hub's CA public key (SPKI SHA-256) inside a native module on iOS and Android, and refuses any other certificate, host, or port. There is no "accept anyway" path. Bridges pin the same CA over TLS 1.3.
- Enrollment — the hub-side QR carries a short-lived secret; the phone generates its keys locally, proves possession, and receives its own signed NATS credential. Private keys never leave the device.
- Pairing — phone and bridge run a mutual key-confirmation exchange over a one-time QR (≤10 minutes validity), deriving a long-term pair root the hub never learns. Each pair has independent keys and counters.
Secrets at rest
- Phone: hardware-backed secure storage; Android sets
FLAG_SECURE(no screenshots/recents preview), iOS covers the app switcher; opening sessions and terminals sits behind your device biometric/passcode. - Bridge: OS credential store by default (
C3BRIDGE_SECRET_BACKEND=keyring); explicit encrypted-file backend for headless hosts. State on disk is encrypted; logs carry event codes only — never prompts, paths, subjects, or tokens. - Hub: administration keys live in the hub machine's keystore and in the passphrase-sealed backup you create with
hub control backup. The deployable bundle contains no secrets.
Revocation
Two independent layers, both effective while the target is offline:
- Unpair — from the app (Settings → paired bridges) or
c3bridge revoke <device-id>on a host: removes that one phone↔bridge relationship. - Hub revocation —
c3sync hub control revoke <USER_PUB>: invalidates the device's hub credential via a signed, monotonic revocation manifest; bridges consume it on their next connection. Use this for a lost phone — see the ceremonies.
What this does NOT protect against
Honest non-goals, from the threat model:
- A compromised endpoint. A rooted/compromised phone, bridge host, or Herdr install can read whatever that endpoint can read. E2EE protects the path, not the ends.
- Recalling data. Revocation stops future access; it cannot erase what a device already received.
- Traffic analysis. The hub operator (you, usually) sees subjects, timing, and coarse sizes. There is no cover traffic.
- Denial of service. Whoever controls the network or the NATS server can always drop or delay messages — expiry turns that into failed commands, not wrong ones.
- Permission-prompt semantics. Allow/Reject in the cockpit sends keystrokes (Enter/Esc) to the agent's terminal; C3 does not parse or verify the prompt the agent is showing. Glance at the terminal when the stakes are high.
Related: architecture · hub commands & ceremonies · C3Sync's separate security model.