The script requires the gcloud command-line tool to interact with Google Cloud Platform.
Installation:
Linux/macOS:
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
Windows: Download from https://cloud.google.com/sdk/docs/install
Verify installation:
gcloud --version
Required for generating cryptographic keys for your MPC node. Usually pre-installed on Linux/macOS.
Verify installation:
openssl version
Authenticate with Google Cloud before running the script:
gcloud auth login
Your Google account needs these IAM roles on the project:
roles/owner OR the following combination:roles/compute.admin - Create compute resourcesroles/iam.serviceAccountAdmin - Create service accountsroles/resourcemanager.projectIamAdmin - Grant IAM rolesroles/secretmanager.admin - Manage secretsroles/storage.admin - Manage GCS bucketsroles/dns.admin - Manage DNS (if applicable)roles/serviceusage.serviceUsageAdmin - Enable APIsFormat: region-zone-letter (e.g., europe-west1-c)
Recommendation: Choose a zone in the europe-west region for optimal performance.
Since Vaultody's central services are hosted in Europe (europe-west), selecting zones in this region minimizes latency and ensures better communication performance between your MPC co-signer node and the main infrastructure. While technically you can deploy in other regions, this is not recommended as it may impact the MPC protocol's performance and timeout behavior.
Example zones: - europe-west1-b (Belgium) - europe-west1-c (Belgium) - europe-west1-d (Belgium) - europe-west3-a (Frankfurt) - europe-west3-b (Frankfurt)
Check zone availability:
gcloud compute zones list --filter="region:europe-west*"
Important: Confidential VMs provide hardware-based memory encryption using AMD SEV-SNP technology, offering enhanced security for sensitive workloads. However, these instances have limited availability and may not be immediately accessible in all zones.
Pricing: Confidential VMs typically cost 10-15% more than standard instances.
Compatible machine types: n2d-standard-*, c2d-standard-*
Availability challenge: GCP doesn't show capacity until you actually request an instance. If the script fails with ZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILS, try: - Different zone in the same region - Different machine type - Standard (non-confidential) VM - Wait and retry later
After deployment, check instance status:
# Check if instance is running
gcloud compute instances list --project=YOUR_PROJECT_ID --filter="name~'mpc-co-signer-.*'"
# Check instance group status
gcloud compute instance-groups managed describe mpc-co-signer-group \
--zone=YOUR_ZONE \
--project=YOUR_PROJECT_ID
# Check for errors in instance group
gcloud compute instance-groups managed list-errors mpc-co-signer-group \
--zone=YOUR_ZONE \
--project=YOUR_PROJECT_ID
Default recommendations: - Without Confidential VM: n2-standard-2 (2 vCPUs, 8GB RAM) - With Confidential VM: n2d-standard-2 (2 vCPUs, 8GB RAM)
Confidential-compatible types: n2d-standard-2, n2d-standard-4, n2d-standard-8, c2d-standard-4, c2d-standard-8
For most deployments, n2-standard-2 or n2d-standard-2 provides adequate performance for MPC operations.
Format: 6-30 characters, lowercase letters, digits, and hyphens - Must start with a lowercase letter - Cannot end with a hyphen
Example: mpc-co-signer-prod, vaultody-mpc-node-01
If the project doesn't exist, the script will create it. If it exists, the script will use it.
Format: Fully qualified domain name (FQDN) that you own
Example: mpc-node.yourdomain.com, cosigner.example.com
Requirements: - You must have access to configure DNS records for this domain - The domain will be used for SSL certificate generation - The domain must be accessible from the internet
After deployment, the script will provide an IP address. You need to create an A record pointing your domain to this IP:
Example DNS Configuration:
| Type | Name | Value | TTL |
|---|---|---|---|
| A | mpc-node.yourdomain.com | 34.49.196.217 | 300 |
Steps: 1. Log in to your domain registrar or DNS provider (e.g., Cloudflare, Google Domains, Route53) 2. Navigate to DNS management 3. Add a new A record: - Name/Host: Your subdomain (e.g., mpc-node or full domain mpc-node.yourdomain.com) - Type: A - Value/Points to: The IP address provided by the script (e.g., 34.49.196.217) - TTL: 300 seconds (5 minutes) or use default 4. Save the record
DNS propagation: Changes typically take 5-30 minutes, but can take up to 48 hours in rare cases.
Verify DNS:
# Check if DNS is resolving
nslookup mpc-node.yourdomain.com
# Or using dig
dig mpc-node.yourdomain.com +short
Purpose: This password is used to encrypt and secure the local database on your MPC co-signer node. The database contains critical MPC key material and state information.
Requirements: - Minimum 12 characters - Must contain uppercase letters - Must contain lowercase letters - Must contain numbers - Special characters are recommended but not required
Example: MySecurePass123!
Important: - Store this password securely (password manager, vault) - Do not share this password - You'll need it if you ever need to manually access or recover the database
Generate a strong password:
# Generate a 20-character random password
openssl rand -base64 20
Purpose: This is your node's private cryptographic key used for secure communication in the MPC protocol. Each co-signer node must have a unique key pair.
Use the following OpenSSL commands to generate your keys:
# Generate private key in DER format (binary)
openssl ecparam -name prime256v1 -genkey -noout -out private_key.der -outform DER
# Extract public key from private key
openssl ec -in private_key.der -inform DER -pubout -out public_key.der -outform DER
# Convert private key to Base64 for script input
openssl base64 -A -in private_key.der
# Convert public key to Base64 for web portal
openssl base64 -A -in public_key.der
What these commands do: 1. Private key generation: Creates an ECDSA private key using the prime256v1 curve (also known as secp256r1 or P-256) 2. Public key extraction: Derives the corresponding public key from the private key 3. Base64 encoding: Converts binary DER format to Base64 text for easy copying
Usage: - Private key (Base64): Copy and paste into the deployment script when prompted - Public key (Base64): Upload to the Vaultody web portal dashboard when configuring your MPC node
Key management: - The private key is stored securely in GCP Secret Manager - The public key is used to establish encrypted communication channels between MPC nodes - Never share your private key or commit it to version control - Keep a secure backup of both keys
File cleanup:
# After copying the keys, securely delete the files
shred -vfz -n 10 private_key.der public_key.der
# Or on macOS:
rm -P private_key.der public_key.der
Purpose: These credentials authenticate your co-signer node with Vaultody's MPC infrastructure and secure all API communications.
How to obtain: 1. Log in to the Vaultody web portal 2. Navigate to MPC Node Configuration 3. Create a new co-signer node configuration 4. The portal will generate and display your API Key and API Secret 5. Copy these values securely
Important: - These are provided by Vaultody, not generated by you - Store them securely alongside your private key and password - Do not share these credentials - Each co-signer node should have unique API credentials
The script uses Google Cloud Storage (GCS) buckets as the persistent storage backend for your MPC co-signer database. This is critical for the following reasons:
The deployment script: 1. Creates a GCS bucket named vaultody-co-signer-artifacts-TIMESTAMP 2. Configures the MPC co-signer container to use this bucket as its database backend 3. The container uses gs://bucket-name as the database source
Important: The bucket persists even after running the cleanup script. This is intentional to prevent accidental loss of MPC key material.
# List all buckets in your project
gsutil ls -p YOUR_PROJECT_ID
# List contents of your MPC bucket
gsutil ls -r gs://vaultody-co-signer-artifacts-*
# Get bucket details
gsutil ls -L -b gs://vaultody-co-signer-artifacts-TIMESTAMP
# Check storage usage
gsutil du -sh gs://vaultody-co-signer-artifacts-*
⚠️ WARNING: Only delete the bucket if you are completely certain you want to permanently destroy your MPC key material. This action is irreversible and will make your co-signer node unable to participate in MPC operations.
# List bucket to verify it's the correct one
gsutil ls gs://vaultody-co-signer-artifacts-TIMESTAMP
# Delete the bucket and all its contents
gsutil -m rm -r gs://vaultody-co-signer-artifacts-TIMESTAMP
When to delete: - You're permanently decommissioning the co-signer node - You're performing a complete teardown for testing purposes - You've confirmed you have proper backups if needed
When NOT to delete: - You're just cleaning up compute resources - You're planning to redeploy with the same configuration - You want to preserve the MPC state for any reason
After the script completes successfully, you'll see output similar to:
✅ Infrastructure created successfully!
ALB IP Address: 34.49.196.217
Endpoint URL: https://mpc-co-signer.vaultody.com
📋 NEXT STEPS:
1. Create DNS A record: mpc-co-signer.vaultody.com → 34.49.196.217
2. Wait 10-15 minutes for SSL certificate validation
3. Test endpoint: https://mpc-co-signer.vaultody.com/health/readiness
As explained in the "Domain Name" section above, create an A record pointing your domain to the provided IP address.
Quick reference:
# Your DNS provider interface:
Type: A
Name: mpc-co-signer (or full domain)
Value: 34.49.196.217 (your IP from script output)
TTL: 300
Google Cloud automatically provisions a managed SSL certificate for your domain. This process requires: 1. DNS record to be in place 2. Google's certificate authority to verify domain ownership 3. Certificate to be issued and activated
Typical timeline: 10-15 minutes, but can take up to 30 minutes
Check certificate status:
gcloud compute ssl-certificates describe mpc-co-signer-cert \
--global \
--project=YOUR_PROJECT_ID \
--format='table(name, type, managed.status, managed.domains, creationTimestamp, expireTime)'
Certificate status meanings: - PROVISIONING - Certificate is being created, DNS verification in progress - FAILED_NOT_VISIBLE - DNS record not found or not propagated yet - ACTIVE - Certificate is valid and ready to use ✅ - RENEWAL_FAILED - Domain ownership verification failed
If stuck in PROVISIONING:
# Verify DNS is correct
dig +short mpc-co-signer.vaultody.com
# Check if it matches the load balancer IP
gcloud compute forwarding-rules describe mpc-co-signer-forwarding-rule \
--global \
--project=YOUR_PROJECT_ID \
--format="value(IPAddress)"
Once the certificate status shows ACTIVE, test your MPC co-signer node:
# Test liveness endpoint (always returns success if container is running)
curl https://mpc-co-signer.vaultody.com/health/liveness
# Test readiness endpoint (returns success if node is fully operational)
curl https://mpc-co-signer.vaultody.com/health/readiness
# Expected response:
{"status":"ok"}
Troubleshooting endpoint issues:
# Check if backend is healthy
gcloud compute backend-services get-health mpc-co-signer-backend \
--global \
--project=YOUR_PROJECT_ID
# Check instance logs
gcloud compute instances get-serial-port-output mpc-co-signer-XXXX \
--zone=YOUR_ZONE \
--project=YOUR_PROJECT_ID
# SSH into instance to check container
gcloud compute ssh mpc-co-signer-XXXX \
--zone=YOUR_ZONE \
--project=YOUR_PROJECT_ID
Once inside the instance:
# Check container status
docker ps -a
# View container logs
docker logs mpc-co-signer
# Check if service is responding locally
curl http://localhost:8000/health/readiness
Both deployment and cleanup scripts are designed to be idempotent, meaning they can be safely run multiple times without causing issues:
Deployment script behavior: - Checks if each resource exists before creating it - Reuses existing resources (project, service account, buckets, SSL certificates) - Updates secrets with new values if they exist - Only creates missing components
Benefits: - Resume after failure: If the script fails partway through (network issue, quota limit, zone capacity), simply run it again - Update configuration: Change secrets or configuration by re-running with new values - No duplicate resources: Won't create duplicate firewalls, load balancers, etc.
Example scenarios:
# Script failed due to zone capacity for confidential VMs
# Solution: Run again with different zone or without confidential VM
# You need to update the database password
# Solution: Run script again with new password - it will update the secret
# You want to change machine type
# Solution: Clean up compute resources, then redeploy with new machine type
When re-running the deployment script:
| Resource | Behavior |
|---|---|
| Project | Reused if exists |
| APIs | Enabled if not already |
| Service Account | Reused if exists |
| IAM Roles | Re-granted (idempotent) |
| GCS Bucket | Reused if exists with same prefix |
| Secrets | Updated with new values |
| Firewall Rules | Reused if exists |
| Instance Template | Recreated with new settings |
| Instance Group | Reused, will use new template on next instance creation |
| Health Checks | Reused if exists |
| Backend Service | Reused if exists |
| SSL Certificate | Reused if exists |
| Load Balancer | Reused if exists |
The cleanup_mpc_resources.sh script provides a safe way to remove deployed infrastructure while preserving critical data.
./cleanup_mpc_resources.sh
The script will interactively ask about:
Prompted question:
Secrets:
- Contains your database password and private key
- Safe to keep if you want to reuse the same credentials
Delete secrets? [y/N]:
Recommendation: Press N (or just Enter)
Why keep: - You'll need the same credentials if you redeploy - Secrets don't incur costs - Re-entering passwords and keys is tedious - Maintains consistency across deployments
Only delete if: - You're performing a complete teardown and won't redeploy - You want to use different credentials in the future - Security requires credential rotation
Prompted question:
Service Account:
- Used by compute instances to access GCP services
- Safe to keep, will be reused in new deployment
Delete service account? [y/N]:
Recommendation: Press N (or just Enter)
Why keep: - Service accounts don't incur costs - Will be automatically reused in next deployment - Maintains consistent IAM structure - Deletion and recreation can cause IAM propagation delays
Only delete if: - You're performing a complete security audit - You're permanently decommissioning the entire project - You need to reset all IAM permissions
The script removes (regardless of your choices above):
✅ Always deleted: - Load balancer (forwarding rule, proxy, URL map) - Backend service and health checks - Compute instances and instance groups - Instance templates - Firewall rules - Autoscalers
❌ Never deleted automatically: - GCS Bucket (contains your MPC database) - SSL Certificate (takes time to provision, safe to keep) - GCP Project (container for all resources) - Static IP addresses (if reserved separately)
⚙️ Optionally deleted: - Secrets (if you choose to delete) - Service Account (if you choose to delete)
The infrastructure can be redeployed by running the deployment script again. If you kept secrets and service account (recommended), the deployment will be faster as these resources will be reused.
As mentioned earlier, the bucket must be manually deleted:
# List your MPC buckets
gsutil ls -p YOUR_PROJECT_ID | grep vaultody-co-signer-artifacts
# Verify contents (optional but recommended)
gsutil ls -r gs://vaultody-co-signer-artifacts-TIMESTAMP
# Delete the bucket (⚠️ PERMANENT - key material will be lost)
gsutil -m rm -r gs://vaultody-co-signer-artifacts-TIMESTAMP
If you want to delete the SSL certificate (not recommended unless changing domain):
# Check certificate status
gcloud compute ssl-certificates list --project=YOUR_PROJECT_ID
# Delete certificate (only if needed)
gcloud compute ssl-certificates delete mpc-co-signer-cert \
--global \
--project=YOUR_PROJECT_ID
Note: If you delete the SSL certificate and redeploy with the same domain, you'll need to wait another 10-15 minutes for a new certificate to be provisioned.
Estimated monthly costs for running the MPC co-signer infrastructure:
| Component | Estimated Cost |
|---|---|
| Compute Instance (n2-standard-2) | ~$50/month |
| Load Balancer | ~$18-25/month |
| GCS Bucket Storage (< 1GB) | < $0.05/month |
| Secrets (< 10 secrets) | Free |
| Egress Traffic | Varies ($0.12/GB) |
| Total | ~$70-80/month |
Notes: - Confidential VMs cost 10-15% more - Larger machine types increase compute costs - Static IP addresses are free while in use - Managed SSL certificates are free - Costs scale with traffic and storage
Cost optimization tips: - Use preemptible/spot instances if downtime is acceptable (not recommended for production MPC) - Use committed use discounts for 1-3 year terms - Monitor and set budget alerts in GCP Console
1. Zone Capacity Exhaustion (Confidential VMs)
ERROR: ZONE_RESOURCE_POOL_EXHAUSTED_WITH_DETAILS
2. Billing Not Enabled
ERROR: Billing is not enabled for project
3. DNS Not Resolving
Certificate stuck in PROVISIONING or FAILED_NOT_VISIBLE
dig +short yourdomain.com4. Health Checks Failing
Backend service shows instances as UNHEALTHY
docker logs mpc-co-signer - Verify firewall rules allow health check source ranges - Ensure container is listening on port 80005. Permission Denied Errors
ERROR: (gcloud...) User does not have permission
Key Management: - Store private keys securely (hardware security module, password manager) - Never commit keys to version control - Rotate credentials periodically
Access Control: - Use dedicated service accounts with minimal permissions - Enable MFA on your GCP account - Limit who can access the GCP project
Network Security: - The deployed firewall rules only allow necessary traffic - Health checks from Google's IP ranges: 130.211.0.0/22, 35.191.0.0/16 - HTTPS traffic from anywhere (load balancer requirement)
Monitoring: - Enable GCP audit logs - Set up alerts for unusual activity - Monitor instance health and logs regularly
Backup: - The GCS bucket provides automatic backup of MPC state - Keep secure copies of your private keys and credentials - Document your deployment configuration
Verify in Vaultody Portal: - Log in to the Vaultody web dashboard - Confirm your co-signer node is registered and online - Check node status and health metrics
Test MPC Operations: - Perform test signing operations through the portal - Verify the co-signer participates correctly in MPC protocols
Set Up Monitoring: - Configure GCP monitoring and alerting - Set up log forwarding if needed - Create uptime checks
Document Your Deployment: - Save all credentials securely - Document domain, project ID, and zone used - Keep a record of your public key and node configuration