Operator keys are cryptographic keys used to identify your SSV operator node and decrypt validator share data. This guide covers generating and managing these keys securely.
Overview
Each SSV operator needs an RSA key pair:
- Private Key: Used to decrypt validator shares assigned to your operator
- Public Key: Your operator’s public identity on the SSV network
Keep your operator private key secure! Loss of this key means you cannot decrypt validator shares and will need to regenerate it, requiring re-registration of all validators.
Generating Operator Keys
The SSV node binary provides the generate-operator-keys command to create operator keys in three formats.
Raw format is NOT recommended for production use as it exposes sensitive data. Use encrypted format for production.
Generate a raw operator key:
./bin/ssvnode generate-operator-keys
Example output:
{
"level": "info",
"time": "2024-01-15T10:30:45Z",
"caller": "cli/generate_operator_keys.go:70",
"message": "generated public key (base64)",
"pk": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcW..."
}
{
"level": "info",
"time": "2024-01-15T10:30:45Z",
"caller": "cli/generate_operator_keys.go:71",
"message": "generated private key (base64)",
"sk": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVB..."
}
The private key (sk) can be used directly in config.yaml:
OperatorPrivateKey: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVB...
Option 2: Encrypted Keystore (Recommended)
For production environments, generate an encrypted keystore:
Create a password file
echo "your-strong-password" > password.txt
chmod 600 password.txt
Generate encrypted keystore
./bin/ssvnode generate-operator-keys --password-file=password.txt
This creates encrypted_private_key.json in the current directory.Secure the keystore files
chmod 600 encrypted_private_key.json
chmod 600 password.txt
# Move to secure location
mkdir -p /secure/keystore
mv encrypted_private_key.json /secure/keystore/
mv password.txt /secure/keystore/
Configure the node
Update config.yaml:KeyStore:
PrivateKeyFile: /secure/keystore/encrypted_private_key.json
PasswordFile: /secure/keystore/password.txt
Example keystore JSON structure:
encrypted_private_key.json
{
"version": 4,
"id": "...",
"pubkey": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0t...",
"crypto": {
"cipher": "aes-128-ctr",
"ciphertext": "...",
"cipherparams": {
"iv": "..."
},
"kdf": "scrypt",
"kdfparams": {
"n": 262144,
"r": 8,
"p": 1,
"dklen": 32,
"salt": "..."
},
"mac": "..."
}
}
Option 3: Convert Existing Key to Keystore
If you already have a raw operator key and want to encrypt it:
# Save your existing private key to a file
echo "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQ..." > operator_key.txt
# Create password file
echo "your-strong-password" > password.txt
# Convert to encrypted keystore
./bin/ssvnode generate-operator-keys \
--password-file=password.txt \
--operator-key-file=operator_key.txt
This generates encrypted_private_key.json from your existing key.
After converting to keystore, securely delete the plain-text key file:shred -u operator_key.txt
Using Operator Keys
Configuration Methods
You can configure operator keys in two ways:
Method 1: Base64-encoded private key (not recommended for production)
OperatorPrivateKey: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVB...
Method 2: Encrypted keystore (recommended)
KeyStore:
PrivateKeyFile: /path/to/encrypted_private_key.json
PasswordFile: /path/to/password.txt
Cannot use both methods simultaneously. Choose one approach and ensure the other is not configured.
To get your operator’s public key from a keystore:
jq -r '.pubkey' /secure/keystore/encrypted_private_key.json
For raw format, the public key was displayed during generation. You’ll need this when registering your operator on the SSV network.
Key Management Best Practices
Security
- Never share your private key - Only the public key should be shared
- Use strong passwords - For encrypted keystores, use passwords with:
- At least 16 characters
- Mix of uppercase, lowercase, numbers, and symbols
- Not used anywhere else
- Restrict file permissions:
chmod 600 encrypted_private_key.json
chmod 600 password.txt
chown ssvnode:ssvnode *.json *.txt
- Store backups securely - Keep encrypted backups in multiple secure locations
- Use hardware security modules (HSM) - For enterprise deployments, consider HSM integration
Backup Strategy
Create encrypted backup
# Backup keystore and password
tar czf operator-keys-backup.tar.gz \
encrypted_private_key.json \
password.txt
# Encrypt the backup
gpg --symmetric --cipher-algo AES256 operator-keys-backup.tar.gz
Store in multiple locations
- Secure cloud storage (encrypted)
- Hardware encrypted USB drive
- Password manager’s secure notes
- Physical safe (for critical production keys)
Document recovery process
Create a recovery document including:
- Location of backups
- Decryption procedures
- Contact information for key stakeholders
Key Rotation
Rotating operator keys requires re-registering all validators with new shares. Plan this carefully during low-activity periods.
To rotate operator keys:
- Generate new operator keys
- Update operator registration on SSV contract with new public key
- Re-split all validator keys with new operator public key
- Update validators on SSV network
- Update node configuration with new private key
- Restart node
Older versions of SSV used a different keystore format. If migrating:
./bin/ssvnode generate-operator-keys \
--password-file=password.txt \
--legacy-pubkey
This generates a keystore with pubKey instead of pubkey field for backward compatibility.
Troubleshooting
”Could not decrypt operator private key keystore”
Cause: Incorrect password or corrupted keystore file.
Solution:
- Verify password file contains correct password
- Check file permissions (should be readable by node process)
- Restore from backup if corrupted
”Cannot enable both OperatorPrivateKey and PrivateKeyFile”
Cause: Both raw key and keystore configured simultaneously.
Solution: Remove one configuration method from config.yaml:
# Remove this if using KeyStore
# OperatorPrivateKey: ...
# Or remove this if using OperatorPrivateKey
# KeyStore:
# PrivateKeyFile: ...
# PasswordFile: ...
“Operator private key is not matching the one encrypted the storage”
Cause: Attempting to use a different private key than originally configured.
Solution: SSV nodes store a hash of the operator private key to prevent accidental key changes. To use a different key:
- Clear the database:
rm -rf ./data/db
- Use the new key (will resync all data)
Clearing the database and changing keys will require re-registering all validators.
Using with Remote Signer (SSV Signer)
For enhanced security, you can use a remote signing service:
SSVSigner:
Endpoint: https://ssv-signer.example.com
RequestTimeout: 10s
KeystoreFile: /path/to/client-keystore.json
KeystorePasswordFile: /path/to/client-password.txt
ServerCertFile: /path/to/server-cert.pem
When using SSVSigner, do not configure OperatorPrivateKey or KeyStore in the node config.
Next Steps