SPEARMINT SPMTC

Spearmint/Developer docs/Security

Developer documentation · Spearmint Mining

Operational security

The pool will be probed by automated agents from the first minute its endpoints are public. These are the controls it is built to have before that minute, grouped by the surface they protect.

Pre-launch · design document
Non-negotiable The Spearmint Core RPC interface is never exposed to the public Internet. It binds to 127.0.0.1, uses cookie authentication, and is reachable only by the Stratum server and the stats exporter on the same host or over a private network. Every other control on this page is secondary to that one.

01 Web

  • HTTPS only, HSTS with a long max-age and preload, TLS 1.2+ with modern ciphers. Plain HTTP redirects and nothing else.
  • Security headers on every response: Content-Security-Policy (no inline script beyond the site's own, no third-party origins except the font host), X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, X-Frame-Options: SAMEORIGIN, Permissions-Policy denying everything.
  • The public site and stats API are static or read-only. No administrative interface exists on the public host at all; operator tooling runs on the private network over SSH.
  • The stats API validates the payout address (bech32 checksum, spmtc HRP) before any lookup, rate-limits per IP, and caches responses so a lookup storm cannot reach the database.
  • No third-party analytics, no session cookies, no login. There is nothing to steal from the browser.

02 Stratum

  • Two listeners: 3333 plain TCP for hardware that cannot do TLS, 3334 TLS. The TLS port is the recommended one and the documentation says so.
  • Login validation: the username's address part must be a valid spmtc bech32 address; the worker part is limited to [A-Za-z0-9_-]{1,32}. Invalid logins are rejected before a job is sent.
  • Per-IP connection and message-rate limits; temporary bans for floods of invalid, duplicate, or malformed shares; escalating ban durations for repeat sources.
  • Variable-difficulty sanity: minimum and maximum share difficulty bounded; a worker cannot request a difficulty that would let it submit thousands of trivial shares per second.
  • Stratum hosts run nothing else. They reach the node over the private network only.

03 Node

  • rpcbind=127.0.0.1, rpcallowip=127.0.0.1, cookie auth. No rpcuser/rpcpassword in config files.
  • Host firewall: inbound allows 9333 (P2P) and SSH from the admin network. Everything else dropped. Outbound restricted to P2P, package updates, and time sync.
  • Separate nodes for template building, for the stats/explorer exporter, and for cold verification of payout runs. A compromise of the public-facing exporter's node does not touch templates.
  • Wallet disabled on the template nodes (disablewallet=1). The only wallet in the system is on the signing host.
  • Peers pinned with addnode to the operator's own nodes plus a rotating set; nMinimumChainWork and checkpoints from the release protect against a private chain presented at first connection.
Repeated on purpose No RPC on the Internet. Not behind a reverse proxy, not with a strong password, not "just for the explorer". The explorer reads from its own node over localhost.

04 Administration

  • SSH keys only; password authentication disabled; keys hardware-backed where possible; one key per person, revocable individually.
  • Two-factor authentication enforced on the hosting provider, DNS, domain registrar, code hosting, and email. Registrar lock and DNSSEC on.
  • Least privilege: separate system users for stratum, node, exporter, and payout daemon; no shared root; sudo limited and logged.
  • An admin network (VPN or bastion) is the only route to management ports. Public hosts have no management ports exposed.
  • Configuration is in version control with signed commits; production changes go through review and are recorded in the configuration-change log.

05 Keys

  • The coinbase address key lives on an isolated signing host that accepts unsigned batch transactions and returns signatures. It has no inbound access from public hosts.
  • Hot amount is kept to what the next payout run needs, by design of the daily run. Fee income and anything above operational need moves to a cold key held offline.
  • Key generation follows a written ceremony: two people, offline machine, verified entropy, encrypted backups to two separate physical locations, passphrases held separately.
  • Backups of the share database are encrypted at rest and in transit, tested by restore quarterly.
  • Miners' keys are never present anywhere in the system. The service has no field for them and no form that asks.

06 Monitoring

  • Share-rate anomalies per worker and per IP: sudden jumps, difficulty gaming, share timing that does not match claimed hashrate.
  • Orphan and stale rates versus network baseline; a rising orphan rate is the first sign of a chain-level problem.
  • Payout-run assertions, evaluated before signing: sum(payouts) == sum(mature allocations paid) − network_fee; every output address exists in workers; no output to an address with an open compliance hold; batch size within bounds. Any assertion failure aborts the run and pages.
  • Chain monitoring: tip height against public nodes, reorg depth, difficulty step-changes, peer count.
  • Host monitoring: disk, memory, certificate expiry, failed logins, firewall drops.
  • Alerting to an on-call rotation with defined response times per severity.

07 Audit logs

Append-only, shipped off-host, retained per the recordkeeping schedule:

  • Every payout run: inputs, assertions, signed txid, who or what triggered it.
  • Every configuration change: diff, author, time, approval.
  • Every compliance event: gate decisions, holds, releases, reason, actor.
  • Every notification-registration change with the signed message that authorised it.
  • Administrative sessions: SSH logins, sudo use, signing-host access.
  • Security events: bans, floods, failed logins, certificate changes.

08 Incident response

Severity tiers
TierExamplesResponse
S1Key compromise suspected; payout assertion failure; chain reorg deeper than maturityPage immediately; pause payouts; two people on the call; public notice within 24 hours
S2Stratum outage; exporter breach; node desyncPage on-call; fix; notice on /network/ if user-visible
S3Single-host hardware fault; certificate near expiry; flood absorbedTicket; next business day

Every S1 and S2 gets a written post-mortem published on the build log, including what failed and what changed, in keeping with how the log has been kept from the start.

09 DDoS

  • Upstream filtering from the hosting provider for volumetric attacks on all public ports.
  • Anycast/CDN in front of the website and read-only API. The site is static, so it can be served from cache indefinitely under attack.
  • Stratum is not put behind a CDN or generic TCP proxy without load-testing first: proxies that buffer or coalesce can raise stale-share rates and break the difficulty feedback loop. Capacity headroom and per-IP limits are the first line for Stratum.
  • Multiple Stratum hosts in different networks, published under one DNS name with health-checked failover.

10 Release integrity

  • Spearmint Core and the pool software ship as signed tags with reproducible build instructions; SHA-256 hashes of binaries published on the updates page and in the repository.
  • Release signing keys are held by named maintainers, offline, with a published fingerprint. Contributions are reviewed by a second maintainer before merge; AI-generated contributions are reviewed as unfamiliar code regardless of source.
  • Production hosts deploy only from tagged, hash-verified artefacts.

11 Miner-side

Keys

Never share them

Your payout address is all the pool needs. Spearmint Mining will never ask for your private key or recovery phrase, on any page, in any email, for any reason.

Connection

Use the TLS port

Connect to stratum+ssl://pool.spearmintcoin.com:3334 where your hardware supports it, and check the certificate fingerprint published on the mining page.

Verification

Check payouts on your own node

Every payout has a transaction id. Look it up on a node you run, not only on this site, and compare the amount to your exported share log.