vavitien
v0.1.0
Published
Sign and verify Vavitien authorization proofs from JavaScript — the client half of the Vavitien SDK, wire-compatible with the Python verifier
Maintainers
Readme
vavitien (JavaScript SDK)
Sign Vavitien authorization proofs in JavaScript and submit them for verification over HTTP — wire-compatible, byte for byte, with the Python verifier.
const { prove, VavitienClient } = require('vavitien');
const client = new VavitienClient({
baseUrl: 'https://api.vavitien.com', // or your own `python -m vavitien.asgi`
apiKey: process.env.VAVITIEN_API_KEY,
// self-hosted servers expose /verify; the hosted service exposes /v1/verify
verifyPath: '/v1/verify',
});
const decision = await client.verify(prove({
privateKeyHex: process.env.VAVITIEN_AGENT_KEY, // stays on your side, always
agentName: 'refund-agent',
action: 'issue_refund',
payload: { amount: 200, customer_id: 'c1' },
audience: 'billing',
policyId: 'refunds',
expiresInSeconds: 300,
}));
if (decision.ok) {
// carry out the action — YOUR systems execute, Vavitien only decides
} else {
// a DENY is a decision, not an error: decision.reason says which rule fired
}A denial never throws — refusing an action is the service doing its job.
VavitienClient throws only when no verdict could be obtained at all (bad
credential, unreachable service), so "the payment was refused" can never be
confused with "the network flaked".
What is proven, and by what
| Claim | Evidence |
|---|---|
| The signable bytes match the frozen protocol v1 profile | test/vectors.test.js — every committed cross-language vector reproduced exactly, ed25519 verdicts included |
| A proof signed here verifies in the Python SDK | test/verify_against_sdk.py — 8 checks: honest proof, key_id agreement, five tamperings rejected, replay caught |
| The client behaves correctly against a real server | test/round_trip.py — allow, policy deny, replay, and a 401 that throws instead of masquerading as a denial |
| This signer and the n8n integration's cannot drift | test/drift_vs_n8n.js — identical bytes AND identical refusals on adversarial inputs |
Zero runtime dependencies — node:crypto and global fetch (Node ≥ 18).
Status: built and exercised, NOT published
Not on npm, not on the website. The npm name vavitien was verified unclaimed
on 2026-08-20 (the PyPI name of the same spelling was lost — deleted, not
yanked — so take the npm name deliberately and early). Before publishing:
- Decide the name and claim it (
vavitien). npm run prepublishOnlymust pass where it runs.- Point the README's hosted URL at an endpoint that actually serves.
- Only then may the website mention it — same rule as the n8n node.
