Skip to content

feat(sharing): securely combine usage across your own devices#532

Merged
iamtoruk merged 7 commits into
mainfrom
feat/device-sharing
Jun 20, 2026
Merged

feat(sharing): securely combine usage across your own devices#532
iamtoruk merged 7 commits into
mainfrom
feat/device-sharing

Conversation

@iamtoruk

Copy link
Copy Markdown
Member

Adds opt-in, local-network sharing so you can see total AI spend across the Macs you own (e.g. a Mac Studio + a MacBook) without any cloud account.

What it adds

  • codeburn share - serve this device's usage over mutual TLS on your LAN. On-demand by default (stops after 10 min idle); --always keeps it up.
  • codeburn devices add - discover nearby devices over mDNS and pair with an approve prompt (confirm a matching 3-digit code, AirDrop style). codeburn devices add <host> --pin <pin> is the manual fallback.
  • codeburn devices - pull each paired device's usage and print a per-device table plus a combined total. Devices are shown separately, never merged server-side.

Security

  • Mutual TLS with self-signed certs; identity is the SHA-256 of the cert, pinned trust-on-first-use (no CA).
  • Tokens are bound to the peer's certificate fingerprint, so a leaked token is useless from another machine.
  • Pairing is either a one-time 6-digit PIN or an approve prompt with a short-authentication-string code derived from both fingerprints.

Privacy

Only aggregate numbers leave a device (cost, tokens, calls, sessions, models, tools, activities, daily). Project names, file paths, and per-session detail are stripped before anything is sent, so what you are working on stays local.

Tests

26 tests under tests/sharing/: pairing/token logic, loopback mutual-TLS transport (pair, pinned authed pull, rejects wrong PIN / replayed token from a different fingerprint / mismatched server fingerprint), the approve flow, and the data sanitizer.

iamtoruk added 7 commits June 20, 2026 15:06
First piece of local device sharing: self-cert fingerprint identity
(trust-on-first-use), a one-time expiring pairing PIN, fingerprint-bound
tokens, and a peer store that authorizes a pull only when both the token
and the TLS peer fingerprint match the same paired device. Pure logic,
fully unit-tested; the TLS share server and host pull build on this.
Add device identity (self-signed cert, persisted; fingerprint = sha256 of
the cert DER), an HTTPS share server (mutual TLS: presents its cert, reads
the client's, and serves /api/usage only when the bearer token AND the
client fingerprint match the same paired peer), a one-time-PIN pairing
endpoint, and a fingerprint-pinning client. Verified end to end on
loopback: PIN pairing, pinned authed pull, and rejection of a wrong PIN,
a token replayed from another device, and a mismatched server
fingerprint. Adds the selfsigned dep (Node cannot generate certs natively).
Phase 3 terminal flow: codeburn share runs the secure server on-demand
(stops after 10 min idle; --always to persist, --pair to add a device),
and codeburn devices add <host> --pin <pin> pairs and pins a remote.
codeburn devices pulls this machine plus every paired device, keeps each
separate, and prints a per-device table with a simple summed Combined
row (no server-side merge). Persists identity and peers under the config
dir. Host pair-and-pull flow covered by a loopback integration test.
Add bonjour-service discovery (advertise/browse over the LAN), a short
confirmation code derived from both cert fingerprints (Bluetooth-style
'do these match?' check), and an approve-style pairing endpoint that
prompts the owner instead of requiring a typed PIN. Loopback-tested:
approved device gets a working token with a matching code on both sides,
declined device is rejected.
codeburn share now advertises on the LAN and approves incoming devices
interactively (confirm the matching code, no typed PIN). codeburn devices
add (no args) discovers nearby devices, lets you pick one, shows the
confirmation code, and waits for the owner to approve. Manual
add <host> --pin stays as a fallback for networks that block mDNS.
Sanitize each device's payload before it leaves the machine: drop
topProjects and topSessions (project names + session detail) and send
only aggregate numbers (cost, tokens, models, tools, activities, daily).
What you are working on stays local; only the totals travel.
@iamtoruk iamtoruk merged commit 887374d into main Jun 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant