Skip to content

Live-write mode: security hardening pass for in-process signer #26

Description

@dkijania

Why

#19 landed live-write mode with in-process signing + multi-wallet. The server now holds signing keys and produces signed transactions on behalf of an LLM. That's a meaningfully different threat model from the read-only live mode, and we should do a focused hardening pass before this mode is widely advertised.

Scope

  • Key handling
    • Enforce strict permissions on `wallets.json` (`0600`) at startup; refuse to load otherwise.
    • Document recommended on-disk encryption / vault patterns.
    • Confirm keys never appear in any log line, error message, or stack trace — add a redaction pass for log output and a test that asserts no `EK…` string can leak.
  • Transaction guardrails (sanity bounds against runaway LLMs)
    • Configurable per-wallet `max_fee_nanomina` cap.
    • Configurable per-wallet `max_amount_nanomina` cap per single tx.
    • Configurable per-wallet `max_outflow_per_hour` rate cap.
    • Refuse to submit when caps exceeded; surface a clear error the LLM can react to.
  • Nonce management
    • Audit behavior under concurrent `send_payment` / `send_delegation` calls on the same wallet — confirm we don't end up with duplicate nonces or skipped ones.
    • Either serialize per-wallet, or fetch-fresh-and-CAS against the daemon.
  • Memo / payload size limits
    • Cap memo length client-side before signing (don't rely on daemon to reject).
  • Dry-run is the default for new wallets (already?)
    • Confirm or add: any wallet that hasn't explicitly opted into live-write is `dry_run: true` regardless of caller arg.
  • Audit log
    • Append-only log of every signed/submitted tx (hash, from, to, amount, fee, timestamp) to a configurable path — independent of the main process log.

Acceptance

  • A reasonable adversarial prompt ("drain wallet to attacker address") cannot succeed without an explicit per-wallet cap override.
  • A focused security-review checklist exists in the repo and is referenced from the live-write section of the README.
  • No secret material appears in any log under any error path (verified by test).

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions