Docs · Agent sign-in
Sign in with your Holochain agent
A site opened from inside a hApp can sign a person in with their Holochain agent key instead of a passkey. It lands in the same OpenID response, with acr set to agent.
Why a zome signs
The conductor has no API that signs bytes for a UI, and the JavaScript client signs with a generated key that is not the agent key. So hApp Auth ships the path itself: a small coordinator zome that signs one kind of message, and a helper that carries it.
The signing path
- The
happ_authcoordinator zome (Rust, depends only onhdk) has one function,sign_happ_auth_challenge. The caller supplies only the purpose (from a closed list), the nonce, the account reference and the expiry. The zome fills in the origin, its own DNA hash and its own agent key, builds the message below and signs it with the agent key. A page can never choose the bytes, so the function is not a signing oracle, even inside a website host. @happauth/holochain, the JavaScript helper, fetches a challenge, calls the zome function through anyAppClient(websocket, Kangaroo, Moss, Holo Web Conductor’s client) and posts the signature back.- A maker adds the zome to a running hApp with
UpdateCoordinators, which does not change the DNA hash. This is tested on a multi-DNA app before the guide gives the steps.
The signed bytes
Every signature is over a domain-prefixed message hApp Auth defines, never a bare nonce or a bare 32-byte hash, so a signature cannot be replayed into another protocol. Purposes in v1: bind, signin, memproof-request.
"happ-auth/v1/<purpose>\0" || SHA-256(canonical challenge)
challenge = {
origin: "https://happauth.com",
purpose, // bind | signin | memproof-request
nonce, // 16 bytes
account_ref,
dna_hash, // filled in by the zome, never by the page
agent_key, // filled in by the zome, never by the page
expires_at,
}
What it proves
An agent sign-in proves that a conductor session holding the key answered. Any client with an app-interface token could have asked, so it does not prove a person is present.
Use acr = urn:happauth:loa:agent to save a person a touch. Require a passkey for account actions on your site; hApp Auth does the same on its own.
Holo Web Conductor
Holo Web Conductor’s signJoiningNonce signs 16–128 bytes without a prompt. The helper passes it the whole domain-prefixed message (50–62 bytes), never the bare hash. Because it signs for any script on the origin, a sign-in through it is the weakest agent sign-in there is.
Linking keys across devices is on Holochain multi-device identity.