Skip to content

Session Keys

Session keys let a parent account delegate limited signing authority to a secondary ed25519 key. They are designed for automation and low-risk flows where the parent key should stay offline.

A transaction is treated as a session key transaction when:

  • payer != authorizer

In that case, the execution engine looks up a session key descriptor under the payer (parent) and enforces its constraints.

Session constraints are enforced on every transaction:

  • Per-tx value limit (max_value_per_tx)
  • Total budget (total_budget, cumulative across the session)
  • Allowed contracts (allowlist by address)
  • Allowed selectors (allowlist by 4-byte function selector)
  • Expiry (expires_at block height)
  • Revocation (explicitly revoked by the parent)

A session becomes inactive if it is revoked, expired, or has exhausted its budget.

Session keys are assigned a dedicated nonce_lane on creation. Transactions signed by the session key should use:

  • nonce_space.lane = <assigned nonce_lane>
  • nonce_space.tag = "" (v1 ignores tags)

This isolates session key nonces from the parent account’s main lane.

Session keys are stored under the parent account. Creation returns a session_key_id and the nonce_lane to use for session transactions.

The current v1 lookup derives the session key ID from the public key (blake3(pubkey)), so the returned ID is stable for a given session key.

A session transaction should:

  • Use the session key as authorizer (ed25519 pubkey address)
  • Use the parent as payer
  • Use the session’s nonce_lane

During execution the engine:

  1. Verifies the signature against the session key
  2. Looks up the session descriptor under the parent
  3. Enforces constraints (value limits, allowlists, expiry, budget)
  4. Updates spent_so_far on success

Revocation flips a revoked flag on the descriptor. Revoked or expired sessions remain in the index for audit, but are not active.

Session key management is implemented by the session_key_* service in src/rpc/session_keys.rs. Check your node build for endpoint exposure.

{
"parent": "0x...",
"session_pubkey": "0x...",
"constraints": {
"max_value_per_tx": "1000000",
"total_budget": "10000000",
"allowed_contracts": ["0x..."],
"allowed_selectors": ["0x12345678"]
},
"expires_at": 123456,
"created_at": 123400
}
{
"parent": "0x...",
"session_pubkey": "0x..."
}
  • session_key_get returns the descriptor plus an is_active flag.
  • session_key_list returns descriptors for all keys under a parent, including revoked or expired sessions.

Common rejection reasons include:

  • SESSION_KEY_NOT_FOUND
  • SESSION_CONTRACT_NOT_ALLOWED
  • SESSION_SELECTOR_NOT_ALLOWED
  • SESSION_VALUE_EXCEEDED
  • SESSION_BUDGET_EXHAUSTED

See /reference/error-domains/ for codes.

  • Use short expiries and tight allowlists for automation keys.
  • Use a low max_value_per_tx and a bounded total_budget.
  • Treat session keys as hot keys; rotate and revoke often.
  • /reference/error-domains/ for session key reject reasons
  • src/core/session_keys.rs for the data model
  • src/core/execution/session.rs for enforcement logic