Boot attestation for atomic Linux, so anti-cheat vendors have something to check besides a list of approved distro names.
Do not deploy this as a trust system. Nothing has run against a real TPM.
GitHub Actions run 31160003873 verified the raw
attestos.tpm/v1mechanics against an isolated software TPM: AK enrollment, MakeCredential/ActivateCredential, quote verification, replay rejection, signature-tamper rejection, and QEMU/OVMF TPM wiring. The same pinned agent also booted inside a Bazzite-derived QCOW2 under QEMU/OVMF and swtpm in attestos runs 31157890393 and 31159951490. The client agent and server-side mechanics verifier exist, but transport, manufacturer certificate validation, event-log replay, UKI measurement, and boot-policy admission do not. Every one of those authorities remains closed.What you get is a frozen protocol, a raw mechanics verifier, a separate synthetic security model, 44 verifier tests, 20 image-agent tests, and a threat model that lists what still beats it. The full gap list is under "What is not here".
Anti-cheat vendors should start with
VENDOR_SPEC.md.
The next milestone is a separate UKI-capable-base admission canary. It must prove the booted UKI identity and signature, exact embedded command line, PCR/event-log replay, substitution rejection, and update/rollback invariants. Hardware provenance and production policy remain later gates.
The required quote selection remains PCRs 7, 11, 12, and 15, but “required” does not mean every register must be nonzero. The embedded UKI command line is part of PCR 11; PCR 12 covers external command-line inputs and may correctly remain zero when none were supplied. Admission compares replayed policy values rather than treating nonzero as a generic validity test.
Protocol reviewers should use the maintained enrollment and quote sequence
diagrams in protocol/v1/SPEC.md. Generated PR review
guides are navigation aids, not protocol authority.
The default path is source-only and does not access a physical TPM:
git clone https://github.com/plunder707/attested-gaming.git
cd attested-gaming
python3 -m venv .venv
.venv/bin/pip install -e '.[test]'
.venv/bin/pytest -qTo exercise the raw TPM mechanics on disposable GitHub infrastructure, open
the repository's Actions tab, select TPM protocol canary, and choose
Run workflow on main. That workflow uses QEMU TCG, OVMF, and a fresh
swtpm; it does not use your TPM, KVM, or machine firmware, and its token has
only contents: read permission.
The image-side source and build instructions are in
plunder707/attestos. There is no
supported install command or trusted image release yet.
Anti-cheat vendors did not leave Linux because Linux is insecure. They left because they have no way to tell which Linux they are talking to. When EA pulled Apex Legends in October 2024 they described Linux as "a path for a variety of impactful exploits and cheats", and Respawn said that "Linux cheats are indeed harder to detect". Both statements are true. If you control your own kernel you can build one that reports a spotless system while a cheat runs underneath it, because the component being asked to report is the component the attacker owns.
Publishers already work around this in the bluntest way available. Some games allow SteamOS and block Fedora and Ubuntu, with the same kernel, the same Proton, and the same anti-cheat runtime on all three. SteamOS gets through because it is a known read-only image on known hardware. That is a form of attestation already; it is just keyed off a hardcoded name instead of a signature. This project does the same thing cryptographically so that any distro can earn what SteamOS currently gets for free.
You reboot into a locked profile to play, and you leave it when you are done. The lockdown is voluntary and it is temporary. That is what separates this from a games console, and it is the only shape of the idea a free operating system can honestly ship.
Reaching for virtualization is the right instinct, but the direction decides whether it works.
Running the game inside a VM is the thing anti-cheat blocks, and for good reason. A VM is the best cheat vector there is: put the cheat in the host and the game in the guest, then read guest memory from outside while the guest sees nothing. EAC, BattlEye and Vanguard all detect and refuse virtualized environments, so "run the game in a VM" walks straight into the ban.
The model that works is the one Windows already ships. Virtualization-Based Security puts a thin hypervisor beneath Windows, so the OS you actually use runs as a guest while the security-critical code sits at a privilege level the OS cannot reach even from ring 0. The hypervisor is the root of trust rather than a sandbox wrapped around the game.
UEFI + Secure Boot
|
measured, signed thin hypervisor <-- root of trust, in PCRs 0-7
|
+-- desktop guest (yours, unlocked, do anything)
|
+-- game guest (attested: UKI, lockdown, atomic image)
The hypervisor is measured at boot, so it cannot be modified without changing its own measurement, and neither guest can reach it.
If the desktop is also a guest, then switching into game mode is not really a reboot:
- entering pauses the desktop guest in RAM and hands the GPU to the game guest
- leaving shuts down the game guest and resumes the desktop guest
The desktop comes back with every window where you left it, since it was never shut down in the first place. Coming back takes under a second.
The GPU is where this gets expensive. Passing a discrete card between guests means unbinding and rebinding the driver, which takes a few seconds and can black out the screen while it happens. The clean setup uses two display adapters, with an integrated GPU driving the desktop guest and the discrete card passed through to the game guest. That works well on a machine with a 4090 plus an iGPU. Single-GPU passthrough is possible but rough.
An earlier version of this file claimed the hypervisor model gives a stronger guarantee than Windows. That is false, and it is left on the record here because it is exactly the kind of claim that kills a pitch.
Windows VBS with HVCI already enforces code integrity from the hypervisor, and it ships enabled by default on new Windows 11 installs. Continuous hypervisor-enforced integrity is not something anyone here would be inventing. The first engineer in the room who knows what HVCI does would throw the proposal out, correctly.
Parity is the honest claim:
You did not leave Linux because you wanted to. You left because you could not tell which Linux you were talking to. This is how to tell, and it gets you to the same footing you already accept on Windows.
It sounds weaker and it lands better, mostly because a vendor can check a comparison but has to take a superiority claim on faith.
PCRs are append-only within a boot, so nothing that happens after attestation can un-extend them. That is the ceiling on what boot attestation buys you, and plenty of cheating sits above it:
- userspace cheats, which modify no kernel state and leave PCRs untouched
- exploits against the kernel that is already running, same story
- DMA cheat hardware, and second-PC capture with an external aimbot, which do not execute on the attested machine at all
So the framing is not that Linux becomes cheat-proof. It is that Linux becomes about as attestable as Windows, leaving the residual risk that vendors already live with today. Overselling this is the fastest way to lose the argument the first time somebody cheats anyway.
Denuvo's structural weakness was never the cryptography, it was position. It runs in userspace inside the game process and tries to verify its own integrity from in there, so whatever controls the process also controls what those checks are allowed to see. Obfuscation inside a process does not survive something running beneath the process.
That is the principle this project is built on, which is why the hypervisor goes underneath. Taken seriously it points at our own weak spots too.
Relay. A nonce proves a quote is recent. It says nothing about which
machine produced it. The synthetic verifier models the intended fix by
quoting H(nonce || channel_id), and
test_a_quote_relayed_from_another_machine_is_refused covers that model. The
raw attestos.tpm/v1 canary deliberately supports only nonce_only, because
there is no transport from which to derive a non-client-controlled channel
binding. The mechanics canary is therefore replay-resistant but not
second-machine-relay-resistant, and it cannot grant production trust.
Everything below the hypervisor. Making the hypervisor the root of trust also makes it the single point of failure, and a compromised root of trust attests as perfectly healthy, because the component doing the reporting is the one that got subverted. Specifically:
- SMM runs at ring -2, above any hypervisor. An implant there wins outright.
- DMA from a malicious PCIe or Thunderbolt device reads and writes memory with no CPU involvement. Stopping it needs IOMMU with pre-boot DMA protection switched on, which plenty of boards ship without.
- UEFI implants sit below Secure Boot entirely.
- TPM bus sniffing works on socketed TPMs, where the LPC/SPI bus between CPU and chip can be probed with cheap gear. This has been demonstrated against BitLocker. Mitigations are TPM 2.0 encrypted sessions with parameter encryption, and using a firmware TPM inside the CPU package instead of a socketed part.
None of that is handled here. It is listed because a threat model that stops at the layer you happened to implement is an advertisement, not an analysis.
Working, tested, and independent of hardware:
attest/policy.pysets out which PCRs get measured, what counts as a trusted profile, and why the kernel command line has to live inside the signed UKI.attest/quote.pymodels the TPM quote structure and includes a software signer, so the verifier can be exercised on a machine with no TPM.attest/verify.pyis the synthetic reference verifier. Every check fails closed.protocol/v1/,attest/enrollment.py, andattest/wire.pydefine and verify the raw TPM mechanics boundary without granting boot-policy trust.tests/holds 44 tests covering replay, cross-machine relay, forged PCR values, bypass by omission, key substitution, uncertified keys, non-quote structures replayed as quotes, algorithm downgrade, and TPM rollback.- The image agent in
plunder707/attestosis pinned by commit in the canary. GitHub Actions run 31160003873 exercised MakeCredential/ActivateCredential, Quote/CheckQuote, single-use replay rejection, signature-tamper rejection, and QEMU/OVMF/swtpm wiring. SeePROTOCOL_CANARY.md.
The verifier came first because a broken verifier does not crash. It returns "trusted" after skipping the one check that mattered, and nothing anywhere logs that it did.
No hardware trust result. Developed without exposing the workstation TPM. The raw path has seen genuine TPM-format quotes from swtpm, including from the installed agent in a booted attestos QCOW2. It has not seen a quote from real hardware and cannot establish hardware provenance.
No manufacturer certificate validation, and this is a load-bearing gap.
The v1 enrollment flow now uses MakeCredential/ActivateCredential to prove
that the AK and EK are controlled by the same TPM. That is not manufacturer
trust. Picture
nested virtualization: an attacker runs this entire clean stack as a guest
under their own hypervisor. Our PCRs measure our stack accurately while their
hypervisor reads everything from below. The certificate chain is the only
thing that catches this. An emulated TPM has no genuine manufacturer chain and
gets refused, and a real TPM passed through will have measured what actually
booted on that hardware, meaning the attacker's hypervisor, so its PCRs will
not match any profile. Without the chain, every other check in verify.py is
decoration. The raw verifier records manufacturer_trusted=false and
production_trusted=false until an approved certificate validator succeeds.
No transport or real channel binding. The raw v1 messages are exercised
locally over stdin/stdout. There is no TLS server, exporter binding, account
session, rate limit, or deployment protocol. nonce_only is not sufficient
against a clean second-machine relay.
No event-log replay or boot-policy admission. The agent can attach bounded logs when the operating system exposes them, but the verifier does not replay those logs or authorize PCRs against a signed distro policy. A valid quote is therefore evidence of TPM mechanics, not evidence of an approved boot.
No production hypervisor. The canaries use QEMU/OVMF with TCG and swtpm to exercise mechanics. The security architecture above remains a design.
No vendor. The engineering is the easy half. The hard half is getting one anti-cheat vendor to accept a quote, and that is a relationship rather than a commit.
Registry will not survive a real distro. It does exact matching against
known-good PCR hashes, which is the naive approach. Every kernel update
changes PCR 11 and every image update changes PCR 15, so anyone who updates
gets locked out until a vendor registers the new hash, and a vendor who
registers late locks out everybody at once. People would stop updating in
order to keep playing, which means the security mechanism would be creating an
unpatched population. That is worse than having no mechanism.
The real design registers a key rather than hashes. TPM 2.0 PolicyAuthorize
lets a policy be satisfied by anything the distro's signing key has signed, so
no image needs pre-registration. Registry is fine for a demo and must not
ship.
No privacy story, and this objection deserves to land. Attestation creates a permanent hardware-bound identifier. The endorsement key is unique per TPM and never changes, so a vendor can link every account ever used on a machine, forever, with no way out short of buying new hardware. For a free-software project this is the central fight and "don't worry about it" is not an answer. The TPM specification includes Privacy CAs and Direct Anonymous Attestation for exactly this reason, and a project that ignores them earns the pushback it gets.
Esports tournaments already require locked-down machines: clean image, no USB, monitored throughout. Organisers have budget, written requirements, and their own distribution through leagues and event operators, and none of it requires an anti-cheat vendor's permission.
There is a second reason tournaments fit better than consumer play. In a tournament the host may be adversarial, since the machine belongs to someone other than the player and both sides have reason to distrust it. That is the threat confidential computing addresses, with Intel TDX or AMD SEV-SNP encrypting guest memory against the host itself.
For consumer anti-cheat that is over-engineering, since vendors want to know the client is untampered and do not care whether its memory is hidden from the OS. For tournaments it is the whole point. The tiers fall out of that:
Tier 1 boot integrity PCR measurement. Parity with Windows Secure
Boot and VBS. Pitch this one first, to anyone.
Tier 2 runtime state Re-measure at game launch: loaded modules,
processes, shared libraries. Catches userspace
rootkits that Tier 1 cannot see.
Tier 3 confidential compute TDX or SEV-SNP. Protects the guest from the
host. Tournaments and esports only.
Only Tier 1 exists. Tiers 2 and 3 are not built.
EAC's Linux support under Proton runs in userspace. Kernel-space anti-cheat is not supported there, and the userspace component does little beyond basic sanity checks.
That matters for the pitch. On Linux, boot attestation is not competing against a strong runtime story; it is filling an almost empty slot. A vendor weighing boot attestation plus their current Linux checks is weighing it against very little, so the marginal value is higher on Linux than the same addition would be on Windows.
The open question is whether a vendor would accept boot attestation on its own or insist on a second measurement at game launch. That is Tier 2, and it belongs in the spec as a question rather than a guess.
If every vendor writes their own checker then nobody writes one. If distros emit a standard token and vendors verify it with a shared library, the cost gets paid once. TLS certificates work this way; nobody negotiates validation server by server.
{
"iss": "distro.example",
"attestation": "tpm2-quote",
"pcrs": {"7": "...", "11": "...", "12": "...", "15": "..."},
"signing_policy": "distro-release-key-v3",
"channel_binding": "<tls-exporter>",
"nonce": "...",
"exp": 1722883200
}- Chain the AK to an EK certificate and drop the stub. First, because nothing else means anything until it is done.
- Replace
Registryexact-matching withPolicyAuthorizeagainst a distro signing key, so updates stop locking people out. - Run the verifier against a real
tpm2_quote, using TPM 2.0 encrypted sessions rather than plaintext, on a firmware TPM rather than a socketed one. - Settle on an unlinkable but revocable identity before asking anyone to run this. Group signatures over a "genuine TPM 2.0 from manufacturer X" group look more implementable than Direct Anonymous Attestation, which needs an online anonymity service and has poor support in consumer TPMs.
- Prototype the hypervisor split with iGPU and dGPU on real hardware.
- Send the one-page spec to one vendor engineer before writing more code. The answer decides everything downstream.