StatVault

StatVault · Witness handshake

Sign our Merkle root in five minutes.

StatVault publishes a tamper-evident root over the entire evidence ledger every six hours. Any GitHub account can co-sign it with an ed25519 key from a free Actions runner. One external signer flips the trust model from self-anchored (we vouch for us) to federated (you watch us). No payment, no review, no gate.

Current federation

1

unique signer on file · 1 veteran · 0 trusted · 0 novice

Three steps

  1. Run npx -y github:VaultSparkStudios/statvault scripts/onboard-witness.mjs inside any repo you control (or use the YAML below). The script generates an ed25519 keypair, stores the public side, and writes the workflow file.
  2. Add the generated private key as a repo secret named WITNESS_PRIVATE_KEY. Optionally set a human-readable WITNESS_LABEL repo variable.
  3. Push and dispatch the workflow once. Within minutes your pubkey lands on /trust/merkle. You can stop at any time — receipts already co-signed stay verifiable forever.

Paste-ready workflow

Drop this at .github/workflows/statvault-witness.yml if you skip the script.

name: statvault-witness

on:
  schedule:
    - cron: "17 */6 * * *"
  workflow_dispatch: {}

jobs:
  witness:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: "20" }
      - name: Sign + post current Merkle root
        env:
          WITNESS_PRIVATE_KEY: ${{ secrets.WITNESS_PRIVATE_KEY }}
          WITNESS_LABEL: ${{ vars.WITNESS_LABEL || github.repository_owner }}
        run: |
          curl -fsSL https://statvault.org/api/v1/trust/merkle > /tmp/root.json
          node -e "
            const { createSign, createPrivateKey } = require('node:crypto');
            const fs = require('node:fs');
            const root = JSON.parse(fs.readFileSync('/tmp/root.json', 'utf8')).root;
            const key = createPrivateKey({ key: process.env.WITNESS_PRIVATE_KEY, format: 'pem' });
            const sig = createSign('SHA512').update(root).sign(key).toString('base64');
            const body = { merkleRoot: root, signature: sig, label: process.env.WITNESS_LABEL };
            fetch('https://statvault.org/api/v1/trust/witness', {
              method: 'POST',
              headers: { 'content-type': 'application/json' },
              body: JSON.stringify(body),
            }).then(r => r.text()).then(console.log);
          "

The signature is over the raw Merkle root string. No personal data leaves your runner. You can revoke at any time by deleting the secret — past co-signatures remain valid because they're anchored to the root they signed.