Files
bootnode/infra/k8s/secrets.yaml
zeekay 3fe4d9fa43 fix: enforce Hanzo KMS for all secrets, remove plaintext credentials
- Remove hardcoded Secret from bootnode-deployment.yaml (conflicted with ExternalSecret)
- Fix Postgres/Redis pods to read passwords from KMS-managed bootnode-secrets
- Expand ExternalSecret from 7 to 30 secrets with UPPERCASE_UNDERSCORE keys matching Pydantic
- Enable hanzo-kms SDK as optional dependency for direct KMS access outside K8s
- Improve inject_secrets() startup logging to indicate active secrets path
- Rewrite secrets.yaml as documentation-only with flow diagram and setup guide
- Fix compose.yml Bitcoin healthcheck to use env vars instead of hardcoded password
2026-02-12 13:05:04 -08:00

98 lines
4.7 KiB
YAML

# Bootnode Secrets — Managed by Hanzo KMS
#
# IMPORTANT: Do NOT define secrets in this file.
# All production secrets are managed via Hanzo KMS and synced to K8s
# by the External Secrets Operator.
#
# See: external-secrets.yaml (ExternalSecret → bootnode-secrets)
#
# ═══════════════════════════════════════════════════════════════════
# SECRET MANAGEMENT FLOW
# ═══════════════════════════════════════════════════════════════════
#
# Hanzo KMS (https://kms.hanzo.ai)
# │
# ▼ (External Secrets Operator, refreshes every 1h)
# K8s Secret: bootnode-secrets
# │
# ▼ (envFrom in deployment)
# API pods read secrets as env vars
# │
# ▼ (Pydantic Settings)
# config.py binds to typed settings
#
# ═══════════════════════════════════════════════════════════════════
# SETUP OPTIONS
# ═══════════════════════════════════════════════════════════════════
#
# 1. Hanzo KMS + External Secrets (Production — RECOMMENDED):
# - Store all secrets in https://kms.hanzo.ai project "bootnode"
# - Apply external-secrets.yaml to sync KMS → K8s
# - See external-secrets.yaml for full setup instructions
#
# 2. kubectl create secret (Development/Testing):
# kubectl create secret generic bootnode-secrets \
# --namespace bootnode \
# --from-literal=DATABASE_URL='postgresql+asyncpg://user:pass@host:5432/db' \
# --from-literal=REDIS_URL='redis://:password@host:6379/0' \
# --from-literal=REDIS_PASSWORD='your-redis-password' \
# --from-literal=POSTGRES_PASSWORD='your-postgres-password' \
# --from-literal=DATASTORE_URL='clickhouse://user:pass@host:8123/db' \
# --from-literal=JWT_SECRET="$(openssl rand -hex 32)" \
# --from-literal=API_KEY_SALT="$(openssl rand -hex 16)" \
# --from-literal=IAM_CLIENT_ID='your-client-id' \
# --from-literal=IAM_CLIENT_SECRET='your-client-secret' \
# --from-literal=COMMERCE_URL='https://commerce.hanzo.ai' \
# --from-literal=COMMERCE_API_KEY='your-commerce-key' \
# --from-literal=COMMERCE_WEBHOOK_SECRET='your-webhook-secret'
#
# 3. Sealed Secrets (GitOps):
# kubeseal --format yaml < secret.yaml > sealed-secret.yaml
#
# ═══════════════════════════════════════════════════════════════════
# REQUIRED SECRETS (must exist in KMS or kubectl)
# ═══════════════════════════════════════════════════════════════════
#
# Database:
# DATABASE_URL - PostgreSQL async connection string
# POSTGRES_PASSWORD - PostgreSQL password (for postgres pod)
# REDIS_URL - Redis connection string (with auth)
# REDIS_PASSWORD - Redis password (for redis pod)
# DATASTORE_URL - ClickHouse connection string
#
# Authentication:
# JWT_SECRET - JWT signing key (min 256 bits)
# API_KEY_SALT - API key hashing salt (min 128 bits)
# IAM_CLIENT_ID - Hanzo IAM OAuth client ID
# IAM_CLIENT_SECRET - Hanzo IAM OAuth client secret
#
# Billing (Hanzo Commerce):
# COMMERCE_URL - Hanzo Commerce API URL
# COMMERCE_API_KEY - Commerce API key
# COMMERCE_WEBHOOK_SECRET - Webhook HMAC signing key
#
# Chain RPCs (contain provider API keys):
# ETH_MAINNET_RPC, POLYGON_MAINNET_RPC, ARBITRUM_MAINNET_RPC,
# OPTIMISM_MAINNET_RPC, BASE_MAINNET_RPC, AVALANCHE_MAINNET_RPC,
# BSC_MAINNET_RPC, LUX_MAINNET_RPC, SOLANA_MAINNET_RPC,
# BTC_MAINNET_RPC, BTC_RPC_USER, BTC_RPC_PASSWORD
#
# Optional:
# BUNDLER_PRIVATE_KEY - ERC-4337 bundler signing key
# CLOUDFLARE_API_TOKEN - Cloudflare edge cache token
# CLOUDFLARE_ZONE_ID - Cloudflare zone identifier
# QDRANT_API_KEY - Qdrant vector DB API key
# MEILISEARCH_API_KEY - Meilisearch full-text search key
---
# Non-sensitive chain configuration (safe to commit)
apiVersion: v1
kind: ConfigMap
metadata:
name: bootnode-chains-config
namespace: bootnode
data:
chains.yaml: |
# Chain configuration loaded by the indexer
# See infra/config/chains.yaml for full config