Skip to content

Agent security model

How the on-machine engine talks to the cloud, and why a captured request can't be replayed or forged.

Trust bootstrap → per-machine credential

The provisioning EXE ships with a tenant enrollment token (a scoped, revocable Bearer token baked in at build time). On its first report the engine calls POST /v1/enroll with that token and receives a per-machine signing credential: a credential id and a random HMAC secret, returned exactly once.

The engine stores the secret DPAPI-encrypted (Protect-TotlDpapiSecret, LocalMachine scope) at C:\ProgramData\TotlProvision\machine-cred.json, so it isn't readable off-box or by another user. From then on every request is signed with that per-machine secret; the shared enrollment token is no longer used for ongoing traffic and can be revoked.

Signed requests (integrity + replay protection)

Every machine → cloud call carries:

Header Meaning
X-Totl-Cred the machine credential id
X-Totl-Timestamp unix seconds (must be within ±5 min of server time)
X-Totl-Nonce a one-time random value
X-Totl-Signature HMAC-SHA256(secret, canonical) as hex

The canonical string signed by both sides is exactly:

METHOD \n PATH \n TIMESTAMP \n NONCE \n SHA256HEX(body)

The server recomputes the HMAC with the machine's stored secret and rejects the request unless it matches, so the body cannot be tampered and the token cannot be lifted and reused (there is no bearer secret on the wire). A stale timestamp is rejected (skew window), and each nonce is stored server-side until it expires, so a captured request cannot be replayed. The canonical form and HMAC are covered by cross-language tests — the PowerShell Totl.Signing module and the Worker signing.js are verified against the same golden vectors, so they always agree byte-for-byte.

Signing is additive and backward-compatible: if the backend or engine predates it, the engine falls back to the Bearer token. To require signing everywhere, set REQUIRE_SIGNED=1 on the Worker.

Revocation

Deleting a machine (or its build) revokes the associated credential. A revoked credential fails the lookup, so the machine stops being able to report until it re-enrolls with a valid token.

Code-signing

Release artifacts are Authenticode-signed by engine/scripts/Sign-TotlRelease.ps1, invoked from build/Build-Release.ps1 -Thumbprint <cert> (staged scripts are signed pre-compile so signatures ship inside the EXEs; the compiled artifacts are signed after). Ship signed builds so Windows SmartScreen and your own allow-listing trust the engine.

What each layer defends against

  • HMAC signature — request tampering, credential theft from TLS-terminating proxies, forged reports.
  • Timestamp + nonce — replay of a previously valid request.
  • DPAPI at rest — secret theft by copying files off the machine.
  • Per-machine credentials + revocation — blast radius: one machine, not a whole tenant.
  • Code-signing — tampered or spoofed engine binaries.