{"_id":"@axiorank/log-witness","_rev":"2-acbb394cbf5f0106a209ecd7a4fd6f6f","name":"@axiorank/log-witness","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@axiorank/log-witness","version":"0.1.0","keywords":["axiorank","transparency-log","witness","rfc6962","certificate-transparency","tamper-evident","audit","split-view","ed25519","self-hosted"],"author":{"name":"AxioRank"},"license":"MIT","_id":"@axiorank/log-witness@0.1.0","maintainers":[{"name":"tejaswi.s","email":"tejaswi33@gmail.com"}],"homepage":"https://axiorank.com","bugs":{"url":"https://github.com/frostyhand/AxioRank/issues"},"bin":{"axiorank-log-witness":"dist/cli.js"},"dist":{"shasum":"ef3542cee5976104eecfbe7ce00776d4eb19f217","tarball":"https://registry.npmjs.org/@axiorank/log-witness/-/log-witness-0.1.0.tgz","fileCount":17,"integrity":"sha512-cTVAwArfuH9pWAStTiAQbodCFQTRVwb3NQGUiNOa+bBK/cTMEkY2Qa+dDG8lUkugqsjTfddL+fZQCBZ1Ibf6nA==","signatures":[{"sig":"MEUCIQDykPlQH5PWISSVjogz+w44Npzpj+ZE+xCgC6kufBs4LAIgINhzrMWOnPAKXB33pTG1pHq3EFTWw7OJcwm1XhRooNg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":85410},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"gitHead":"fb77199cd50cc5f237d0c2320e4f7be3321d952f","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"tejaswi.s","email":"tejaswi33@gmail.com"},"repository":{"url":"git+https://github.com/frostyhand/AxioRank.git","type":"git","directory":"packages/log-witness"},"_npmVersion":"10.9.8","description":"A self-hostable witness for an AxioRank audit transparency log. Countersigns each sealed signed tree head with an Ed25519 key you control, so your records are an independent split-view defense. Zero runtime dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","vitest":"^4.1.8","typescript":"^6.0.3","@types/node":"^22.10.2","@axiorank/audit-verify":"workspace:^"},"_npmOperationalInternal":{"tmp":"tmp/log-witness_0.1.0_1781203685746_0.646619074746072","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@axiorank/log-witness","version":"0.1.1","description":"A self-hostable witness for an AxioRank audit transparency log. Countersigns each sealed signed tree head with an Ed25519 key you control, so your records are an independent split-view defense. Zero runtime dependencies.","license":"MIT","homepage":"https://axiorank.com","bugs":{"url":"https://axiorank.com/support"},"author":{"name":"AxioRank"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","bin":{"axiorank-log-witness":"dist/cli.js"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./package.json":"./package.json"},"sideEffects":false,"engines":{"node":">=18"},"keywords":["axiorank","transparency-log","witness","rfc6962","certificate-transparency","tamper-evident","audit","split-view","ed25519","self-hosted"],"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","test":"vitest run"},"publishConfig":{"access":"public"},"devDependencies":{"@axiorank/audit-verify":"workspace:^","@types/node":"^22.10.2","tsup":"^8.3.5","typescript":"^6.0.3","vitest":"^4.1.8"},"_id":"@axiorank/log-witness@0.1.1","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-VcWZAgSVgZyj+Kg2Z/acuD0mnBv8j6KeOh0g3RH739rbg2XDuwDiAN7KlVj7PWFEXqHCN2Ug5JkL7d8GwpQDpA==","shasum":"765515a92e13c2d3414910bd9c40077e85890218","tarball":"https://registry.npmjs.org/@axiorank/log-witness/-/log-witness-0.1.1.tgz","fileCount":17,"unpackedSize":85250,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCwGoE5ROFxAZDJq4z2jjghCC0jdmro6luJhOIvhiJR7wIhAIwVVls2XZOXEcc9gtw2Z0SImr2TbhEuh/l8q5ngO0L2"}]},"_npmUser":{"name":"tejaswi.s","email":"tejaswi33@gmail.com"},"directories":{},"maintainers":[{"name":"tejaswi.s","email":"tejaswi33@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/log-witness_0.1.1_1785415311643_0.43335147282777453"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-11T18:48:05.591Z","modified":"2026-07-30T12:41:53.924Z","0.1.0":"2026-06-11T18:48:05.929Z","0.1.1":"2026-07-30T12:41:51.791Z"},"bugs":{"url":"https://axiorank.com/support"},"author":{"name":"AxioRank"},"license":"MIT","homepage":"https://axiorank.com","keywords":["axiorank","transparency-log","witness","rfc6962","certificate-transparency","tamper-evident","audit","split-view","ed25519","self-hosted"],"description":"A self-hostable witness for an AxioRank audit transparency log. Countersigns each sealed signed tree head with an Ed25519 key you control, so your records are an independent split-view defense. Zero runtime dependencies.","maintainers":[{"name":"tejaswi.s","email":"tejaswi33@gmail.com"}],"readme":"# @axiorank/log-witness\n\nA self-hostable **witness** for an AxioRank audit transparency log.\n\nAxioRank's audit log is tamper-evident on its own (Merkle-sealed, signed tree\nheads). What a log operator cannot prove by itself is that it never showed two\ndifferent histories to two different observers, the \"split view.\" The defense is\nexternal witnessing: an independent party countersigns each sealed head. If the\nlog ever forked, the witness's signatures over the two heads expose it.\n\nThis package is that witness. You run it on infrastructure **you** control, with\nan Ed25519 key only you hold. Point a workspace's witness URL at it, and every\nsealed head is countersigned by a key AxioRank does not have, so your records are\na genuinely independent attestation.\n\n## Run it\n\n```bash\nnpx @axiorank/log-witness --port 8787\n```\n\nGenerate a stable key (do this once, keep it secret):\n\n```bash\nnode -e \"const {generateKeyPairSync}=require('node:crypto');console.log(generateKeyPairSync('ed25519').privateKey.export({format:'der',type:'pkcs8'}).toString('base64'))\"\n```\n\n```bash\nAXR_WITNESS_NOTE_KEY=\"<base64-from-above>\" \\\nAXR_WITNESS_NAME=\"note:acme-witness\" \\\nnpx @axiorank/log-witness --port 8787\n```\n\nWithout `AXR_WITNESS_NOTE_KEY` an ephemeral key is generated and a restart\ninvalidates every record. That is fine for a quick try and never for production.\n\nOptionally require a shared bearer on the witnessing endpoint:\n\n```bash\nAXR_WITNESS_AUTH_TOKEN=\"...\" npx @axiorank/log-witness\n```\n\n## HTTP API\n\n| Route | Purpose |\n| --- | --- |\n| `POST /witness` | Body `{ signedTreeHead, signedAt }`. Returns a `WitnessRecord`. |\n| `GET /key` | `{ witness, keyId, publicJwk }`. Pin this out-of-band. |\n| `GET /healthz` | Liveness. |\n\nA `WitnessRecord` is an Ed25519 signature over\n`canonicalize({ subjectHash, witness, signedAt })`, where `subjectHash` is the\nSHA-256 of the canonical signed tree head with its own signature stripped. It is\nverified by [`@axiorank/audit-verify`](https://www.npmjs.com/package/@axiorank/audit-verify)\nand the [`@axiorank/log-watchdog`](https://www.npmjs.com/package/@axiorank/log-watchdog)\nmonitor.\n\n## Connect it to AxioRank\n\nIn **Settings → Security → Witnesses** (Enterprise plan), add this daemon's URL.\nAxioRank POSTs each sealed head to it and stores the returned record alongside\nthe checkpoint, exposed on the public log so anyone, including you, can verify\nthe split-view defense with the watchdog.\n\n## Programmatic use\n\n```ts\nimport { createWitnessServer } from \"@axiorank/log-witness\";\n\nconst witness = createWitnessServer({ name: \"note:acme\", rawKey: process.env.KEY });\nawait witness.listen(8787);\n```\n\nZero runtime dependencies; built on `node:http` and `node:crypto`. MIT licensed.\n","readmeFilename":"README.md"}