Skip to content

End-user auth (hosted tier)

The hosted tier gives your users embedded wallets: XKOVA operates the signing parties, but every signature is gated by that user’s own token from your identity provider. Your users get a Web2-simple wallet, and neither you nor XKOVA can move their funds without a valid token from them.

This guide wires that up end to end. For the custody model behind it, see How it works.

Tell XKOVA which tokens to trust: your IdP’s JWK Set (the public keys XKOVA verifies end-user tokens against) and the audience it expects on those tokens.

await xkova.setEndUserAuth({
jwks: {
keys: [ /* your IdP's public JWKs */ ],
},
audience: "xkova-wallets", // the `aud` claim your IdP mints on end-user tokens
});

This is org-level configuration; hosted vaults created afterward are gated by it. When your IdP rotates its signing keys, re-register the updated JWK Set.

Bind the vault to one end user with their stable subject — the sub claim your IdP issues for that person:

const vault = await xkova.createVault({
tier: "hosted",
name: "wallet:user-8471",
end_user_sub: "user-8471", // must match the `sub` in that user's tokens
});

Derive wallets under it exactly as for any vault (Manage keys).

3. Attach the user’s token to each signature

Section titled “3. Attach the user’s token to each signature”

On every send, pass the end user’s JWT. XKOVA verifies it — signature valid against the registered JWKS, aud equal to your configured audience, not expired — and that its sub matches the vault’s end_user_sub. Only then does signing proceed.

await xkova.sendNative({
wallet,
chainId: 43113,
to: "0xRecipient…",
amount: "5000000000000000",
idempotencyKey: "user-8471-tx-001",
endUserJwt: userToken, // from the user's authenticated session in your app
});

endUserJwt works on every send helper and on submitIntent. A hosted-tier signature without a valid end-user token is rejected — no partial signature is produced.

  • Your users authorize their own transactions with the login they already have; you forward their token, you don’t custody their key.
  • XKOVA can’t sign unilaterally for a hosted vault — the user’s token is required each time, on top of the vault’s policy and spend limits.
  • No key ever exists to export or steal, same as every tier.
  • The JWT must come from the user’s authenticated session in your app — mint or forward it per request; never hardcode or share one across users.
  • Keep tokens short-lived; XKOVA rejects expired ones. A signature needs a currently-valid token, so refresh before long-running flows.
  • The token authorizes one signature. It is not a session with XKOVA and grants nothing beyond the matching vault.