Secrets Management Runbook¶
Operational procedures for Infisical secrets management - Step-by-step guides for managing secrets, projects, and environments.
Table of Contents¶
- Overview
- Authentication
- Managing Secrets
- Managing Projects & Environments
- Export & Import
- Backup & Restore
- Emergency Access
- Troubleshooting
Overview¶
Purpose¶
This runbook provides step-by-step procedures for: - Authenticating to Infisical - Adding, updating, and deleting secrets - Creating and managing projects/environments - Exporting secrets for development - Backing up and restoring Infisical - Emergency access scenarios
Prerequisites¶
- SSH access to Hetzner VPS (100.80.53.55)
- Infisical CLI installed (pre-installed on server)
- Infisical account credentials
Authentication¶
Login to Infisical¶
When to use: First time, or after logout/session expired
Procedure:
Step 1: Run login command
Alternative domain:
Step 2: Follow prompts
? How would you like to authenticate?
> Email/Password
Universal Auth
# Select: Email/Password
? Email: your-email@example.com
? Password: [hidden]
✔ Successfully authenticated!
Step 3: Verify authentication
Check Authentication Status¶
# Quick check
infisical whoami
# If not authenticated:
# Error: Not authenticated. Run 'infisical login'
Logout¶
Managing Secrets¶
List Secrets¶
Show all secrets in an environment:
# List secrets in dev environment
infisical secrets --env=dev --projectId=personal-vault
# Expected output:
# KEY VALUE
# ANTHROPIC_API_KEY sk-ant-api03-...
# GOOGLE_API_KEY AIza...
# DATABASE_URL postgresql://...
List secrets in different environment:
# Production secrets
infisical secrets --env=prod --projectId=personal-vault
# Staging secrets
infisical secrets --env=staging --projectId=personal-vault
Add or Update Secret¶
Set a single secret:
# Syntax
infisical secrets set <KEY>=<VALUE> --env=<environment> --projectId=<project>
# Example: Add API key
infisical secrets set ANTHROPIC_API_KEY="sk-ant-api03-..." --env=dev --projectId=personal-vault
# Example: Add database URL
infisical secrets set DATABASE_URL="postgresql://user:pass@localhost:5432/mydb" --env=dev --projectId=personal-vault
Set multiple secrets:
# One command, multiple secrets
infisical secrets set \
API_KEY="abc123" \
SECRET_KEY="xyz789" \
DATABASE_URL="postgresql://localhost/db" \
--env=dev --projectId=personal-vault
Update existing secret:
# Same command - overwrites existing value
infisical secrets set ANTHROPIC_API_KEY="sk-ant-new-key" --env=dev --projectId=personal-vault
Get Single Secret¶
# Get specific secret value
infisical secrets get ANTHROPIC_API_KEY --env=dev --projectId=personal-vault
# Output:
# sk-ant-api03-...
Delete Secret¶
# Remove secret
infisical secrets delete ANTHROPIC_API_KEY --env=dev --projectId=personal-vault
# Confirm when prompted
? Are you sure you want to delete ANTHROPIC_API_KEY? Yes
✔ Secret deleted successfully
Warning: Deletion is permanent. Ensure you have a backup or the value recorded elsewhere before deleting.
Managing Projects & Environments¶
List Projects¶
# Show all projects
infisical projects
# Example output:
# ID NAME
# personal-vault Personal Vault
# work-project Work Project
# terraform-state Terraform State
Create New Project¶
Via CLI:
# Create project
infisical projects create --name="my-new-project"
# Output:
# ✔ Project created: my-new-project (id: abc123...)
Via Web UI (recommended for first project):
1. Go to https://secrets.kua.cl
2. Click "New Project"
3. Enter name: my-new-project
4. Click "Create"
List Environments¶
# Environments are per-project
# List environments for a project
infisical envs --projectId=personal-vault
# Common environments:
# - dev (development)
# - staging
# - prod (production)
Create New Environment¶
Via Web UI:
1. Go to https://secrets.kua.cl
2. Select project
3. Settings → Environments
4. Click "New Environment"
5. Enter name: staging
6. Click "Create"
Note: CLI doesn't support creating environments directly. Use Web UI.
Export & Import¶
Export Secrets¶
To dotenv format (for use with Docker --env-file):
# Export to file
infisical export --env=dev --projectId=personal-vault --format=dotenv > /tmp/secrets.env
# File contents:
# ANTHROPIC_API_KEY=sk-ant-api03-...
# GOOGLE_API_KEY=AIza...
# DATABASE_URL=postgresql://...
To JSON format:
# Export as JSON
infisical export --env=dev --projectId=personal-vault --format=json > /tmp/secrets.json
# File contents:
# {
# "ANTHROPIC_API_KEY": "sk-ant-api03-...",
# "GOOGLE_API_KEY": "AIza...",
# "DATABASE_URL": "postgresql://..."
# }
To environment variables (inject directly):
# Use in scripts
eval $(infisical export --env=dev --projectId=personal-vault --format=dotenv)
# Now secrets are in environment
echo $ANTHROPIC_API_KEY
# sk-ant-api03-...
Security warning: Exported files contain sensitive data. Always:
- Delete after use: rm /tmp/secrets.env
- Use restrictive permissions: chmod 600 /tmp/secrets.env
- Never commit to Git
Import Secrets¶
From dotenv file:
# Import secrets from .env file
infisical secrets import --env=dev --projectId=personal-vault --file=.env
# .env file format:
# KEY1=value1
# KEY2=value2
Bulk import:
# Import from JSON
infisical secrets import --env=dev --projectId=personal-vault --file=secrets.json --format=json
Backup & Restore¶
Backup ENCRYPTION_KEY¶
CRITICAL: The ENCRYPTION_KEY in ~/infisical/.env encrypts ALL secrets. If lost, ALL secrets are permanently lost.
Procedure:
Step 1: Locate .env file
# On Hetzner VPS
ls -la ~/infisical/.env
# File contains:
# ENCRYPTION_KEY=...
# MONGO_PASSWORD=...
# AUTH_SECRET=...
# SITE_URL=...
Step 2: Backup locally (encrypted)
# On Hetzner VPS
cd ~/infisical
# Encrypt with GPG
gpg --symmetric --cipher-algo AES256 .env
# Creates: .env.gpg
ls -la .env.gpg
Step 3: Copy to secondary server
# From Hetzner to Kimsufi
scp ~/infisical/.env.gpg ubuntu@100.81.231.36:~/infisical-hetzner-backup.env.gpg
Step 4: Copy to local machine
# From Hetzner to MacBook
scp kavi@100.80.53.55:~/infisical/.env.gpg ~/Backups/infisical-encryption-key-$(date +%Y%m%d).gpg
Step 5: Upload to cloud (optional)
# Upload to cloud storage (encrypted)
# Example: AWS S3, Google Drive, Dropbox
# Ensure it's the .gpg (encrypted) version
Backup schedule: Monthly or after any major change
Backup All Secrets¶
Export all secrets from all environments:
# Create backup directory
mkdir -p ~/infisical-backups/$(date +%Y%m%d)
# Export each environment
infisical export --env=dev --projectId=personal-vault --format=json \
> ~/infisical-backups/$(date +%Y%m%d)/personal-vault-dev.json
infisical export --env=staging --projectId=personal-vault --format=json \
> ~/infisical-backups/$(date +%Y%m%d)/personal-vault-staging.json
infisical export --env=prod --projectId=personal-vault --format=json \
> ~/infisical-backups/$(date +%Y%m%d)/personal-vault-prod.json
# Encrypt backup
tar czf - ~/infisical-backups/$(date +%Y%m%d)/ | \
gpg --symmetric --cipher-algo AES256 \
> ~/infisical-backups/backup-$(date +%Y%m%d).tar.gz.gpg
# Remove unencrypted files
rm -rf ~/infisical-backups/$(date +%Y%m%d)/
Restore from Backup¶
Scenario: Infisical server crashed, need to restore
Step 1: Restore ENCRYPTION_KEY
# On Hetzner VPS (after fresh Infisical install)
cd ~/infisical
# Copy encrypted .env from backup
scp macbook:~/Backups/infisical-encryption-key-20250115.gpg .env.gpg
# Decrypt
gpg --decrypt .env.gpg > .env
# Verify
cat .env | grep ENCRYPTION_KEY
Step 2: Restart Infisical
# On Hetzner VPS
cd ~/infisical
docker-compose down
docker-compose up -d
# Verify services running
docker-compose ps
Step 3: Verify Secrets Accessible
# Login
infisical login --domain=https://secrets.kua.cl
# Check secrets
infisical secrets --env=dev --projectId=personal-vault
# Should see all secrets (decrypted with restored ENCRYPTION_KEY)
Step 4: If secrets still missing, restore from backup
# Decrypt backup
gpg --decrypt ~/infisical-backups/backup-20250115.tar.gz.gpg | tar xzf -
# Import each environment
infisical secrets import --env=dev --projectId=personal-vault \
--file=~/infisical-backups/20250115/personal-vault-dev.json --format=json
infisical secrets import --env=staging --projectId=personal-vault \
--file=~/infisical-backups/20250115/personal-vault-staging.json --format=json
Emergency Access¶
Scenario 1: Infisical Server Down¶
Problem: Hetzner VPS offline, can't access Infisical
Solution: Use local cached secrets or backup exports
Option A: Cached secrets
If you recently ran dev(), temp file may still exist:
# Check for recent exports
ls -la /tmp/env-*.list
# Use if found
docker run --env-file /tmp/env-12345.list ...
Option B: Backup exports
# Use backup from Backup All Secrets procedure
gpg --decrypt ~/infisical-backups/backup-20250115.tar.gz.gpg | tar xzf -
# Use secrets
cat ~/infisical-backups/20250115/personal-vault-dev.json
Option C: Emergency credentials
Keep critical credentials in secure secondary location: - Password manager (1Password, Bitwarden) - Encrypted file on separate device - Physical secure storage (for ENCRYPTION_KEY)
Scenario 2: ENCRYPTION_KEY Lost¶
Problem: Lost all backups of ENCRYPTION_KEY
Result: ALL SECRETS PERMANENTLY LOST
No recovery possible - Infisical uses symmetric encryption, no master key.
Prevention: - ✅ Multiple backups (Hetzner, Kimsufi, local, cloud) - ✅ GPG encrypted - ✅ Physical backup (USB in safe) - ✅ Test restore quarterly
Scenario 3: Forgot Infisical Password¶
Problem: Can't login to Infisical Web UI or CLI
Solution: Password reset via MongoDB
Step 1: Access MongoDB
# On Hetzner VPS
cd ~/infisical
docker-compose exec mongo mongosh
# Connect to database
use infisical
Step 2: Find user
Step 3: Reset password
⚠️ Warning: This requires encrypting a new password with bcrypt. Recommend using Web UI password reset if available.
Alternative: Recreate user: 1. Create new user via Web UI 2. Grant admin permissions via MongoDB 3. Use new user to access secrets
Troubleshooting¶
"Not authenticated"¶
Symptom:
Solution:
"Project not found"¶
Symptom:
Solution:
# List available projects
infisical projects
# Use correct project ID
infisical secrets --env=dev --projectId=personal-vault
"Environment not found"¶
Symptom:
Solution:
# List available environments
infisical envs --projectId=personal-vault
# Create environment via Web UI if missing
# Then retry command
"Failed to fetch secrets"¶
Symptom:
Causes: 1. Infisical server down 2. Network issue 3. Authentication expired
Solution:
Check 1: Server running?
# On Hetzner VPS
cd ~/infisical
docker-compose ps
# All services should be "Up"
# If not:
docker-compose up -d
Check 2: Network accessible?
Check 3: Re-authenticate
"Secret already exists"¶
Symptom:
infisical secrets set API_KEY="new" --env=dev --projectId=personal-vault
# Error: Secret already exists
Solution: Use set (not create) - it will update existing:
# 'set' command overwrites existing
infisical secrets set API_KEY="new-value" --env=dev --projectId=personal-vault
ENCRYPTION_KEY mismatch after restore¶
Symptom: After restoring .env, secrets are gibberish or errors
Cause: Wrong ENCRYPTION_KEY (restored from wrong backup)
Solution:
# Verify ENCRYPTION_KEY hash
cat ~/infisical/.env | grep ENCRYPTION_KEY
# Compare with backup
gpg --decrypt ~/backup.env.gpg | grep ENCRYPTION_KEY
# If different, restore correct backup
Summary¶
Secrets Management Operations:
- ✅ Authentication: infisical login --domain=https://secrets.kua.cl
- ✅ List secrets: infisical secrets --env=dev --projectId=personal-vault
- ✅ Add/update secret: infisical secrets set KEY=value --env=dev --projectId=personal-vault
- ✅ Delete secret: infisical secrets delete KEY --env=dev --projectId=personal-vault
- ✅ Export: infisical export --env=dev --projectId=personal-vault --format=dotenv
Critical Operations: - ✅ Backup ENCRYPTION_KEY: Monthly, encrypted, multiple locations - ✅ Backup all secrets: Monthly exports, encrypted - ✅ Test restore: Quarterly verification
Emergency: - Use backup exports if Infisical down - ENCRYPTION_KEY loss = permanent data loss (no recovery) - Password reset via MongoDB or Web UI
Security Rules:
1. Never share ENCRYPTION_KEY in plaintext
2. Always encrypt backups (GPG)
3. Delete exported files after use (rm /tmp/secrets.env)
4. Use restrictive permissions (chmod 600)
5. Never commit secrets to Git
What's Next: - See Infisical Architecture - complete Infisical guide - See SSH Operations - SSH key management - See dev() Function - how secrets are injected