Skip to content

Security: x0lg0n/RemitFlow

SECURITY.md

RemitFlow Security Guide πŸ”’

Production Security Best Practices & Secrets Management


🚨 Critical Security Issues Fixed

Problem: Secrets Hardcoded in docker-compose.yml

Before (INSECURE):

environment:
  - JWT_SECRET=dev-secret-change-me
  - SEP10_SERVER_SECRET=SAC2T4LY4EOY35VZDBNBORDDLXA56S5FERIBTXXPTES2VJH5QFK2DODN
  - ORACLE_SECRET_KEY=412b18e689dc5f11fc8ca91a179a18e25ac0fa430cd5656074127df914bbad65
  - POSTGRES_PASSWORD=postgres

❌ Problems:

  • Secrets visible in Git history
  • Anyone with repo access can see credentials
  • No separation between environments
  • Impossible to rotate secrets without code changes

After (SECURE):

env_file:
  - .env
environment:
  - JWT_SECRET=${JWT_SECRET}
  - SEP10_SERVER_SECRET=${SEP10_SERVER_SECRET}
  - ORACLE_SECRET_KEY=${ORACLE_SECRET_KEY}
  - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}

βœ… Benefits:

  • Secrets stored in .env (ignored by Git)
  • Different secrets per environment
  • Easy to rotate without code changes
  • Follows 12-factor app methodology

πŸ” Secrets Management Strategy

1. Environment Files Structure

docker/
β”œβ”€β”€ .env.example          # βœ… Commit to Git - template only
β”œβ”€β”€ .env                  # ❌ NEVER commit - actual secrets
└── docker-compose.yml    # βœ… Commit - references .env vars

2. Git Ignore Rules

Already configured in .gitignore:

.env
.env.local
.env.production
docker/.env

3. Quick Setup

# Generate secure .env file with random secrets
./scripts/setup-env.sh

# Or manually
cp docker/.env.example docker/.env
# Edit with your secrets
nano docker/.env

πŸ›‘οΈ Security Best Practices

Development Environment

1. Generate Strong Secrets

# JWT Secret (minimum 32 bytes)
openssl rand -base64 32

# Stellar Keypairs (for SEP-10 and Oracle)
stellar keys generate --network testnet

# Database Password
openssl rand -base64 24

2. Local Development Workflow

# 1. Clone repository
git clone https://github.com/your-org/remitflow.git
cd remitflow

# 2. Setup environment (generates secure secrets)
./scripts/setup-env.sh

# 3. Review generated secrets
cat docker/.env | grep -v '^#' | grep -v '^$'

# 4. Start services
cd docker && docker compose up -d

# 5. Verify
curl http://localhost:3001/health

Production Environment

1. Use Secret Management Services

Option A: Docker Secrets (Swarm)

services:
  backend:
    secrets:
      - jwt_secret
      - sep10_secret

secrets:
  jwt_secret:
    external: true
  sep10_secret:
    external: true

Option B: HashiCorp Vault

# Store secrets in Vault
vault kv put secret/remitflow/production \
  jwt_secret="your-secret" \
  sep10_secret="your-secret"

# Retrieve in deployment
vault kv get -field=jwt_secret secret/remitflow/production

Option C: AWS Secrets Manager

# Store secret
aws secretsmanager create-secret \
  --name remitflow/production/jwt-secret \
  --secret-string "your-secret"

# Retrieve in ECS/EKS
aws secretsmanager get-secret-value \
  --secret-id remitflow/production/jwt-secret

2. Environment-Specific Files

config/
β”œβ”€β”€ .env.development    # Development secrets
β”œβ”€β”€ .env.staging        # Staging secrets
└── .env.production     # Production secrets (restricted access)

Load based on environment:

docker compose --env-file config/.env.$ENVIRONMENT up -d

3. Secret Rotation

Monthly Rotation Checklist:

  • Rotate JWT_SECRET
  • Rotate SEP10_SERVER_SECRET
  • Rotate ORACLE_SECRET_KEY
  • Rotate database passwords
  • Rotate anchor API tokens
  • Update all environments
  • Test all services after rotation

