Initial commit: breakpilot-core - Shared Infrastructure
Docker Compose with 24+ services: - PostgreSQL (PostGIS), Valkey, MinIO, Qdrant - Vault (PKI/TLS), Nginx (Reverse Proxy) - Backend Core API, Consent Service, Billing Service - RAG Service, Embedding Service - Gitea, Woodpecker CI/CD - Night Scheduler, Health Aggregator - Jitsi (Web/XMPP/JVB/Jicofo), Mailpit Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
44
vault/agent/config.hcl
Normal file
44
vault/agent/config.hcl
Normal file
@@ -0,0 +1,44 @@
|
||||
# Vault Agent Configuration for BreakPilot SSL Certificates
|
||||
# Automatically renews certificates and updates nginx
|
||||
|
||||
pid_file = "/tmp/vault-agent.pid"
|
||||
|
||||
vault {
|
||||
address = "http://vault:8200"
|
||||
retry {
|
||||
num_retries = 5
|
||||
}
|
||||
}
|
||||
|
||||
auto_auth {
|
||||
method "approle" {
|
||||
mount_path = "auth/approle"
|
||||
config = {
|
||||
role_id_file_path = "/vault/agent/data/role-id"
|
||||
secret_id_file_path = "/vault/agent/data/secret-id"
|
||||
remove_secret_id_file_after_reading = false
|
||||
}
|
||||
}
|
||||
|
||||
sink "file" {
|
||||
config = {
|
||||
path = "/vault/agent/data/token"
|
||||
mode = 0600
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Single template that generates all certificate components
|
||||
# Uses a single pkiCert call to ensure cert/key match
|
||||
template {
|
||||
source = "/vault/agent/templates/all.tpl"
|
||||
destination = "/vault/certs/combined.pem"
|
||||
perms = 0600
|
||||
command = "sh /vault/agent/split-certs.sh"
|
||||
}
|
||||
|
||||
# Listener for debugging (optional)
|
||||
listener "tcp" {
|
||||
address = "127.0.0.1:8100"
|
||||
tls_disable = true
|
||||
}
|
||||
28
vault/agent/split-certs.sh
Executable file
28
vault/agent/split-certs.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
# Split combined certificate file into separate components
|
||||
|
||||
COMBINED="/vault/certs/combined.pem"
|
||||
CERT_FILE="/vault/certs/macmini.crt"
|
||||
KEY_FILE="/vault/certs/macmini.key"
|
||||
CA_FILE="/vault/certs/ca-chain.crt"
|
||||
|
||||
# Extract certificate (between ===CERT=== and ===CA===)
|
||||
sed -n '/===CERT===/,/===CA===/p' "$COMBINED" | sed '1d;$d' > "$CERT_FILE"
|
||||
|
||||
# Append CA to certificate file for full chain
|
||||
sed -n '/===CA===/,/===KEY===/p' "$COMBINED" | sed '1d;$d' >> "$CERT_FILE"
|
||||
|
||||
# Extract CA chain
|
||||
sed -n '/===CA===/,/===KEY===/p' "$COMBINED" | sed '1d;$d' > "$CA_FILE"
|
||||
|
||||
# Extract private key
|
||||
sed -n '/===KEY===/,$p' "$COMBINED" | sed '1d' > "$KEY_FILE"
|
||||
|
||||
# Set permissions
|
||||
chmod 644 "$CERT_FILE" "$CA_FILE"
|
||||
chmod 600 "$KEY_FILE"
|
||||
|
||||
# Reload nginx if running
|
||||
nginx -s reload 2>/dev/null || true
|
||||
|
||||
echo "Certificates split successfully"
|
||||
9
vault/agent/templates/all.tpl
Normal file
9
vault/agent/templates/all.tpl
Normal file
@@ -0,0 +1,9 @@
|
||||
{{- /* Combined Certificate Template - generates all certificate components from a single PKI call */ -}}
|
||||
{{- with pkiCert "pki_int/issue/breakpilot-internal" "common_name=macmini" "alt_names=localhost,macmini.local" "ip_sans=127.0.0.1,192.168.178.163" "ttl=168h" -}}
|
||||
===CERT===
|
||||
{{ .Cert }}
|
||||
===CA===
|
||||
{{ .CA }}
|
||||
===KEY===
|
||||
{{ .Key }}
|
||||
{{- end -}}
|
||||
4
vault/agent/templates/ca-chain.tpl
Normal file
4
vault/agent/templates/ca-chain.tpl
Normal file
@@ -0,0 +1,4 @@
|
||||
{{- /* CA Chain Template */ -}}
|
||||
{{- with pkiCert "pki_int/issue/breakpilot-internal" "common_name=macmini" "alt_names=localhost,macmini.local" "ip_sans=127.0.0.1,192.168.178.163" "ttl=168h" -}}
|
||||
{{ .CA }}
|
||||
{{- end -}}
|
||||
5
vault/agent/templates/cert.tpl
Normal file
5
vault/agent/templates/cert.tpl
Normal file
@@ -0,0 +1,5 @@
|
||||
{{- /* Certificate Template for macmini */ -}}
|
||||
{{- with pkiCert "pki_int/issue/breakpilot-internal" "common_name=macmini" "alt_names=localhost,macmini.local" "ip_sans=127.0.0.1,192.168.178.163" "ttl=168h" -}}
|
||||
{{ .Cert }}
|
||||
{{ .CA }}
|
||||
{{- end -}}
|
||||
4
vault/agent/templates/key.tpl
Normal file
4
vault/agent/templates/key.tpl
Normal file
@@ -0,0 +1,4 @@
|
||||
{{- /* Private Key Template for macmini */ -}}
|
||||
{{- with pkiCert "pki_int/issue/breakpilot-internal" "common_name=macmini" "alt_names=localhost,macmini.local" "ip_sans=127.0.0.1,192.168.178.163" "ttl=168h" -}}
|
||||
{{ .Key }}
|
||||
{{- end -}}
|
||||
188
vault/init-pki.sh
Executable file
188
vault/init-pki.sh
Executable file
@@ -0,0 +1,188 @@
|
||||
#!/bin/sh
|
||||
# Vault PKI Initialization Script for BreakPilot SSL Certificates
|
||||
#
|
||||
# This script sets up a PKI secrets engine with:
|
||||
# - Root CA
|
||||
# - Intermediate CA
|
||||
# - Certificate issuance role for macmini hostname
|
||||
# - AppRole for vault-agent authentication
|
||||
#
|
||||
# Usage: Run this after Vault is initialized
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Vault PKI Initialization ==="
|
||||
echo "Waiting for Vault to be ready..."
|
||||
|
||||
# Wait for Vault to be ready
|
||||
until vault status > /dev/null 2>&1; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Vault is ready. Setting up PKI..."
|
||||
|
||||
# Create directories
|
||||
mkdir -p /vault/agent/data
|
||||
mkdir -p /vault/certs
|
||||
|
||||
# ================================================
|
||||
# Step 1: Enable PKI Secrets Engine (Root CA)
|
||||
# ================================================
|
||||
echo "Enabling Root CA PKI engine..."
|
||||
vault secrets enable -path=pki pki 2>/dev/null || echo "PKI engine already enabled"
|
||||
|
||||
# Set max lease TTL to 10 years for root CA
|
||||
vault secrets tune -max-lease-ttl=87600h pki
|
||||
|
||||
# Check if Root CA already exists
|
||||
if ! vault read pki/cert/ca > /dev/null 2>&1; then
|
||||
echo "Generating Root CA certificate..."
|
||||
vault write -field=certificate pki/root/generate/internal \
|
||||
common_name="BreakPilot Root CA" \
|
||||
issuer_name="root-2024" \
|
||||
ttl=87600h > /vault/certs/root_ca.crt
|
||||
else
|
||||
echo "Root CA already exists, skipping generation"
|
||||
fi
|
||||
|
||||
# Configure URLs
|
||||
vault write pki/config/urls \
|
||||
issuing_certificates="http://vault:8200/v1/pki/ca" \
|
||||
crl_distribution_points="http://vault:8200/v1/pki/crl"
|
||||
|
||||
# ================================================
|
||||
# Step 2: Enable PKI Secrets Engine (Intermediate CA)
|
||||
# ================================================
|
||||
echo "Enabling Intermediate CA PKI engine..."
|
||||
vault secrets enable -path=pki_int pki 2>/dev/null || echo "Intermediate PKI engine already enabled"
|
||||
|
||||
# Set max lease TTL to 5 years for intermediate
|
||||
vault secrets tune -max-lease-ttl=43800h pki_int
|
||||
|
||||
# Check if Intermediate CA already exists
|
||||
if ! vault read pki_int/cert/ca > /dev/null 2>&1; then
|
||||
echo "Generating Intermediate CA..."
|
||||
|
||||
# Generate Intermediate CSR (using -field to get raw CSR)
|
||||
vault write -field=csr pki_int/intermediate/generate/internal \
|
||||
common_name="BreakPilot Intermediate CA" \
|
||||
issuer_name="breakpilot-intermediate" \
|
||||
> /tmp/pki_intermediate.csr
|
||||
|
||||
echo "CSR generated, signing with Root CA..."
|
||||
|
||||
# Sign the Intermediate with Root CA (using -field to get raw certificate)
|
||||
vault write -field=certificate pki/root/sign-intermediate \
|
||||
issuer_ref="root-2024" \
|
||||
csr=@/tmp/pki_intermediate.csr \
|
||||
format=pem_bundle \
|
||||
ttl="43800h" \
|
||||
> /tmp/intermediate.cert.pem
|
||||
|
||||
echo "Importing signed intermediate certificate..."
|
||||
|
||||
# Import signed intermediate certificate
|
||||
vault write pki_int/intermediate/set-signed \
|
||||
certificate=@/tmp/intermediate.cert.pem
|
||||
else
|
||||
echo "Intermediate CA already exists, skipping generation"
|
||||
fi
|
||||
|
||||
# ================================================
|
||||
# Step 3: Create Role for Certificate Issuance
|
||||
# ================================================
|
||||
echo "Creating certificate issuance role..."
|
||||
|
||||
# Role for macmini certificates (internal use)
|
||||
vault write pki_int/roles/breakpilot-internal \
|
||||
allowed_domains="macmini,macmini.local,localhost,breakpilot.local" \
|
||||
allow_bare_domains=true \
|
||||
allow_subdomains=true \
|
||||
allow_localhost=true \
|
||||
allow_ip_sans=true \
|
||||
max_ttl="720h" \
|
||||
ttl="168h"
|
||||
|
||||
# ================================================
|
||||
# Step 4: Create Policy for Certificate Access
|
||||
# ================================================
|
||||
echo "Creating certificate policy..."
|
||||
|
||||
vault policy write breakpilot-pki - <<EOF
|
||||
# BreakPilot PKI Policy
|
||||
# Allows issuing and reading certificates
|
||||
|
||||
# Issue certificates
|
||||
path "pki_int/issue/breakpilot-internal" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
|
||||
# Read CA certificates
|
||||
path "pki/cert/ca" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "pki_int/cert/ca" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
# Renew own token
|
||||
path "auth/token/renew-self" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
EOF
|
||||
|
||||
# ================================================
|
||||
# Step 5: Create AppRole for nginx/vault-agent
|
||||
# ================================================
|
||||
echo "Creating AppRole for certificate management..."
|
||||
|
||||
vault auth enable approle 2>/dev/null || echo "AppRole already enabled"
|
||||
|
||||
# Create role for nginx certificate management
|
||||
vault write auth/approle/role/breakpilot-nginx \
|
||||
token_policies="breakpilot-pki" \
|
||||
token_ttl=24h \
|
||||
token_max_ttl=168h \
|
||||
secret_id_ttl=0
|
||||
|
||||
# Get role-id
|
||||
ROLE_ID=$(vault read -field=role_id auth/approle/role/breakpilot-nginx/role-id)
|
||||
|
||||
# Generate secret-id
|
||||
SECRET_ID=$(vault write -field=secret_id -f auth/approle/role/breakpilot-nginx/secret-id)
|
||||
|
||||
echo ""
|
||||
echo "=== AppRole Credentials ==="
|
||||
echo "Role ID: $ROLE_ID"
|
||||
echo "Secret ID: $SECRET_ID"
|
||||
echo ""
|
||||
|
||||
# Save credentials to file for vault-agent
|
||||
echo "$ROLE_ID" > /vault/agent/data/role-id
|
||||
echo "$SECRET_ID" > /vault/agent/data/secret-id
|
||||
chmod 600 /vault/agent/data/role-id /vault/agent/data/secret-id
|
||||
|
||||
# ================================================
|
||||
# Step 6: Verify PKI setup is working
|
||||
# ================================================
|
||||
echo "Verifying PKI setup..."
|
||||
|
||||
# Test that certificate issuance works (don't save, just verify)
|
||||
if vault write -format=json pki_int/issue/breakpilot-internal \
|
||||
common_name="test.macmini" \
|
||||
ttl="1h" > /dev/null 2>&1; then
|
||||
echo "✓ Certificate issuance working"
|
||||
else
|
||||
echo "✗ Certificate issuance failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== PKI Initialization Complete ==="
|
||||
echo ""
|
||||
echo "AppRole credentials saved to /vault/agent/data/"
|
||||
ls -la /vault/agent/data/
|
||||
echo ""
|
||||
echo "Vault-agent will generate and manage certificates automatically."
|
||||
echo "Start vault-agent to begin certificate management."
|
||||
176
vault/init-secrets.sh
Executable file
176
vault/init-secrets.sh
Executable file
@@ -0,0 +1,176 @@
|
||||
#!/bin/sh
|
||||
# Vault Initialization Script for BreakPilot
|
||||
#
|
||||
# This script initializes the KV v2 secrets engine and creates
|
||||
# placeholder secrets for development.
|
||||
#
|
||||
# IMPORTANT: In production, replace these with real secrets via
|
||||
# the Vault UI or CLI before deployment!
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== Vault Secret Initialization ==="
|
||||
echo "Waiting for Vault to be ready..."
|
||||
|
||||
# Wait for Vault to be ready
|
||||
until vault status > /dev/null 2>&1; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Vault is ready. Initializing secrets..."
|
||||
|
||||
# Enable KV v2 secrets engine at 'secret/' (usually enabled in dev mode)
|
||||
vault secrets enable -version=2 -path=secret kv 2>/dev/null || echo "KV engine already enabled"
|
||||
|
||||
# ================================================
|
||||
# API Keys (PLACEHOLDER - Replace in production!)
|
||||
# ================================================
|
||||
echo "Creating API key secrets..."
|
||||
|
||||
vault kv put secret/breakpilot/api_keys/anthropic \
|
||||
value="REPLACE_WITH_REAL_ANTHROPIC_API_KEY"
|
||||
|
||||
vault kv put secret/breakpilot/api_keys/vast \
|
||||
value="REPLACE_WITH_REAL_VAST_API_KEY"
|
||||
|
||||
vault kv put secret/breakpilot/api_keys/tavily \
|
||||
value="REPLACE_WITH_REAL_TAVILY_API_KEY"
|
||||
|
||||
vault kv put secret/breakpilot/api_keys/stripe \
|
||||
value="REPLACE_WITH_REAL_STRIPE_SECRET_KEY"
|
||||
|
||||
vault kv put secret/breakpilot/api_keys/stripe_webhook \
|
||||
value="REPLACE_WITH_REAL_STRIPE_WEBHOOK_SECRET"
|
||||
|
||||
# ================================================
|
||||
# Database Credentials
|
||||
# ================================================
|
||||
echo "Creating database secrets..."
|
||||
|
||||
vault kv put secret/breakpilot/database/postgres \
|
||||
username="breakpilot" \
|
||||
password="breakpilot123" \
|
||||
url="postgres://breakpilot:breakpilot123@postgres:5432/breakpilot_db?sslmode=disable"
|
||||
|
||||
# ================================================
|
||||
# Authentication
|
||||
# ================================================
|
||||
echo "Creating auth secrets..."
|
||||
|
||||
# Generate random secrets for development
|
||||
JWT_SECRET=$(openssl rand -hex 32 2>/dev/null || echo "dev-jwt-secret-replace-in-prod-32ch")
|
||||
JWT_REFRESH_SECRET=$(openssl rand -hex 32 2>/dev/null || echo "dev-refresh-secret-replace-prod32")
|
||||
|
||||
vault kv put secret/breakpilot/auth/jwt \
|
||||
secret="$JWT_SECRET" \
|
||||
refresh_secret="$JWT_REFRESH_SECRET"
|
||||
|
||||
vault kv put secret/breakpilot/auth/keycloak \
|
||||
client_secret="REPLACE_WITH_KEYCLOAK_CLIENT_SECRET"
|
||||
|
||||
# ================================================
|
||||
# Communication Services
|
||||
# ================================================
|
||||
echo "Creating communication secrets..."
|
||||
|
||||
vault kv put secret/breakpilot/communication/matrix \
|
||||
access_token="REPLACE_WITH_MATRIX_ACCESS_TOKEN" \
|
||||
db_password="synapse_secret_123"
|
||||
|
||||
vault kv put secret/breakpilot/communication/jitsi \
|
||||
app_secret="REPLACE_WITH_JITSI_APP_SECRET" \
|
||||
jicofo_password="jicofo_secret_123" \
|
||||
jvb_password="jvb_secret_123"
|
||||
|
||||
# ================================================
|
||||
# Storage
|
||||
# ================================================
|
||||
echo "Creating storage secrets..."
|
||||
|
||||
vault kv put secret/breakpilot/storage/minio \
|
||||
access_key="minioadmin" \
|
||||
secret_key="minioadmin123"
|
||||
|
||||
# ================================================
|
||||
# Infrastructure
|
||||
# ================================================
|
||||
echo "Creating infrastructure secrets..."
|
||||
|
||||
vault kv put secret/breakpilot/infra/vast \
|
||||
api_key="REPLACE_WITH_VAST_API_KEY" \
|
||||
instance_id="REPLACE_WITH_VAST_INSTANCE_ID" \
|
||||
control_api_key="REPLACE_WITH_CONTROL_API_KEY"
|
||||
|
||||
# ================================================
|
||||
# Create policy for BreakPilot services
|
||||
# ================================================
|
||||
echo "Creating Vault policy..."
|
||||
|
||||
vault policy write breakpilot-backend - <<EOF
|
||||
# BreakPilot Backend Policy
|
||||
# Allows read access to all breakpilot secrets
|
||||
|
||||
path "secret/data/breakpilot/*" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
|
||||
path "secret/metadata/breakpilot/*" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
EOF
|
||||
|
||||
vault policy write breakpilot-admin - <<EOF
|
||||
# BreakPilot Admin Policy
|
||||
# Full access to breakpilot secrets
|
||||
|
||||
path "secret/data/breakpilot/*" {
|
||||
capabilities = ["create", "read", "update", "delete", "list"]
|
||||
}
|
||||
|
||||
path "secret/metadata/breakpilot/*" {
|
||||
capabilities = ["read", "list", "delete"]
|
||||
}
|
||||
|
||||
path "secret/delete/breakpilot/*" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
|
||||
path "secret/undelete/breakpilot/*" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
EOF
|
||||
|
||||
# ================================================
|
||||
# Create AppRole for services
|
||||
# ================================================
|
||||
echo "Enabling AppRole auth method..."
|
||||
|
||||
vault auth enable approle 2>/dev/null || echo "AppRole already enabled"
|
||||
|
||||
# Create role for backend service
|
||||
vault write auth/approle/role/breakpilot-backend \
|
||||
token_policies="breakpilot-backend" \
|
||||
token_ttl=1h \
|
||||
token_max_ttl=4h \
|
||||
secret_id_ttl=0
|
||||
|
||||
# Get role-id for backend
|
||||
ROLE_ID=$(vault read -field=role_id auth/approle/role/breakpilot-backend/role-id)
|
||||
echo ""
|
||||
echo "=== AppRole Credentials ==="
|
||||
echo "Role ID: $ROLE_ID"
|
||||
echo ""
|
||||
echo "Generate a secret-id with:"
|
||||
echo " vault write -f auth/approle/role/breakpilot-backend/secret-id"
|
||||
echo ""
|
||||
|
||||
echo "=== Vault Initialization Complete ==="
|
||||
echo ""
|
||||
echo "IMPORTANT: Replace placeholder secrets before production deployment!"
|
||||
echo ""
|
||||
echo "To view secrets:"
|
||||
echo " vault kv list secret/breakpilot/"
|
||||
echo " vault kv get secret/breakpilot/api_keys/anthropic"
|
||||
echo ""
|
||||
echo "To update a secret:"
|
||||
echo " vault kv put secret/breakpilot/api_keys/anthropic value='sk-ant-xxx...'"
|
||||
Reference in New Issue
Block a user