PAROLE

Pairwise attestation — no server, no accounts, no idp

A deepfake has the voice.
It does not have the key.

PAROLE asks one person exactly one kind of question and returns an answer signed by their own device, over a channel two humans paired themselves, once, by speaking a word to each other. A synthetic voice can imitate a cadence. It cannot produce a private key it was never given.

a CLI and browser tool · iroh peer to peer · Ed25519 signatures · BLAKE3 receipts

Pairing — once, before any question exists

Say a sigil out loud. Pin a key forever.

Before PAROLE will ask or answer anything, two devices meet exactly once. One side prints a sigil — a word and two short codes — and speaks it. The other types it back, live, on a call or in the same room.

That shared, spoken secret authenticates a key exchange (SPAKE2) that a listener without the sigil cannot complete, even recording every packet. Both devices then show the same 12-word fingerprint of the peer's actual key. A human has to read it and type a deliberate y before it's pinned. There is no trust-on-first-use, and a wrong sigil gets one attempt, not a retry.

sigil
Anchor WX42 3CL5
speak this to your peer. one attempt, 120 seconds, then it expires.
peer fingerprint — 96 bits, read before you pin it
gabbierluringclinichalter oddestjigglesedgierorgandy dukesrockerbailiffchigger

The ceremony — every question, every time

One bit, and it has to be earned.

A finance controller gets a call. The voice is right, the urgency is right, and none of that is evidence anymore. So instead of answering the call, they run one line:

parole ask cfo "did you request: wire 180,000 USD to Meridian LLC, invoice 4471?"

Try it below. The question text is signed inside both the question and the answer — a receipt doesn't just prove someone said yes, it proves what, specifically, they said yes to.

from: cfo · fingerprint gabbier…chigger ttl 300s
“Did you request: wire 180,000 USD to Meridian LLC, invoice 4471?”
answer yes/no — the full word, typed out.
no answer sent yet — the receipt log stays empty until you do.

The receipt — what's left afterward

Hash-chained. Signed. Readable from a public key alone.

Every question and answer is appended to a local, append-only log, one file per peer, each line chained to the last with BLAKE3. parole receipts verify bob walks the whole chain against the pinned key. Flip one byte, anywhere in the history, and verification fails.

A verified NO is the artifact you attach to the fraud report. It didn't come from a phone call anyone can dispute happened.

nkindpayloadchain
41Q_SENTwire 180,000 USD…c1a9…70e2
42A_RECVNO7fd3…114b
43Q_SENTstill need prod‑db admin?08e6…c9a5
44A_RECVYESb421…3f07

Three outcomes — every failure mode collapses to an exit code

Timeout and NO both mean stop. Only a verified YES exits zero.

exit 0
YES
Verified signature, correct peer, fresh question. Proceed.
exit 10
NO
A verified refusal, signed by the pinned key. Stop.
exit 11
TIMEOUT
No answer inside the TTL, default 300s. Stop.
exit 12
INVALID
Wrong key, replay, or tampered payload. Stop, and logged.

Get it

One binary. No accounts to create.

Exit codes are the enforcement API. A payment script, a change window, an access recertification — whatever needs the answer just checks the exit code. No webhook to register, no dashboard to check, no session to hold.

No terminal handy? Pair and answer straight from a browser — same wire protocol, same receipts, interoperates directly with the CLI.

# pair once, in person or on a trusted call
$ cargo install --locked parole
$ parole init
$ parole pair --name cfo
 
# then, every time it matters:
$ parole ask cfo "did you request: wire 180,000 USD to Meridian LLC, invoice 4471?" || exit 1