VaultysID is a decentralized identity framework. Every identity is a keypair you own — no central authority, no account server. Identities can sign, verify, encrypt to each other, and mutually authenticate through the handcheck protocol, a short challenge–response exchange that leaves both parties with a signed certificate of the relationship.
The same wire format is implemented in three languages and continuously tested for byte-for-byte interoperability.
- 🪪 DIDs out of the box — every identity resolves to a
did:vaultys:…identifier and a DID document. - 🔐 Modern cryptography — Ed25519 signatures, X25519 key agreement, DHIES encryption, HMAC/OTP derivation.
- 🛡️ Post-quantum ready — Dilithium (ML-DSA-87) and hybrid Ed25519 + Dilithium identities.
- 🔑 Hardware-backed keys — FIDO2 / WebAuthn (including PRF) for passkeys and security keys.
- 🤝 Handcheck protocol — mutual authentication with nonces, timestamps and signed metadata exchange.
- 📇 IdManager — contacts, apps, signed files and metadata on top of a pluggable storage layer.
- 🌐 Runs everywhere — Node.js, browsers, native Go binaries and Rust (incl.
cdylib).
| Language | Path | Package | Status |
|---|---|---|---|
| TypeScript (reference) | typescript/ |
@vaultys/id |
Node.js + browser, FIDO2, PQC |
| Go | go/ |
github.com/vaultys/vaultysid/go |
Library + vaultysid-cli, PQC |
| Rust | rust/ |
vaultysid crate |
Library, Dilithium, zeroized secrets |
Each folder has its own README with language-specific details.
pnpm add @vaultys/idimport { VaultysId, Challenger } from "@vaultys/id";
// Create identities (ed25519 by default, or "dilithium" / "dilithium_ed25519")
const alice = await VaultysId.generatePerson();
const bob = await VaultysId.generateMachine("dilithium_ed25519");
console.log(alice.did); // did:vaultys:…
// Sign & verify
const signature = await alice.signChallenge("hello");
VaultysId.fromId(alice.id).verifyChallenge("hello", signature, false); // true
// Handcheck: mutual authentication
const a = new Challenger(alice);
const b = new Challenger(bob);
a.createChallenge("p2p", "auth", 1);
await b.update(a.getCertificate());
await a.update(b.getCertificate());
await b.update(a.getCertificate());
a.isComplete() && b.isComplete(); // truego get github.com/vaultys/vaultysid/goid, _ := vaultysid.GeneratePerson()
fmt.Println(id.DID())
sig, _ := id.Sign([]byte("hello"))
err := id.Verify([]byte("hello"), sig) // nil when valid[dependencies]
vaultysid = { git = "https://github.com/vaultys/vaultysid" }let id = vaultysid::VaultysId::generate_person().await?;
println!("{}", id.did());The Go implementation ships vaultysid-cli, a single static binary:
curl -fsSL https://raw.githubusercontent.com/vaultys/vaultysid/main/scripts/install.sh | bashvaultysid-cli generate personIt covers identity generation, signing/verification of data, challenges and files, DHIES file encryption, and an IdManager store (manager init | contacts | apps | save-contact …). Windows users can use scripts/install.ps1.
| Type | Value | Notes |
|---|---|---|
| Machine | 0 |
Software keys, servers and devices |
| Person | 1 |
Software keys for individuals |
| Organization | 2 |
Software keys for organizations |
| FIDO2 | 3 |
Keys held by a security key / passkey |
| FIDO2 PRF | 4 |
FIDO2 with the PRF extension for encryption |
Software identities can use ed25519, dilithium or the hybrid dilithium_ed25519 algorithm.
The protocols are documented as RFC-style specs in rfc/:
- DID.md — Decentralized Identity Keyring: identity format, key derivation, DID documents.
- PROTOCOL.md — Web of Trust / handcheck protocol: mutual authentication and relationship certificates.
- ENCRYPTION.md — File encryption format: headers, whole-file and chunked modes.
.
├── typescript/ Reference implementation (@vaultys/id)
├── go/ Go library + vaultysid-cli
├── rust/ Rust crate
├── rfc/ Protocol specifications
├── interops/ Cross-language interoperability test runners
├── kmip-client-go/ KMIP integration tooling
├── scripts/ CLI installers (sh / PowerShell)
└── test/ Repo-level integration tests
TypeScript (Node.js 20+, pnpm)
cd typescript && pnpm install && pnpm build && pnpm testGo (Go 1.25+)
cd go && make build && go test ./...Rust (Rust 1.91+)
cd rust && cargo testCross-language interoperability — verifies that identities, signatures, handchecks and encrypted payloads produced in one language are accepted by the others:
./interops/run-all-interops.shSaltpack encryption (TypeScript ⇄ Go) — encrypt / signcrypt / decrypt must open across languages. Each side writes vectors the other opens (CI regenerates both on every change, .github/workflows/go.yml):
cd typescript && pnpm test:saltpack:vectors # TypeScript encrypts…
cd ../go && go test ./test/compatibility -run Saltpack # …Go decrypts
cd test/compatibility && go run generate_saltpack_vectors.go # Go encrypts…
cd ../../../typescript && pnpm test:saltpack:go # …TypeScript decryptsNew features land in the TypeScript reference implementation first, then in Go and Rust, with interop tests proving the three stay byte-compatible. Please keep backward compatibility with existing identities and update the RFCs when the wire format changes.
MIT © Vaultys