How to Deploy Mpcium in Production: A Security-Hardened Systemd Setup Guide
Deploy Mpcium in production by running a non-privileged systemd service with encrypted SystemD credentials, TLS-only communication, and automated BadgerDB backups using the hardened unit templates and validation scripts provided in deployments/systemd/.
Production deployment of fystack/mpcium requires a hardened, repeatable configuration that protects cryptographic material, ensures reliable inter-node communication, and provides observability. The repository ships a complete systemd-based workflow that implements defense-in-depth safeguards through strict file permissions, encrypted credential injection, and resource isolation. This guide walks through the essential architecture, configuration requirements, and step-by-step deployment process based on the official source code.
Hardened Systemd Service Architecture
The production deployment centers on a locked-down systemd unit defined in deployments/systemd/mpcium.service. This template enforces the principle of least privilege while securely injecting secrets via systemd's native credential mechanism.
Non-Privileged Execution and File Permissions
Run the node as a dedicated non-privileged system user mpcium to limit the impact of a compromised process. The setup-config.sh script automates this via the create_user function, creating the user and group before installation.
Configuration files require strict ownership:
/etc/mpcium/config.yamlmust be owned byroot:mpciumwith permissions640(lines 94-104 ofsetup-config.sh)- The service definition sets
ReadOnlyPaths=/etc/mpciumto prevent runtime modification - Data directories under
/opt/mpciumuseReadWritePathsrestrictions
Encrypted Credential Injection
Never store plaintext passwords in the YAML configuration or environment variables. Instead, use SystemD Credential files (*.cred) injected via SetCredentialEncrypted=:
- The BadgerDB password is supplied through a credential file referenced by
loadPasswordFromFileat startup - Identity encryption passphrases are stored as
mpcium-identity-password.cred - The
update_service_credentialsfunction insetup-config.shmanages these files
This approach ensures secrets never appear in /proc/<pid>/environ or process listings.
System Call Filtering and Capability Bounding
The mpcium.service template (lines 26-35) implements aggressive sandboxing:
[Service]
User=mpcium
Group=mpcium
NoNewPrivileges=yes
ProtectSystem=full
CapabilityBoundingSet=CAP_DAC_READ_SEARCH
LimitNOFILE=65535
LimitNPROC=4096
These directives prevent privilege escalation, restrict filesystem access to read-only for system paths, and bound capabilities to the minimum required for database operations.
Secure Configuration Management
Production settings are validated against config.prod.yaml.template using logic in setup-config.sh.
Production Environment Enforcement
Set environment: production in config.yaml to guarantee TLS-only defaults enforced in pkg/constant/env.go. The check_environment function in the setup script validates this setting and warns if NATS URLs do not use tls:// or if Consul addresses lack HTTPS.
Storage and Backup Configuration
Enable AES-256 encrypted BadgerDB storage by supplying the password via systemd credentials rather than the config file. The database initialization in pkg/kvstore/badger.go derives the encryption key from this credential.
For disaster recovery, configure:
backup_enabled: truebackup_dir: /opt/mpcium/backupsbackup_period_seconds: 300
The StartPeriodicBackup function in cmd/mpcium/main.go (lines 54-62) invokes the logic in pkg/kvstore/badger_backup.go, creating encrypted snapshots using the same password as the live database.
Cryptographic Material Management
Mpcium relies on several key types that must be generated and distributed according to strict protocols.
Peer Registry Generation
Generate the shared peer registry on a single designated node using:
mpcium-cli generate-peers -n 3
This command (implemented in the CLI source) creates peers.json under /opt/mpcium. Distribute this file to all nodes with permissions 640 and ownership root:mpcium. All nodes must share an identical chain_code (64-hex-character string) validated by validate_config_credentials.
Identity Key Lifecycle
Initiator Identity: Create the event initiator using mpcium-cli generate-initiator --encrypt (source: cmd/mpcium-cli/generate-initiator.go). This produces an Age-encrypted private key (initiator.key.age) and a public key. Copy the public key to the event_initiator_pubkey field in /etc/mpcium/config.yaml.
Node Identity: Each node generates its own unique identity using:
mpcium-cli generate-identity --node $(hostname) --encrypt
The resulting private key never leaves the host. After loading keys, the node invokes pkg/security/zeroize.go to wipe sensitive buffers from memory.
Observability and Health Monitoring
The deployment provides multiple observability vectors:
- Journal Integration: All logs route to systemd journal via
StandardOutput=journal. Monitor withjournalctl -u mpcium -f - Health Endpoints: Enable
healthcheck.enabled: trueto activate the HTTP server defined inpkg/healthcheck/server.go - Consul Integration: The node automatically registers health checks via
infra.GetConsulClientwhen Consul is configured
Step-by-Step Production Deployment Workflow
Execute the following sequence on each node:
-
Install Binaries
sudo make install -
Initialize System Configuration
sudo /opt/mpcium/deployments/systemd/setup-config.shThis interactive wizard creates the
mpciumuser, validates TLS settings viacheck_environment, and installs the systemd unit. -
Generate Peer Registry (on one node only)
mpcium-cli generate-peers -n 3 # Distribute peers.json to all nodes at /opt/mpcium/peers.json -
Create Initiator Identity (on one node)
mpcium-cli generate-initiator --encrypt # Copy the public key to event_initiator_pubkey in config.yaml -
Create Node Identity
mpcium-cli generate-identity --node $(hostname) --encrypt -
Validate Deployment
sudo /opt/mpcium/deployments/systemd/setup-config.sh verifyThe
verify_deploymentfunction confirms directory permissions, key presence, and credential files. -
Start Service
sudo systemctl start mpcium sudo systemctl status mpcium
Summary
- Use the hardened systemd template from
deployments/systemd/mpcium.servicewithNoNewPrivilegesandProtectSystemto isolate the process - Inject secrets via systemd credentials managed by
setup-mpcium-cred.shand consumed byloadPasswordFromFile, never via environment variables - Enforce TLS for all external communication (NATS, Consul) by setting
environment: productionand validating withsetup-config.sh - Automate encrypted backups using
pkg/kvstore/badger_backup.gowith the same credential protecting the live BadgerDB - Verify before starting using
setup-config.sh verifyto ensure cryptographic material and permissions are correctly configured
Frequently Asked Questions
How should I store the BadgerDB password in production?
Store the password as a systemd credential file using setup-mpcium-cred.sh, which creates an encrypted blob loaded via SetCredentialEncrypted= in the service unit. The application reads this via loadPasswordFromFile at startup, ensuring the secret never appears in environment variables or command-line arguments accessible via ps or /proc.
What systemd security features protect the Mpcium process?
The mpcium.service unit implements NoNewPrivileges=yes to prevent privilege escalation, ProtectSystem=full to make most of the filesystem read-only, and CapabilityBoundingSet=CAP_DAC_READ_SEARCH to restrict available kernel capabilities. These settings, combined with the dedicated mpcium user, create a minimal attack surface as defined in the template (lines 26-35).
How are database backups encrypted and managed?
Automated backups are handled by StartPeriodicBackup in cmd/mpcium/main.go, which uses the same AES-256 encryption key as the live BadgerDB instance (defined in pkg/kvstore/badger_backup.go). Backups are written to backup_dir with the .enc extension. You should periodically copy these files to an off-site immutable store such as S3 with bucket-level encryption.
Can I rotate node identity keys without cluster downtime?
Yes. Generate a new identity using mpcium-cli generate-identity --node <name> --encrypt, update the corresponding systemd credential using setup-mpcium-cred.sh, and execute systemctl restart mpcium. The node rejoins the cluster using the existing peers.json and chain_code, provided the network addresses remain consistent.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →