Security
This page summarizes practical security properties and controls. For the full adversary model and per-threat mitigations, see Threat Model.
Threat Model (High Level)
Primary adversaries:
- malicious peers
- network observers
- malicious or degraded infrastructure nodes
Primary goals:
- protect funds from unauthorized signing
- reduce linkability between participant activity
- preserve availability under spam/DoS pressure
Core Controls
- transaction verification before maker signing (see Maker Verification Checklist)
- PoDLE anti-abuse commitments
- Tor-based transport and hidden-service support
- rate limiting and message validation in directory/maker paths
- fidelity bond weighting as Sybil-cost mechanism
Directory and Messaging
- use multiple directory servers where possible
- prefer direct maker/taker channels when available
- enforce per-message signatures and a strict session state machine during the CoinJoin flow (takers may switch transport mid-session)
Neutrino Notes
- neutrino is convenient, but full-node backends remain the strongest default for verification and compatibility
- run neutrino infrastructure you trust and route traffic with Tor where possible
- neutrino-api supports TLS with certificate pinning and bearer-token authentication, enabled by default; see Neutrino TLS for setup details
- the TLS certificate is self-signed and pinned on first use (TOFU model), so only the specific neutrino-api instance that generated it is trusted
Operational Advice
- treat mnemonics and wallet files as high-value secrets
- keep software updated
- test operational setup on testnet/signet/regtest before production use
Process Memory Hardening
Each long-running daemon (jmwalletd, maker, taker, directory server,
orderbook watcher) calls jmcore.process_hardening.harden_current_process
at startup. This applies two cheap, OS-level mitigations on Linux to keep
secrets (mnemonic, BIP32 extended keys, derived private keys, NaCl session
keys, signed PSBTs) from leaking on crash or live introspection:
RLIMIT_CORE = 0disables core dumps for the process, preventing tools likesystemd-coredump(8)from writing the address space to diskprctl(PR_SET_DUMPABLE, 0)blocks non-privilegedptraceand/proc/$pid/memreads from peer processes in the same user namespace
Set JOINMARKET_DISABLE_PROCESS_HARDENING=1 to opt out (only useful when
debugging with gdb or rr).
These mitigations do not protect anonymous pages that get paged out to swap or written to a hibernation image. Operators who hold non-trivial funds should also:
- enable encrypted swap (for example LUKS-backed swap with a random key on each boot, or zram-swap, so paged-out pages never persist plaintext)
- disable hibernation, or back the hibernation partition with the same
encrypted volume as
/ - avoid running daemons on systems with
kernel.yama.ptrace_scope = 0(Ubuntu's default is1, which is fine; RHEL-style systems should set this in/etc/sysctl.d/) - prefer running daemons under a dedicated unprivileged user account
and, where possible, a
systemdunit withProtectKernelTunables=,ProtectControlGroups=,PrivateTmp=, andNoNewPrivileges=
For protocol-level details, see Protocol and Privacy. For the maker-side pre-sign checklist, see Maker Verification Checklist.