Rotation Script:

#!/bin/bash
# scripts/rotate-secrets.sh

# Generate new secrets
NEW_JWT=$(openssl rand -base64 32)
NEW_DB=$(openssl rand -base64 24)

# Update .env file
sed -i "s|JWT_SECRET=.*|JWT_SECRET=$NEW_JWT|g" docker/.env
sed -i "s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$NEW_DB|g" docker/.env

# Restart services
cd docker && docker compose down && docker compose up -d

echo "βœ… Secrets rotated successfully"

πŸ” Security Checklist

Before Committing Code

  • No .env files committed
  • No hardcoded secrets in source code
  • No API keys in comments
  • No private keys in repository
  • .gitignore includes all secret files
  • Git history scanned for leaked secrets

Before Deploying to Production

  • All default passwords changed
  • Strong secrets generated (32+ bytes)
  • HTTPS/TLS enabled
  • CORS restricted to production domains
  • Rate limiting enabled
  • Logging configured (no sensitive data in logs)
  • Database access restricted
  • Firewall rules configured

Ongoing Security

  • Regular dependency audits (pnpm audit)
  • Secret rotation (monthly)
  • Access log monitoring
  • Failed authentication alerts
  • Backup encryption
  • SSL certificate renewal
  • Penetration testing (quarterly)

🚫 Common Security Mistakes

❌ DON'T Do This

# Hardcoded secrets in docker-compose.yml
environment:
  - JWT_SECRET=my-secret-123
  - DB_PASSWORD=password

# Committing .env files
git add docker/.env
git commit -m "Add environment config"

# Logging sensitive data
console.log('User token:', token);
logger.info('DB password:', process.env.DB_PASSWORD);

# Weak secrets
JWT_SECRET=123456
POSTGRES_PASSWORD=admin

βœ… DO This Instead

# Use env_file
env_file:
  - .env

# Keep .env out of Git
echo "docker/.env" >> .gitignore

# Never log secrets
logger.info('User authenticated successfully');
logger.debug('DB connection established');

# Strong, random secrets
JWT_SECRET=$(openssl rand -base64 32)
POSTGRES_PASSWORD=$(openssl rand -base64 24)

πŸ› οΈ Security Tools

1. Git Secrets Scanning

# Install git-secrets
brew install git-secrets  # macOS
apt-get install git-secrets  # Linux

# Scan for secrets
git-secrets --scan

2. Pre-commit Hooks

# Install pre-commit
pip install pre-commit

# Add to .pre-commit-config.yaml
repos:
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets

3. Docker Security

# Scan images for vulnerabilities
docker scout cve remitflow-backend:latest

# Check container security
docker run --rm -it aquasec/trivy image remitflow-backend:latest

πŸ“‹ Incident Response

If Secrets Are Leaked

  1. Immediate Actions (within 1 hour)

    • Rotate ALL compromised secrets
    • Revoke affected API tokens
    • Check access logs for unauthorized access
    • Notify security team
  2. Short-term (within 24 hours)

    • Audit all systems using leaked secrets
    • Update .env files with new secrets
    • Restart all affected services
    • Monitor for suspicious activity
  3. Long-term (within 1 week)

    • Investigate how leak occurred
    • Implement additional safeguards
    • Update security documentation
    • Conduct security training

Emergency Secret Rotation

#!/bin/bash
# scripts/emergency-rotate.sh

echo "🚨 EMERGENCY SECRET ROTATION"
echo "This will rotate all secrets and restart services"
read -p "Continue? (y/N) " -n 1 -r
echo

if [[ $REPLY =~ ^[Yy]$ ]]; then
  # Generate new secrets
  ./scripts/setup-env.sh

  # Restart all services
  cd docker && docker compose down && docker compose up -d

  echo "βœ… Emergency rotation complete"
  echo "⚠️  Notify all team members to pull new .env file"
fi

πŸ“š Resources


πŸ†˜ Support


Remember: Security is everyone's responsibility. When in doubt, rotate the secret! πŸ”

There aren't any published security advisories