Evidence that a server runs the code that was published.
Attestium is a Node.js library for remote attestation. It collects evidence of what a machine runs and verifies it against references the verifier obtains itself.
Publishing source code proves nothing about production. Attestation makes that claim checkable by anyone.
npm install attestium
- Format
- JSON evidence, version 2
- Binding
- Nonce and SHA-256 digest
- Hardware
- TPM 2.0, IMA, SEV-SNP, TDX
- Runtime
- Node.js 18+ on Linux
- License
- MIT
How it works
Following the IETF remote attestation architecture (RATS), the attester reports facts and never decides. The verifier trusts nothing from the machine that it cannot check against an outside reference or a hardware signature.
- Verifier to attesternonce Sends a nonce: 16 to 64 random bytes, hex encoded.
- Attestercollect Collects facts about files, packages, processes and containers, computes evidenceDigest, and asks the TPM or CPU to sign both values.
- Attester to verifierevidence Returns the evidence: nonce, digest, files, processes and any hardware statement.
- Verifier to referencesfetch Fetches references itself, by digest: the commit, lockfile-pinned tarballs, image layers, signed archives.
- References to verifierreferences Each reference is checked against the digest that names it.
- Verifiercompare Checks the nonce, the digest and the hardware signature, then compares every fact with its reference.
- Verifier to relying partyresult Publishes the result, pass, fail or inconclusive, with its evidence level.
What it verifies
Every running file must be explained by a reference: a verified package, an image layer, an official release, a signed archive or a hardware measurement. Hover, focus or tap an element to see what is compared with what.
- 1Npnpmnpm. Every file under node_modules, compared with the registry tarball that pnpm-lock.yaml or package-lock.json pins.
- 2PyPyPIPyPI. Virtual environments, compared with the wheels that uv.lock, pylock.toml, poetry.lock, Pipfile.lock or hashed requirements pin.
- 3RbRubyGemsRubyGems. Bundler's vendor/bundle, compared with the .gem files pinned by the CHECKSUMS section of Gemfile.lock.
- 4HxHexHex. Mix's deps/, compared with the tarballs pinned by the outer checksums of mix.lock.
- 5CpComposerComposer. vendor/, compared with the git tree of the commit that composer.lock pins.
- 6MvMavenMaven. Directories of jars, compared with the hashes in Gradle verification metadata or a Maven lockfile.
- 7NgNuGetNuGet. A published .NET application, compared file by file with the packages whose content hashes packages.lock.json pins.
- 8GoGoGo. The build information inside a Go binary, compared with go.sum and the commit. The binary's own hash proves the rest.
- 9RsRustRust. The cargo-auditable crate list inside a binary, compared with Cargo.lock at the commit.
- 10NbNativeNative. The hash of a running binary, compared with a signed checksum list, an artifact attestation, a release manifest or a pinned hash.
- 11NdNode.jsNode.js. The node executable, compared with bin/node inside the official release archive listed in SHASUMS256.txt.
- 12OcOCIOCI. A container's root filesystem, compared with the image layers fetched by digest from the registry and applied in order.
- 13DbDebianDebian. Each running file's owning Debian or Ubuntu package, compared with the .deb reached from the signed InRelease file.
- 14TpTPMTPM. A TPM 2.0 quote over SHA-256(nonce ‖ digest), checked with the attestation key pinned at enrollment and expected PCR values.
- 15ImIMAIMA. The kernel's measurement log, replayed to the quoted PCR 10. Each running file's hash is compared with its measurement.
- 16SnSEV-SNPSEV-SNP. An AMD SEV-SNP report over SHA-512(nonce ‖ digest), chained through the VCEK to AMD's root, with debugging off.
- 17TdTDXTDX. An Intel TDX quote over SHA-512(nonce ‖ digest), chained to Intel's root. The MRTD is compared with the expected image.
- 18SgSigstoreSigstore. A Sigstore bundle: the Fulcio certificate chain, the Rekor log entry, and the signer identity the verifier requires.
- 19GaGitHubGitHub. A GitHub artifact attestation for a file's SHA-256, signed for the expected repository, workflow and ref.
- 20CsChecksumsChecksums. A published checksum list signed with gpg, minisign or Sigstore. The file's hash must be in the list.
- Packages
- Binaries and runtimes
- System
- Hardware
- Signatures
Ecosystems and referencesHardware-backed evidenceSignatures and trust
Evidence levels
The strength of a result depends on what backs it. Report the level with every result. Security model and limits
-
1Software evidence
- Backed by
- The attester's report, bound to the nonce by the digest.
- Proves
- Drift, failed deploys, modified files and packages, injected libraries, attached debuggers, unexplained programs.
- Does not prove
- Anything against root that anticipates the check: root can run a modified attester.
-
2TPM-bound
- Backed by
- A TPM 2.0 quote over the nonce and digest, signed by an attestation key pinned at enrollment.
- Proves
- The report came from the enrolled machine, now; with pinned PCRs, that it booted the expected firmware and kernel.
- Does not prove
- That root did not misreport files and processes after boot.
-
3TPM and IMA
- Backed by
- The quote, plus the kernel's IMA log replayed to the quoted PCR 10.
- Proves
- The logged hashes are the files the kernel loaded, even against a hostile root user.
- Does not prove
- Files outside the IMA policy, or a compromised kernel or firmware.
-
4Confidential VM
- Backed by
- An AMD SEV-SNP or Intel TDX report over the nonce and digest, chained to the vendor's root.
- Proves
- The VM's launch measurement, with debugging off, in memory the host cannot read.
- Does not prove
- Software loaded after launch, unless the launch measurement covers it.
Example
An attester answers a nonce with evidence about a deployed directory. The verifier checks shape, nonce and digest, then compares every file with a checkout of the expected commit.
On its own this is software evidence: whoever controls the attester can forge it. A TPM quote with a pinned key and IMA, or a confidential VM, makes a forgery fail.
const fs = require('node:fs');
const os = require('node:os');
const {evidence, fileTree, util} = require('attestium');
(async () => {
// Verifier: a fresh nonce.
const nonce = util.generateNonce();
// Attester: hash the deployed files and answer the nonce.
const {entries, errors} = await fileTree.walkTree('./app');
const files = {};
for (const entry of entries) {
util.setOwn(files, entry.path, [entry.type === 'symlink' ? `symlink:${entry.target}` : entry.sha256, entry.mode]);
}
const document = {
type: evidence.TYPE,
version: evidence.VERSION,
nonce,
collectedAt: new Date().toISOString(),
attester: {name: 'example-attester', version: '1.0.0'},
host: {hostname: os.hostname(), kernel: os.release()},
services: [{
name: 'app', kind: 'directory', root: './app', realRoot: fs.realpathSync('./app'), git: {commit: null}, files, fileCount: entries.length, errors, installs: [], processes: [], userProcesses: [],
}],
executables: [],
libraries: [],
};
document.evidenceDigest = evidence.evidenceDigest(document);
// Verifier: shape, nonce and digest first; then every file against the reference.
const {valid} = evidence.validateEvidence(document);
const bound = document.nonce === nonce && evidence.evidenceDigest(document) === document.evidenceDigest;
const reference = await evidence.createManifest('./reference', {repository: 'example/app', commit: 'a'.repeat(40)});
const service = document.services[0];
const differ = [...new Set([...Object.keys(reference.files), ...Object.keys(service.files)])]
.filter(file => String(reference.files[file]) !== String(service.files[file]));
console.log(valid && bound && differ.length === 0 && service.errors.length === 0 ? 'pass' : `fail: ${differ.join(', ')}`);
})();Attestium and Audit Status
Two projects with different purposes.
Attestium
The library and the format: collecting facts on a machine, the evidence schema, and the checks against each kind of reference. Use it to build an attester or a verifier, to verify one thing, or to implement the format in another language.
Audit Status
A ready-made tool built on Attestium: one binary with an attester, invoked over a restricted SSH key, and a verifier that runs in CI and publishes reports and a status badge.
A project by Forward Email, the open-source, privacy-focused email service, which publishes verification results for its own production servers on status.forwardemail.net.