ChainLaunch

Security Best Practices

This guide outlines security best practices for deploying and operating ChainLaunch.

This guide outlines security best practices for deploying and operating ChainLaunch.

Access Control & Authentication

1. Strong Password Policy

Enforce:

  • Minimum 12 characters
  • Mix of uppercase, lowercase, numbers, and symbols
  • No dictionary words or personal information
  • Change password every 90 days

Configuration:

security:
  password_policy:
    min_length: 12
    require_uppercase: true
    require_lowercase: true
    require_numbers: true
    require_symbols: true
    expiration_days: 90

2. Multi-Factor Authentication (MFA)

Enable MFA for:

  • All admin accounts (required)
  • All operator accounts (recommended)
  • Users with sensitive permissions

Via UI:

  1. Go to Settings → Users
  2. Select user
  3. Click Enable MFA
  4. Follow 2FA setup (TOTP or U2F)

3. API Key Security

Best Practices:

  • ✅ Rotate API keys every 90 days
  • ✅ Set specific expiration dates
  • ✅ Use separate keys per service
  • ✅ Minimize permissions per key
  • ✅ Store securely (environment variables, secrets manager)
  • ❌ Never commit API keys to version control
  • ❌ Never use permanent keys for automation

Create restricted API key:

chainlaunch api-keys create \
  --name ci-cd-pipeline \
  --role OPERATOR \
  --permission NODE_READ,NETWORK_READ,SYSTEM_MONITOR \
  --expires-in 365d

4. OIDC/SSO Setup

Enable Single Sign-On for enterprise:

  1. Go to Settings → Authentication
  2. Select OIDC provider (Keycloak, Auth0, Okta)
  3. Configure provider credentials
  4. Map OIDC groups to ChainLaunch roles

Configuration Example:

oidc:
  provider: keycloak
  issuer_url: https://keycloak.example.com/auth/realms/master
  client_id: chainlaunch
  client_secret: "${OIDC_CLIENT_SECRET}"
  group_claim: groups
  group_mappings:
    admins: admin
    operators: operator
    viewers: viewer

Network Security

1. TLS/SSL Encryption

Enable TLS for all communications:

  • API server TLS
  • Node-to-node TLS
  • P2P network TLS

Configuration:

tls:
  enabled: true
  cert_file: /etc/chainlaunch/tls.cert
  key_file: /etc/chainlaunch/tls.key
  min_version: "1.2"
  cipher_suites:
    - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305

2. Firewall Configuration

Whitelist traffic:

Incoming:
  - Port 8100 (API) - From admin networks only
  - Port 8545 (JSON-RPC) - From app servers only
  - Port 30303 (P2P) - From other validators/nodes only
  - Port 3101 (UI) - From trusted networks only

Outgoing:
  - Port 443 (HTTPS) - For external services
  - Port 53 (DNS) - For DNS resolution

3. Network Segmentation

Isolate networks:

┌─────────────────┐
│  Internet       │
└────────┬────────┘
         │ (Firewall)
         │
┌────────▼────────┐
│  Public Subnet  │ (Bastion, Load Balancer)
└────────┬────────┘
         │ (Internal Network)
         │
┌────────▼────────────────────────┐
│  Private Subnet                  │
│  ┌─────────────────────────────┐ │
│  │  ChainLaunch Server      │ │
│  │  ┌──────────────────────┐    │ │
│  │  │  Validator Nodes     │    │ │
│  │  │  Database            │    │ │
│  │  └──────────────────────┘    │ │
│  └─────────────────────────────┘ │
└─────────────────────────────────┘

4. DDoS Protection

Implement rate limiting:

curl -X POST http://localhost:8100/api/v1/settings/ratelimit \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "requests_per_minute": 1000,
    "burst_size": 50,
    "enable_ddos_protection": true
  }'

Monitoring & Metrics Hardening

ChainLaunch can deploy and manage an embedded Prometheus instance to scrape your nodes (see Configure Monitoring). Prometheus has no built-in authentication, so its network exposure and the admin API are the two settings you must get right.

1. Prometheus binds to loopback by default

