Enrollment
tokenshift install wires the agent hooks. Enrollment is the separate
step that binds the binary to a specific TokenShift tenant — required for
anything that touches the cloud side.
Why enrollment exists
Section titled “Why enrollment exists”Pinning (the ingest URL + public key compiled into the binary) tells TokenShift where to send records and how to encrypt them. The enrollment manifest tells TokenShift who is sending them — the tenant ID and the per-tenant HMAC key used to derive stable, pseudonymous user IDs.
Without an enrollment manifest, TokenShift still works as a local proxy and hook layer:
- compression and rewrite rules run normally
- recovery cache is populated and readable
- stats land in the local SQLite DB
Telemetry, recovery sync, and any feature that talks to the cloud side stay off.
Install a manifest
Section titled “Install a manifest”# From a filetokenshift enroll ~/Downloads/enrollment.json
# Or from stdin (paste / pipe)pbpaste | tokenshift enroll -Then verify:
tokenshift doctor --verifyThis ships one synthetic record through the live ingest path and reports acceptance.
Where it lives
Section titled “Where it lives”~/.tokenshift/enrollment.json — what tokenshift enroll writes.
No sudo required. The runtime resolver looks here first.
- macOS / Linux:
/etc/tokenshift/enrollment.json - Windows:
%PROGRAMDATA%\tokenshift\enrollment.json
Used when an MDM (Jamf, JumpCloud, Intune, Ansible) drops a manifest as root for every user on the machine. The runtime resolver falls through here when no per-user manifest is present. See MDM rollout.
The same shape works at either path. Per-user wins if both exist.
Manifest shape
Section titled “Manifest shape”{ "tenant_id": "acme-corp", "bearer_token": "", "user_id_hmac_key": "base64-encoded-32-bytes", "config": { "tier_cap": 2, "project_mode": "basename", "recovery_cache_enabled": true, "sample_allowlist": ["git:diff"], "sample_rate": 0.05 }}| Field | Meaning |
|---|---|
tenant_id | The tenant your records land in. |
bearer_token | Currently a no-op on the server. Will be used when ingest gates on a tenant secret. |
user_id_hmac_key | Per-tenant 32-byte salt for deriving pseudonymous user IDs from the local user identity. Base64-encoded. |
config.tier_cap | Maximum telemetry tier this tenant allows. Effective tier is min(local tier, tier_cap). |
config.project_mode | How project names are derived for project labels on records. |
config.recovery_cache_enabled | Whether the local recovery cache is enabled for this tenant. |
config.sample_allowlist | Rules eligible for Tier-4 compression samples. |
config.sample_rate | Probability that an allowlisted invocation actually emits a sample. |
Pinned vs. manifest
Section titled “Pinned vs. manifest”| Comes from the binary (ldflags) | Comes from the manifest (deployment) |
|---|---|
| Ingest URL | tenant_id |
| Ingest public key | user_id_hmac_key |
| Build version | Tier cap, project mode, sample allowlist, sample rate |
This split is intentional: the binary pins transport (where and how), the manifest pins identity and policy (who and how much).
- MDM rollout — patterns for Jamf, JumpCloud, Intune, Ansible.
- Security overview — what’s pinned in the binary vs MDM-pushed, and what’s never transmitted.