The Problem: Your Code Runs on the Attacker's Machine
Every client-side bot defense ships code that executes in an environment the attacker fully controls. They can set breakpoints, run your logic ten thousand times, and diff outputs. The industry's typical response—obfuscation—is theater. Obfuscation adds cost but never prevents understanding.
TrustSig's team starts from a brutal assumption: the attacker has read every line of your client code. Once you accept that, the design space shifts from hiding to making understanding worthless.
Principle 1: Be a Moving Target
Reverse engineering is an investment. Attackers spend a week understanding a binary because that knowledge pays off next week. TrustSig's builds reshuffle internals every release. The mapping between operations and wire encoding regenerates from scratch each build. A signature extracted from one version doesn't fit the next. A meaningful chunk of sensitive machinery re-randomizes per session. The shape of the code in your debugger is unique to one visitor's one visit. Learn it perfectly, and you've learned nothing transferable.
"Static signatures that survive a rebuild: 0," the team states. Cross-version signatures don't carry over.
This mutation comes with a discipline cost. Every transformation must be provably behavior-preserving. TrustSig pins cross-implementation test vectors and fuzzes transformed logic against a plain twin across thousands of inputs. The build fails on the first disagreement.
Principle 2: Don't Branch, Seal
The natural way to write a check is:
if (debuggerDetected) {
zero_all_memory();
}
This is the single most patchable line of code. An attacker finds the jump and flips one byte. Game over.
TrustSig avoids branches in critical paths. Instead of comparing a value and branching, the signal folds directly into key material that decrypts the next stage. If everything is legitimate, the math works out. If tampered, the derived key is wrong, and output is silently garbage. There is no if to flip, no "you got caught" flag. The code simply stops producing valid results without explaining why.
"A branch is a question the attacker can overhear and answer for you. A key derivation is a lock that only opens if the world is genuinely in the expected state."
They extend this across sequences: each step folds its identity and result into a one-way running accumulator. Downstream keys derive from that accumulator. Run steps out of order, skip one, or splice in a replay—the accumulator is wrong, keys are wrong, decryption fails. Order itself becomes part of the secret, with no comparison anywhere to short-circuit.
There's an engineering tax: you must never fold in signals that legitimately vary between honest devices, or you'll lock out real users on slower hardware. The whitelist of safe signals is one of the most conservative parts of the codebase.
Principle 3: Don't Ship the Secret
The most valuable strings and logic shouldn't be in the bundle at all. Certain critical lookup tables and executable logic are minted by the server per session at handshake, under a key derived from that session. They are delivered just-in-time, used, and discarded. An attacker running the bundle in isolation has neither the table nor the key, not because they failed to find it, but because it isn't there.
"Lifetime of the most sensitive material: One session. Minted server-side at handshake, used once, gone."
Browser API names get similar treatment. Hundreds of named host-call slots collapse into a few dozen anonymous numbered channels. Original names are stripped from both sides, and numbering reshuffles per build. Listing what the module "calls out to" no longer tells you what it's actually looking at.
"Named host-calls, erased: ~400 → ~45. Browser-API touch points collapsed into anonymous, per-build-renumbered channels."
Every byte of sensitive material minted live server-side and allowed to expire is a byte no offline analysis can ever recover.
Principle 4: Don't Trust Offline
The nightmare phrase is "reverse once, run forever." An attacker invests one painful week understanding your client, extracts a clean offline replica, and runs it on their own infrastructure forever with no rate limits, no observation, no cost.
TrustSig's structural answer: make "forever offline" impossible by moving part of the decision off the client. In the most-protected configuration, the client is not a self-contained judge. It couples to their edge across a live round-trip. The logic that turns signals into a verdict cannot complete without material the server releases per step, in real time, gated on a liveness proof that the client genuinely ran the exact code issued. Skip the round-trip and you get a dead husk.
This converts the attacker's dream into its opposite: contact our server every step forever. A server round-trip is something you can rate-limit, observe, and reason about. The home-field advantage lost by running on the client is clawed back by refusing to let the client finish the job alone.
They wrap the whole thing in an authenticated AEAD-protected wire protocol with keys that roll on a schedule, a single uniform request shape so you can't tell handshake from telemetry from a decision, and self-healing recovery that never leaks which protection just fired.
Why This Matters
TrustSig's approach inverts the typical defense-in-depth model. They don't rely on secrecy. As they put it: "If telling you how it works breaks it, it was never security. It was a secret waiting to be found."
The defenses assume a fully-informed attacker. That's the bar a serious client-side system has to clear. No CAPTCHAs, no puzzles for real users—just a defense that assumes the worst about its own exposure and is built accordingly.




