mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-02 08:47:26 +08:00
fix(wallet): harden keystore fallback, persist policy/history, wire gateway injection
Addresses review findings: - Remove insecure automatic encrypted-file credential-store fallback. now only uses real OS/keyctl-backed stores, or remains unavailable. Headless users must use explicit HERMES_KEYSTORE_PASSPHRASE if desired. - Add shared wallet runtime so tools/CLI/approval use the same configured providers and persisted policy state. - Inject keystore-backed secrets into gateway/headless startup too, so migrated .env stubs don't break messaging deployments. - Persist wallet policy state (freeze, daily totals, rate-limit timestamps, cooldown timestamps) across invocations. - Persist transaction history to disk across invocations. - Make owner-approved sends execute through the same runtime/policy path and record policy state after successful approved sends. - Fix wallet export by allowing explicit CLI export reads of sealed keys via dedicated requester path () instead of generic CLI reads. - Make CLI wallet sends evaluate policy before execution and honor freeze. - Align docs with actual crypto primitive (XSalsa20-Poly1305 via SecretBox) and current policy-config scope. Validation: - 129 tests passing - freeze persistence verified manually - wallet export verified manually
This commit is contained in:
@@ -33,11 +33,16 @@ hermes keystore init
|
||||
You'll be prompted to create a passphrase. This is needed each time Hermes starts. To avoid typing it every time:
|
||||
|
||||
```bash
|
||||
# Save to your OS credential store (macOS Keychain, GNOME Keyring, etc.)
|
||||
# Save to your OS credential store (macOS Keychain, Windows Credential Locker,
|
||||
# GNOME/KDE Secret Service, or Linux keyctl when available)
|
||||
hermes keystore remember
|
||||
|
||||
# Or set an env var (for Docker / systemd / headless)
|
||||
export HERMES_KEYSTORE_PASSPHRASE="your-passphrase"
|
||||
|
||||
Hermes intentionally does **not** fall back to a machine-derived encrypted file
|
||||
for remembered passphrases. In the current same-user execution model, that would
|
||||
be derivable by the local agent process and would weaken the keystore boundary.
|
||||
```
|
||||
|
||||
### 2. Create a wallet
|
||||
@@ -135,7 +140,7 @@ hermes keystore status Show keystore status
|
||||
### Encryption
|
||||
|
||||
- Master key derived from your passphrase via **Argon2id** (memory-hard KDF, 64MB)
|
||||
- Each secret encrypted with **XChaCha20-Poly1305** (AEAD, random nonce per write)
|
||||
- Each secret encrypted with **XSalsa20-Poly1305** via libsodium SecretBox (AEAD, random nonce per write)
|
||||
- Master key held in memory only — never written to disk
|
||||
- Keystore DB file permissions: `0600`, directory: `0700`
|
||||
|
||||
@@ -244,11 +249,20 @@ wallet:
|
||||
solana: "https://api.mainnet-beta.solana.com"
|
||||
ethereum: "https://eth.llamarpc.com"
|
||||
|
||||
# Agent wallet policy overrides (tightens defaults, cannot loosen)
|
||||
# Minimal policy overrides currently supported at runtime
|
||||
# (global/shared state, not per-wallet yet)
|
||||
agent_wallet:
|
||||
enabled: true
|
||||
auto_approve_below_native: "0.5"
|
||||
daily_limit_native: "5.0"
|
||||
max_per_tx_native: "1.0"
|
||||
rate_limit: "5/hour"
|
||||
auto_approve_below_native: "0.5" # maps to require_approval.above_native
|
||||
daily_limit_native: "5.0" # maps to daily_limit.max_native
|
||||
max_per_tx_native: "1.0" # maps to spending_limit.max_native
|
||||
```
|
||||
|
||||
:::note
|
||||
Per-wallet policy management and richer policy configuration are not fully surfaced yet. Today Hermes supports:
|
||||
- runtime RPC endpoint overrides via `wallet.rpc_endpoints`
|
||||
- a minimal set of global agent-wallet policy overrides via `wallet.agent_wallet`
|
||||
- durable freeze/rate-limit/daily-limit state across CLI invocations
|
||||
|
||||
More granular per-wallet policy editing is planned follow-up work.
|
||||
:::
|
||||
|
||||
Reference in New Issue
Block a user