Skip to content

Running a node

Running a Quidnug node is a single Go binary with a persistent data directory. This page covers the minimum path to a healthy node, plus the extras you need if you intend to join the public network.

Terminal window
git clone https://github.com/bhmortim/quidnug.git
cd quidnug/deploy/public-network
NODE_NAME=your-org-node-1 NODE_REGION=iad \
NODE_KEY_FILE=./secrets/node.key.json \
NODE_AUTH_SECRET=$(openssl rand -hex 32) \
./deploy-node.sh

That script provisions the app, creates a 10 GB volume, sets secrets, and deploys the image from GHCR. Smoke test:

Terminal window
curl https://your-org-node-1.fly.dev/api/health
Terminal window
docker run -d --name quidnug \
-p 8080:8080 \
-v quidnug-data:/data \
-e DATA_DIR=/data \
-e REQUIRE_NODE_AUTH=true \
-e NODE_AUTH_SECRET=$(openssl rand -hex 32) \
ghcr.io/bhmortim/quidnug:latest

Terminate TLS at your ingress (Caddy, nginx, Cloudflare Tunnel, all fine). See the deployment patterns page.

Every node has its own quid (the node’s operator identity). Generate offline and store the private key in a password manager + paper backup:

Terminal window
./bin/quidnug-cli keygen \
--out node.key.json \
--name "your-org-node-1"

The quid ID (first 16 hex chars of sha256(publicKey)) becomes how peers and the public seeds address your node.

Install a 3-of-5 guardian quorum before the node starts accepting any external peering traffic. Guardians should be distinct humans or organizations you trust specifically for this role, not other nodes you operate.

Terminal window
./bin/quidnug-cli guardians:set \
--subject <your-quid-id> \
--key node.key.json \
--m 3 \
--n 5 \
--members <guardian-1-quid>,<guardian-2-quid>,<guardian-3-quid>,<guardian-4-quid>,<guardian-5-quid> \
--time-lock 24h

Each guardian must separately sign a consent transaction, get them to run guardians:consent before the quorum is effective. See QDP-0002: Guardian-Based Recovery for the full lifecycle.

Each node ships a Prometheus scrape endpoint at /metrics. Either:

  • Remote-write to Grafana Cloud free tier, set GRAFANA_REMOTE_WRITE_URL and GRAFANA_REMOTE_WRITE_TOKEN in the environment, and the node streams metrics up. This is what quidnug.com uses.
  • Scrape locally, point your own Prometheus at /metrics every 30 seconds.

See the observability reference for the metric names that matter.

Only do this after steps 1–4 are complete.

The public network is an open peering layer over the network.quidnug.com reserved domain tree. You peer with one or more existing seeds; in exchange for tiering your blocks as Trusted, they expect the same from you.

  1. Read the peering protocol.
  2. Write a signed peering request (the shape is standardized).
  3. Open an issue on the repo using the peering request template.
  4. Wait for review (target: under 72 hours). Decision comments on the issue.
  5. On approval, reciprocate within 72 hours by publishing your own TRUST edges back at the seed.

The /network/join/ page on the marketing site walks through this flow with a checklist.

Peers of the public network are expected to:

  • Respond to security advisories in #network within one business day.
  • Keep uptime ≥95% over a rolling 30-day window.
  • Rotate node keys at least annually (or on any suspected compromise).
  • Give notice before decommissioning a peer relationship.
  • Operate only in the trust domains you requested, don’t start issuing attestations in credentials.* if you only asked for oracles.*.

The seeds commit the same back: public review within 72 hours, standardized rejection reasons, protocol upgrade notices via fork-block, no silent mass revocation.

When you’re ready to retire a peering relationship:

  1. Publish a TRUST transaction with trustLevel: 0.0 in each peering domain. This is prospective only, blocks already accepted remain tier-Trusted.
  2. Optional: publish GuardianResign from your node’s quid if you were acting as a guardian for any other subjects (QDP-0006).
  3. Optional: publish AnchorInvalidation against your current epoch if you’re also rotating the key out.
  4. Update operatorUrl to point at your decommission notice.

Perfectly valid. A node that isn’t peered with the public network still:

  • Validates transactions signed with published public keys.
  • Gossips with peers that trust it enough (or that it trusts).
  • Serves as a local read-only mirror of whatever chain you care about.

This is the right shape for developer nodes, CI nodes, and organization-internal nodes that don’t need the public “validators” attestation.