As of the latest release, the managed Prometheus instance binds to 127.0.0.1 (loopback) by default in all three deployment modes — Docker, systemd, and launchd. Only processes on the same host (including the ChainLaunch backend, which dials http://localhost:<port> to query metrics) can reach it. Nothing is published on the network unless you explicitly opt in.

This is a change from earlier behavior, where Prometheus could be reachable on 0.0.0.0. If you previously relied on a remote scraper hitting the ChainLaunch Prometheus port directly, you must now either run that scraper on the same host or opt into external exposure (below).

Prometheus is unauthenticated

The Prometheus HTTP endpoint exposes every metric ChainLaunch collects — node topology, resource usage, internal labels — to anyone who can reach it. Never bind it to 0.0.0.0 on a host with a public IP without an authenticating reverse proxy in front of it.

2. Opting into external access safely

If an external scraper, standalone Grafana, federation peer, or external Alertmanager genuinely needs to reach Prometheus directly, set the listen address to 0.0.0.0. Do this only behind one of the following controls:

  • Authenticating reverse proxy (recommended). Put nginx, Caddy, Traefik, or oauth2-proxy in front of Prometheus and keep Prometheus itself on loopback. The proxy terminates TLS and enforces auth; Prometheus never listens on a routable interface.
  • Private network / firewall allowlist. If you must expose the port, restrict it to the scraper's source IPs (security group, ufw, or the firewall rules in Network Security above). Treat the Prometheus port like the API port: admin networks only.
  • mTLS or a service mesh. In Kubernetes, keep Prometheus on ClusterIP and require client certificates or mesh policy for cross-namespace scrapes.

Example nginx reverse proxy enforcing basic auth while keeping Prometheus on loopback:

server {
    listen 443 ssl;
    server_name prometheus.example.com;
 
    ssl_certificate     /etc/nginx/tls/fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/privkey.pem;
 
    location / {
        auth_basic           "Prometheus";
        auth_basic_user_file /etc/nginx/prometheus.htpasswd;
        proxy_pass           http://127.0.0.1:9090;  # Prometheus stays on loopback
    }
}

Keep the listen address at its 127.0.0.1 default whenever the backend is the only consumer — which is the case for the in-app dashboards and per-node metrics views.

Prefer remote_write over exposing the port

If the goal is to centralize metrics in an external store (Grafana Mimir, Grafana Cloud, AWS Managed Prometheus, Datadog), you usually do not need to expose Prometheus at all. Configure outbound remote_write instead and keep the endpoint on loopback. See External Observability.

3. The --web.enable-admin-api risk

Prometheus' admin API (--web.enable-admin-api) exposes unauthenticated, destructive endpoints such as POST /api/v1/admin/tsdb/delete_series and DELETE /api/v1/data. Anyone who can reach the Prometheus port could wipe your metrics history — and it completely bypasses ChainLaunch RBAC.

ChainLaunch does not use the admin API internally, so it is now opt-in and off by default in all three deployment modes. Leave it off:

  • Off (default). ChainLaunch never enables --web.enable-admin-api. Recommended for virtually all deployments.
  • ⚠️ On (opt-in only). Enable it only if you have a specific operational need (e.g. deleting series during a controlled cleanup), and only when Prometheus is on loopback or behind an authenticating proxy that blocks the admin paths.

If you turn the admin API on, treat the Prometheus port as a privileged interface and restrict access exactly as you would the ChainLaunch API.

4. Notification-provider secrets are protected

SMTP passwords, webhook HMAC secrets, API tokens, and custom auth headers stored on notification providers (see Notifications) are handled as write-only secrets:

  • Redacted in API responses. GET/POST responses replace secret fields (password, secret, token, apikey, apitoken, and webhook customHeaders) with a __REDACTED__ placeholder. The plaintext is never returned to a client after it is saved. Updates that resubmit the placeholder (or an empty value) keep the stored secret intact, so editing a provider in the UI does not require re-entering credentials.
  • Encrypted at rest. The provider config blob is sealed with the ChainLaunch master encryption key before it touches SQLite, the same AES-256-GCM scheme used for SSO, Vault, and KMS credentials. See Encryption at Rest for how the master key is supplied and rotated. Existing rows are migrated lazily — they stay readable as plaintext until the next edit re-saves them encrypted.

This means a stolen chainlaunch.db does not leak your SMTP password or Slack/PagerDuty webhook secrets, and API consumers (including audit log subscribers) never see them.

Data Security

1. Encryption at Rest

Enable database encryption:

database:
  encryption:
    enabled: true
    algorithm: AES-256-GCM
    key_derivation: PBKDF2
    iterations: 100000

Encrypt sensitive fields:

  • API keys
  • Provider credentials
  • Certificate private keys
  • User passwords

2. Encryption in Transit

Use TLS 1.2+:

tls:
  min_version: "1.2"
  max_version: "1.3"
  require_client_cert: true
  client_ca: /etc/chainlaunch/ca-cert.pem

3. Database Security

Secure database connection:

# Use SSL for database connections
DATABASE_URL="postgresql://user:pass@db.example.com:5432/chainlaunch?sslmode=require"

Limit database access:

  • Run database on private network
  • Use database user with minimal privileges
  • Enable database audit logging
  • Regular backups to secure location

4. Key Management

Hardware Security Module (HSM):

  • Store master keys in HSM
  • Use AWS KMS or HashiCorp Vault for key provider
  • Never store keys in plaintext

Key Rotation:

# Generate a replacement key, then update the consuming node and remove the
# old key. ChainLaunch does not expose an in-place "rotate" endpoint today.
chainlaunch keys create --name signing-key-2026 --algorithm EC --curve P-256
# (reconfigure the node to use the new key, then…)
chainlaunch keys delete <old-key-id>

Monitoring & Audit

1. Enable Comprehensive Audit Logging

Configuration:

audit:
  enabled: true
  retention_days: 365
  log_level: info
  archive_after_days: 30
  targets:
    - type: syslog
      server: syslog.example.com
    - type: s3
      bucket: audit-logs-bucket

2. Monitor for Anomalies

Set up alerts for:

  • Failed login attempts (>3 in 15 minutes)
  • Permission elevation (user assigned admin role)
  • Unusual API usage patterns
  • Certificate expiration warnings
  • Network topology changes

Example alert configuration:

alerts:
  failed_logins:
    threshold: 3
    window_minutes: 15
    action: lock_account
  permission_elevation:
    enabled: true
    notify: security-team@example.com
  certificate_expiry:
    days_before: 30
    notify: ops-team@example.com

3. Collect Security Logs

Send logs to SIEM:

# Example: Send to Splunk
curl -X POST https://splunk.example.com:8088/services/collector \
  -H "Authorization: Splunk YOUR_TOKEN" \
  -d @audit-logs.json

4. Regular Security Audits

Monthly:

  • Review audit logs for anomalies
  • Check user permissions are appropriate
  • Verify API key usage
  • Audit failed operations

Quarterly:

  • Security assessment
  • Penetration testing
  • Policy review
  • Compliance verification

Infrastructure Security

1. Host Hardening

Operating System:

  • Apply latest security patches
  • Disable unnecessary services
  • Use SELinux/AppArmor
  • Enable firewall

SSH Configuration:

# ~/.ssh/config
Host chainlaunch-prod
  HostName prod.chainlaunch.example.com
  User chainlaunch
  IdentityFile ~/.ssh/id_rsa_chainlaunch
  IdentitiesOnly yes
  StrictHostKeyChecking yes
  UserKnownHostsFile ~/.ssh/known_hosts

2. Container Security (if using Docker)

Build secure images:

# Use minimal base image
FROM alpine:3.18
 
# Run as non-root user
RUN addgroup -g 1000 chainlaunch && \
    adduser -D -u 1000 -G chainlaunch chainlaunch
 
USER chainlaunch
 
# No secrets in image

Scan images:

# Scan for vulnerabilities
docker scan chainlaunch:latest
trivy image chainlaunch:latest

3. Kubernetes Security (if deployed on K8s)

RBAC:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: chainlaunch-role
rules:
  - apiGroups: [""]
    resources: ["pods", "services"]
    verbs: ["get", "list"]

Network policies:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: chainlaunch-netpol
spec:
  podSelector:
    matchLabels:
      app: chainlaunch
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: ingress
      ports:
        - protocol: TCP
          port: 8080

Compliance & Governance

1. Document Security Policies

Create and maintain:

  • Information Security Policy
  • Access Control Policy
  • Data Classification Policy
  • Incident Response Plan
  • Disaster Recovery Plan

2. Regular Training

User Training:

  • Password security
  • Phishing awareness
  • Data handling procedures
  • Incident reporting

Administrator Training:

  • Secure configuration
  • Backup procedures
  • Incident response
  • Compliance requirements

3. Compliance Reporting

Generate compliance reports:

# SOC 2 audit report
curl -X POST http://localhost:8100/api/v1/reports/soc2 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "start_date": "2024-01-01",
    "end_date": "2024-12-31"
  }' \
  --output soc2-report.pdf

Incident Response

1. Incident Response Plan

Document:

  • Detection procedures
  • Escalation paths
  • Response procedures
  • Communication templates
  • Recovery procedures

2. Security Incident Workflow

1. Detection
   ↓
2. Analysis
   ↓
3. Containment
   ↓
4. Eradication
   ↓
5. Recovery
   ↓
6. Post-Incident Review

3. Breach Notification

In case of security incident:

  1. Isolate affected systems
  2. Collect forensic evidence
  3. Notify security team
  4. Investigate root cause
  5. Implement fixes
  6. Notify users if required
  7. Document lessons learned

Security Checklist

  • TLS 1.2+ enabled for all communications
  • All users have strong passwords (min 12 chars)
  • Admin users have MFA enabled
  • API keys have expiration dates
  • RBAC configured with principle of least privilege
  • Audit logging enabled with retention policy
  • Database encrypted at rest
  • Backups encrypted and stored securely
  • Firewall configured to limit network access
  • SSH key-based authentication only
  • Regular security patches applied
  • Monitoring and alerting configured
  • Incident response plan documented
  • Security policies documented
  • Regular security audits scheduled

See Also