Responsibility boundaries
The onchain validator checks the contract, selector, calldata rules, native value limit, time window, usage limit, and any crosschain claim permit encoded in the approved session. A request outside those rules fails even if Rhinestone prepared or forwarded it.
Names and ABI metadata shown during review improve readability only. Only Rhinestone’s maintained clear-signing registry can supply verified display metadata; app-supplied metadata is not an authorization boundary.
Protect the signer
Treat a session key as a bearer credential for everything inside its scope.- The
sessionoption onsendIntent()takes a viemLocalAccount. WithprivateKeyToAccount(), keep the extractable private key in protected local or backend secret storage appropriate to the grant’s value. - A non-exportable KMS or HSM key needs a custom
toAccount()signer; that integration is outside this guide. - If a browser must sign, keep the scope short-lived and low-value. Any script that can read the key can use it.
- Separate keys by user, account, environment, and purpose. Do not reuse one signer across unrelated grants.
- Persist the grant ID, account, signer address, private key, and handle together. Refuse to sign unless the stored account and signer match the handle.
- Bind your own backend requests to the authenticated application user and expected smart account before allowing a signing job.
- Stop scheduling a function on a chain as soon as its counter is exhausted. Other function or chain counters can remain active. Stop all work on expiry or suspected compromise. Onchain rejection is the final backstop, not normal control flow.
Recover grant metadata
Your application can recover public grant records after local handle loss. The user must have an active embedded-wallet session in the account namespace that created the grant.wallet is the @rhinestone/wallet client from Accounts.
rpId; its server-authorized sibling origins then use that shared RP and account namespace. A matching clientId alone does not share the account namespace. Reuse the same clientId, rpId, and authenticated account configuration when recovering a shared-RP grant.
The recovered handle contains no private signing capability. Pair it only with a signer whose public address matches sessionKeyHandle.sessionKeyAddress and whose stored account matches sessionKeyHandle.accountAddress. If the private key was lost, create a new signer and grant rather than pretending the old session is recoverable.
Revoke authority
Revoke a grant withrevokeSessionGrant(). The user must be signed in to the account that owns the grant; they review the revoke and sign it with their passkey, and it runs on every chain the grant is enabled on.
success is true only when the revoke landed on every chain. Each chain whose revoke completed shows as revoked in listSessionGrants(); authority stays active on any chain whose revoke failed.
Use short expiry windows, low per-call caps, and low per-function use counts so that a leaked key’s reach stays small until revocation lands. Fail closed when grant state or signer consistency cannot be confirmed.
Incident response
If a signer may be compromised:- Stop every worker and browser task that can use it, and reject new signing requests.
- Preserve the account address, grant ID, signer address, handle, and affected chain IDs for response.
- Revoke the grant with
revokeSessionGrant()and checkchainResultsfor every affected chain. - Treat every unexpired function and chain counter as usable until its onchain configuration is confirmed removed or its limits expire.
- Remove the signer from application storage, then create a narrower replacement only after identifying the exposure.