Security overview
This page is the one-screen summary of TokenShift’s security posture. For the field-level data contract, see Data contract. For the install model and threat table, see Installation & distribution.
No control plane
Section titled “No control plane”TokenShift has no control plane. The binary is the only thing PointFive controls; once it’s on a developer’s machine, the customer controls what it does:
- All configuration is install-time — baked into a four-field local JSON file (the enrollment manifest) that the customer admin deploys via their MDM (Jamf, JumpCloud, Intune, Ansible, …).
- There is no remote policy push, no remote rule update, no remote opt-out, no audit-event stream coming the other way.
- Reconfiguration = regenerate the manifest in the customer portal, redeploy via MDM. PointFive cannot reach a running client.
- Upgrades follow the same path — the customer admin promotes a new binary version through MDM at their own pace.
Eliminating the control plane removes the highest-value attack surface in any client-side agent. It also gives customers a clean answer to “what stops you from pushing a malicious config to my fleet?” — nothing in the architecture allows it.
Wire-level encryption
Section titled “Wire-level encryption”Every record TokenShift emits is hybrid-encrypted client-side before it leaves the developer’s machine, using a public key pinned in the binary at build time. The matching private key is held by PointFive and never leaves PointFive’s key-management system.
- Compromise of a developer laptop yields ciphertext but no decryption capability.
- Compromise of the enrollment manifest grants no decryption capability either — the public key isn’t in the manifest.
- Key rotation requires a new binary version. Binaries can ship multiple acceptable keys for graceful transitions.
Manifest tampering can at most disrupt telemetry or redirect records the attacker can’t decrypt.
Allowlist (fail-closed)
Section titled “Allowlist (fail-closed)”Every field allowed on the wire is enumerated explicitly in a single shared list. If a record carries a field that isn’t on the allowlist, that field is stripped before send. If a record carries an unknown signal name, the whole record is dropped. If the redactor warns on a shape-carrying field, the whole record is dropped — never partial.
The full fail-closed table — including outbox overflow, network unavailability, missing manifest, encryption failures — is in Data contract §10.
Local recovery cache
Section titled “Local recovery cache”TokenShift can keep a one-hour local cache of compressed-away tool output so a developer can tokenshift recover <id> the original back. This cache is:
- Local-only. Never shipped over the wire. Lives on the developer’s machine.
- One hour TTL. Bounded by design.
- Off when disabled. Install-time config; when disabled, the
recovery_retrievedsignal is naturally absent.
The signal recovery_retrieved records that a recovery happened (with a join key and an age in seconds) — not the recovered content.
The five wire signals
Section titled “The five wire signals”Every record TokenShift emits is one of five typed JSON documents. Each has a full field table in Data contract.
| Signal | What it is |
|---|---|
tool_invocation | The atomic record — one per Claude tool call, regardless of whether TokenShift compressed. |
recovery_retrieved | A developer pulled back the original output via the recovery command — the compression-quality signal. |
session_summary | End-of-Claude-session aggregates — turn count, end reason, context-window peaks. |
compression_sample | Triple-gated, off-by-default redacted before/after pair for rule tuning. Tier 4 only. |
client_state | Periodic (≤1/24h per machine) fleet metadata — binary version, OS, install method, self-check passed. |
What the wire never carries
Section titled “What the wire never carries”The wire never carries any of these — none are on the allowlist, no code path attaches them, and an automated test asserts only allowlisted keys appear on the wire:
- Bash stdout/stderr content (including hashes).
- Tool inputs: file contents, web content, MCP tool-call results.
- Claude Code transcripts, prompts, messages, message hashes.
- Environment variables (names or values).
- Raw file paths, hostnames, OS usernames, IPs, MACs.
- Branch names, commit messages, git refs.
- Raw email. Read once locally to compute
user_id = HMAC(per-tenant-key, email), then discarded. The hash ships; the email never does.
Full list: Data contract §13.
Tiers — what leaves the laptop
Section titled “Tiers — what leaves the laptop”A single integer set by user choice and capped from above by install-time config. The effective tier on the wire is min(user_choice, admin_cap).
| Tier | What leaves the laptop |
|---|---|
| 0 | Nothing. Local stats only. |
| 1 | tool_invocation (no shape fields), recovery_retrieved, session_summary, client_state. |
| 2 | Tier 1 + command_shape and rewritten_command_shape on tool_invocation. |
| 4 | Tier 2 + compression_sample. Triple-gated; off by default even when permitted. |
Default tier when enrolled: 1. Tier 4 additionally requires a per-rule allowlist and a configured sample rate.
Further reading
Section titled “Further reading”- Data contract — every field on every signal, redactor semantics, retention.
- Installation & distribution — distribution channels, enrollment, key management, full threat model.
- Telemetry signals — one-paragraph index of the five signals.