Storage & Security - Dynamic

What you must persist

For storage mechanics (KMS envelope encryption, schemas, checklists), see Storage Best Practices.

Artifact Storage class Lifetime If you lose it
Session private key (privateKeyJwk or KMS/HSM key) Secrets vault, KMS, or HSM — or keep the key non-extractable in KMS and never materialize a JWK. Never a plain file or database column. Life of the agent session Signed-session proofs can no longer be produced; backup and recovery calls fail. Generate a new key pair and sign the user in again to bind it.
User JWT Encrypted at rest in your app store, or memory only Until refreshed or expired, bounded by refreshExp The user signs in again. Update the stored value on every refreshAuthToken() call — the old token is superseded.
Backup password Secrets vault. It is the PBKDF2 password for the key-share backup — never log it. Life of the wallet Dynamic-stored backups encrypted with it are permanently undecryptable.
walletMetadata (including externalServerKeySharesBackupInfo) Durable app store (Redis, Postgres). Non-sensitive. Life of the wallet fetchWalletMetadata recovers identity fields only — it does not return externalServerKeySharesBackupInfo, and no SDK endpoint does. Operations that need backup state (sign with auto-recovery, refresh, reshare, password checks) fail.
externalServerKeyShares Secrets vault or HSM. Sensitive. Life of the wallet Recoverable from Dynamic only if backed up with backUpToDynamic: true; otherwise signing is permanently impossible.
Agent signing token (autonomous mode only) Secrets vault, KMS, or HSM Life of the agent’s Dynamic user identity The Dynamic user is keyed to this key’s public address. Once the current JWT can no longer be refreshed, the agent cannot sign in as that user again, and the user’s wallets are unreachable through this flow.
OTP codes, external JWTs, session nonces, decrypted key shares Memory only — never persist Single use Nothing: request a new code, token, or nonce.

Mutating operations (refreshWalletAccountShares, reshare, updatePassword) return new backupInfo. Merge it into your stored walletMetadata.externalServerKeySharesBackupInfo immediately — subsequent operations read stale metadata and fail otherwise.

Security