This directory contains deployment scripts and configurations for production deployment of Mpcium MPC (Multi-Party Computation) nodes using systemd.
For local development and testing, please refer to INSTALLATION.md instead.
Mpcium is a distributed threshold cryptographic system that requires multiple nodes to collaborate for secure operations. This deployment guide covers setting up a secure, production-ready MPC cluster with proper security hardening, systemd integration, and operational best practices.
- Minimum 3 nodes (cloud-based, ARM architecture preferred)
- Linux distribution
- Network connectivity between all nodes
- External services: NATS message broker, Consul service discovery
- Go 1.25+ on all nodes
- Git for source code management
- NATS server with credentials
- Consul for service discovery
- mkcert for TLS certificate generation
Follow these steps for manual deployment across your cluster:
Before installing Mpcium, you need Go 1.25+ installed on all nodes.
Download Go Binaries with wget:
For amd64 (x86_64):
wget https://go.dev/dl/go1.25.0.linux-amd64.tar.gzFor arm64 (AArch64, e.g. Graviton or Apple M1/M2 Linux VMs):
wget https://go.dev/dl/go1.25.0.linux-arm64.tar.gzExtract to /usr/local:
Remove any old Go installation first:
sudo rm -rf /usr/local/goExtract the archive:
# For amd64
sudo tar -C /usr/local -xzf go1.25.0.linux-amd64.tar.gz
# For arm64
sudo tar -C /usr/local -xzf go1.25.0.linux-arm64.tar.gzUpdate PATH:
Add Go binary to your environment. Edit ~/.bashrc or ~/.zshrc:
export PATH=$PATH:/usr/local/go/binReload shell:
source ~/.bashrcVerify Installation:
go versionYou should see:
go version go1.25.0 linux/amd64
or
go version go1.25.0 linux/arm64
# Install Mpcium binaries (preserve environment to access Go)
sudo -E make install
# Create system user and directories
sudo useradd -r -s /bin/false -d /opt/mpcium -c "Mpcium MPC Node" mpcium
sudo mkdir -p /opt/mpcium /etc/mpcium# Application data directories (service-owned)
sudo chown -R mpcium:mpcium /opt/mpcium
sudo chmod g+s /opt/mpcium
sudo chmod 750 /opt/mpcium
# Configuration directory (root-controlled, service-readable)
sudo chown root:mpcium /etc/mpcium
sudo chmod 750 /etc/mpciumOn one designated node only:
cd /opt/mpcium
mpcium-cli generate-peers -n 3# Copy configuration template
cp ~/mpcium/config.prod.yaml.template /etc/mpcium/config.yaml
# Set proper configuration permissions
sudo chown root:mpcium /etc/mpcium/config.yaml
sudo chmod 640 /etc/mpcium/config.yamlEdit /etc/mpcium/config.yaml to include:
- NATS server connection details and credentials
- Consul service discovery configuration
- MPC threshold settings (
mpc_threshold) - Event initiator public key (will be updated in Step 5)
On one designated node only:
mpcium-cli generate-initiator --encrypt- This creates an encrypted private key file with
.key.ageextension that you'll need to securely distribute to application nodes that initiate MPC operations - Copy the public key from
initiator_identity.jsonand update theevent_initiator_pubkeyfield in/etc/mpcium/config.yamlon all nodes
# Register peers
mpcium-cli register-peers --config /etc/mpcium/config.yaml --environment production
# Generate node identity (with encryption) - replace node0 with actual node name
mpcium-cli generate-identity --node node0 --encryptcd ~/mpcium/deployments
./setup-mpcium-cred.sh
# Enter BadgerDB password when prompted
# ⚠️ IMPORTANT: Backup password to secure storage (e.g., Bitwarden)sudo ./setup-config.sh# Check service status
sudo systemctl status mpcium
# Monitor logs
journalctl -f -u mpciumAfter deployment, the following directory structure is created:
/opt/mpcium/ # Application home (mpcium:mpcium, 750)
├── certs/ # TLS certificates
│ ├── client-cert.pem
│ ├── client-key.pem
│ └── rootCA.pem
├── db/ # BadgerDB storage (auto-created)
├── backups/ # Encrypted backups (auto-created)
├── identity/ # Node identity files (auto-created)
│ ├── node0_identity.json
│ ├── node1_identity.json
│ ├── node2_identity.json
│ └── node{X}_private.key # Current node's private key
├── peers.json # Peer registry
└── .env # Environment variables
/etc/mpcium/ # Configuration (root:mpcium, 750)
└── config.yaml # Main configuration (root:mpcium, 640)
Node 0 (unencrypted private key):
/opt/mpcium/identity/
├── node0_identity.json
├── node0_private.key # This node's private key
├── node1_identity.json
└── node2_identity.json
Generated with: mpcium-cli generate-identity --node node0 --config /etc/mpcium/config.yaml
Node 1 (encrypted private key):
/opt/mpcium/identity/
├── node0_identity.json
├── node1_identity.json
├── node1_private.key.age # This node's encrypted private key
└── node2_identity.json
Generated with: mpcium-cli generate-identity --node node1 --config /etc/mpcium/config.yaml --encrypt
- Configuration files are root-controlled to prevent tampering
- Application data is service-owned for runtime access
- Database encryption is mandatory in production
- All inter-node communication uses Ed25519 signatures
- Message payloads encrypted with ECDH key exchange
- TLS required for NATS connections
The service runs with enhanced security:
- Non-privileged user (
mpcium) - Read-only configuration directory
- Private temp directory
- System call filtering
- Capability restrictions
# Service status
sudo systemctl status mpcium
# Start/stop/restart
sudo systemctl start mpcium
sudo systemctl stop mpcium
sudo systemctl restart mpcium
# View logs
journalctl -u mpcium
journalctl -f -u mpcium # Follow logsThe deployment includes Consul-based health monitoring. Check cluster health via your Consul UI.
BadgerDB automatically creates encrypted backups in /opt/mpcium/backups/. Ensure regular backup of:
- Database encryption password
- Node identity files
- Configuration files
Service won't start:
# Check service logs
journalctl -u mpcium --no-pager
# Verify configuration
sudo ./setup-config.sh verifyNetwork connectivity:
- Verify NATS and Consul connectivity
- Check firewall rules between nodes
- Validate TLS certificates
Service logs are available via systemd journal:
# Recent logs
journalctl -u mpcium -n 100
# Logs since specific time
journalctl -u mpcium --since "1 hour ago"
# Filter by log level
journalctl -u mpcium -p err