Verify a VAID without talking to us.
Three steps. About twenty lines. No account.
By the end of this page you will have minted a VAID, signed a request with the key it binds, and verified both against public keys alone. Nothing here calls a service we run, nothing asks who you are, and nothing needs a credential from us. That is not a convenience of the quickstart. It is the property the whole primitive exists to provide, so the honest way to show it is to let you run it.
Pick a language — or skip that.
The reference implementation is open source under Apache-2.0. There is no server, no database and no runtime to stand up, because verification is a computation and not a request.
If you work in a coding agent, one command
vaid-skill is an Agent Skill: it teaches your agent when to mint a VAID, how to
present one, and how to check one it was handed. It is a thin wrapper over the same published
SDKs below and implements no cryptography of its own.
npx vaid-skill
It detects which agents are present and installs into each:
Claude Code, Codex, Cursor,
Gemini CLI and GitHub Copilot. Add --global for
your home directory instead of this project, or --dry-run to see the plan and
change nothing. Re-running it is safe: the agents that share one context file get a delimited
block rewritten in place, never a second, drifting copy.
The skill is also published from this domain, for the skills CLI:
npx skills add https://solara.associates
This reads /.well-known/agent-skills/index.json,
which publishes a SHA-256 for the skill file beside it. The CLI recomputes that hash over the
bytes it downloaded and installs nothing if the two disagree — so a substituted file fails
rather than installs. It fetches the skill only; the vaid commands below still come
from the published package, which is why the skill invokes them as
npx -p vaid-skill. Use npx vaid-skill above if you want both in one step.
Four verbs, and there is no fifth
vaid mint issue a VAID — or, with --parent, an attenuated child
whose authority is a strict subset of yours
vaid present package one into the single line you send to someone
vaid verify check one you received, offline, against a pinned key
vaid revoke mark one revoked ON THIS MACHINE ONLY — read below verify does and does not tell you
It establishes authenticity, expiry, delegation containment, and whether the issuer configured a
real identity. It does not consult revocation, and it cannot: there is no
published revocation list, and an offline verifier could not reach one if there were. Read a
pass as genuinely issued and in date, never as currently authorised. That is
also why vaid revoke only writes a local file — it says so on every run.
vaid-skill is 0.1.3 today. Prefer the raw
CLI? npx -p vaid-skill vaid --help works without installing the skill into anything —
npx resolves its argument as a package, so -p is what reaches a
bin whose name is not the package's.
Or use the SDKs directly
cargo add vaid-pop vaid-client vaid-mint cargo add ring serde_json base64 sha2 hex
pip install vaid-pop vaid-mint
npm install vaid-pop vaid-client vaid-mint
vaid-pop is 0.2.1 on crates.io,
0.2.0 on PyPI and
0.3.0 on npm. Byte-for-byte
agreement between them is asserted at the frozen conformance vector, never at the version number,
and step 03 is how you confirm that yourself rather than take it from this page.
The whole loop, in one file.
Mint a VAID, sign a request with the key it binds, then verify both the VAID and the request against public keys alone. The verifier half of each snippet holds a public key and the request, and nothing else. It never calls the mint that issued the identity, because it does not need to.
use base64::Engine;
use ring::rand::SystemRandom;
use ring::signature::{Ed25519KeyPair, KeyPair};
use sha2::{Digest, Sha256};
use vaid_client::RequestSigner;
use vaid_mint::{verify_vaid_authenticity, AgentClass, ReferenceIssuer, TenantId, VaidIssuer};
use vaid_pop::{request_auth::RequestAuthPayload, vaid_pop::verify_signed_payload};
fn main() {
let pkcs8 = Ed25519KeyPair::generate_pkcs8(&SystemRandom::new()).unwrap();
let agent_key = Ed25519KeyPair::from_pkcs8(pkcs8.as_ref()).unwrap(); // the agent holds this
let issuer = ReferenceIssuer::ephemeral(24, "vaid.example").unwrap(); // your own mint
let vaid = issuer.issue_vaid_with_key(
AgentClass::new("orchestrator"), "1.0.0".into(), TenantId::new("acme"), None,
vec!["data.acme".into()], vec!["read".into()],
agent_key.public_key().as_ref().to_vec()).unwrap();
let body = br#"{"query": "select 1"}"#;
let signer = RequestSigner::from_vaid_json(&serde_json::to_vec(&vaid).unwrap(), agent_key).unwrap();
let headers = signer.sign_headers("POST", "/query", body).unwrap();
// Verifier side: public keys and the request. No call to the mint.
let payload = RequestAuthPayload {
vaid_id: vaid.vaid_id(), method: "POST".into(), path: "/query".into(),
body_sha256: hex::encode(Sha256::digest(body)), tenant_id: vaid.tenant_id().as_str().into(),
timestamp: headers.timestamp.parse().unwrap(), client_nonce: headers.nonce.clone(),
};
let sig = base64::engine::general_purpose::STANDARD.decode(&headers.signature).unwrap();
println!("vaid authentic: {}", verify_vaid_authenticity(issuer.kernel_public_key(), &vaid));
println!("request signed by holder: {}", verify_signed_payload(&payload, vaid.public_key_der(), &sig));
} import base64, hashlib from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from vaid_mint import ReferenceIssuer, verify_vaid_authenticity from vaid_pop import RequestSigner, build_request_auth_payload, verify_signed_payload agent_key = Ed25519PrivateKey.generate() # the agent holds this issuer = ReferenceIssuer.ephemeral(24, "vaid.example") # your own mint vaid = issuer.issue_vaid_with_key( agent_class="orchestrator", version="1.0.0", tenant_id="acme", parent_vaid=None, scope_boundary=["data.acme"], capability_set=["read"], public_key_der=agent_key.public_key().public_bytes_raw()) body = b'{"query": "select 1"}' headers = RequestSigner(vaid=vaid, private_key=agent_key).sign_headers("POST", "/query", body) # Verifier side: public keys and the request. No call to the mint. payload = build_request_auth_payload( vaid_id=vaid["vaid_id"], method="POST", path="/query", body_sha256=hashlib.sha256(body).hexdigest(), tenant_id=vaid["tenant_id"], timestamp=headers["x-synthera-timestamp"], client_nonce=headers["x-synthera-nonce"]) signature = base64.b64decode(headers["x-synthera-signature"]) print("vaid authentic:", verify_vaid_authenticity(issuer.kernel_public_key(), vaid)) print("request signed by holder:", verify_signed_payload(payload, vaid["public_key_der"], signature))
rust $ cargo run
vaid authentic: true
request signed by holder: true
py $ python quickstart.py
vaid authentic: True
request signed by holder: True Do not take the interop claim from us.
Every package in all three languages ships a conformance firewall as an executable. It reproduces the frozen vectors from the package you actually installed, not from a copy in our repository and not from this page. Run it wherever you like and compare the hex by eye: same digest, same signature, different runtimes, different version numbers.
cargo install vaid-pop vaid-pop-conformance
vaid-pop-conformance vaid-mint-conformance
npx -p vaid-pop vaid-pop-conformance npx -p vaid-mint vaid-mint-conformance npx -p vaid-client vaid-client-conformance
CROSS-LANGUAGE PoP FIREWALL: PASS — installed signer == frozen vectors, byte-for-byte
request digest = ee474ba87d703ebeacf663d7d6a2f15319bdef285c5b702e336d0f4af5b61327
request signature = 77e79744c362d352ce678992a3e3934fa57c33c3f307f6ffbe6ffc4ec5e726e0
96844fd8552db819b21a3e49e3b7796e23d1e10d4a03699285df4871f62e1502 If your own implementation reproduces those bytes, it conforms. If it does not, the diff shows where it diverged. That is the entire interoperability contract, and it is checkable by a stranger who has never spoken to us, which is the only kind of claim worth making about identity.
SYNTHERA is the trust layer for multi-agent systems: every agent gets a verifiable identity, scoped authority and a tamper-evident record, so software from different teams, vendors and frameworks can act on each other’s behalf without custom glue between every pair.
It ran. Now tell us what broke.
VAID is an interoperability contract, and contracts get better under adversarial reading. If you ran this and something was wrong, unclear, or missing, that is the most useful thing you can send us.