Documentation Index
Fetch the complete documentation index at: https://docs.vane.build/llms.txt
Use this file to discover all available pages before exploring further.
Why Ed25519
Vane uses Ed25519 (EdDSA with the Curve25519 base field) for all cryptographic signing. The choice is deliberate: No parameter choices. ECDSA requires a fresh random nonce per signature. If that nonce is ever reused — even once — the private key is exposed. Ed25519 uses a deterministic nonce derived from the private key and the message. There is no random number to generate wrong. No algorithm confusion. RSA and ECDSA have many modes: different key sizes, different hash functions, different padding schemes. Getting this wrong is the source of entire classes of vulnerability. Ed25519 has exactly one configuration.crypto.sign(null, data, privateKey) works because the algorithm is implied by the key type — there is no way to accidentally use the wrong digest.
Compact. 32-byte public keys, 64-byte signatures. A passport fits in a small HTTP header. A full attestation record is readable in a curl response.
Built into Node.js. Ed25519 has been available in node:crypto since Node 12. Vane has zero external cryptographic dependencies. No supply-chain risk from a crypto library you didn’t write.
Key generation
Each company gets one Ed25519 key pair, generated at registration:COUNSEL_MASTER_KEY is set, private keys are encrypted with AES-256-GCM before storage. See Envelope Encryption.
Key ID derivation
Thekid claim in JWT headers is derived deterministically from the public key:
kid.
Signing attestation records
Each attestation record’shash is computed as:
signature is:
sign(null, ...) — the first argument is null because the hash function is determined by the key type (Ed25519 uses SHA-512 internally; you do not choose it).
Signing JWTs and passports
JWT headers and payloads are base64url-encoded. The signature covers the concatenationheader.payload:
What signing protects
A valid Ed25519 signature over a hash proves two things:- Integrity. The signed data has not been modified since it was signed. Any alteration — even a single byte change in a payload — produces a different hash, which the signature no longer covers.
- Origin. The signature was produced by the holder of the private key. Since each company’s private key is unique to that company, a valid signature is proof of which company produced the record.
- When the action occurred beyond the timestamp field (which itself is covered by the hash).
- That the server was not compromised at signing time.
SPKI PEM as the canonical public key format
All public key endpoints return SPKI PEM. This is the formatcreatePublicKey() accepts directly. If you need to verify signatures from another language, SPKI is the interoperable format supported by OpenSSL, libsodium, and most JVM crypto libraries.