disclosure-bureau/infra/disclosure-stack/scripts/gen-secrets.sh

82 lines
3.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# Regenerate all per-VPS secrets in .env. Run ONCE per new VPS deployment.
# Backs up the existing .env first.
#
# Generates:
# POSTGRES_PASSWORD, JWT_SECRET, DASHBOARD_PASSWORD,
# SECRET_KEY_BASE, VAULT_ENC_KEY, MEILI_MASTER_KEY,
# IMGPROXY_KEY, IMGPROXY_SALT,
# ANON_KEY and SERVICE_ROLE_KEY (JWTs signed with JWT_SECRET)
#
# Usage: ./gen-secrets.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STACK_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="${STACK_DIR}/.env"
if [ ! -f "$ENV_FILE" ]; then
echo "$ENV_FILE not found. Copy .env.example to .env first."
exit 1
fi
cp "$ENV_FILE" "${ENV_FILE}.backup.$(date +%s)"
echo "✓ backed up to ${ENV_FILE}.backup.<ts>"
POSTGRES_PASSWORD=$(openssl rand -hex 32 | head -c 48)
JWT_SECRET=$(openssl rand -hex 64)
DASHBOARD_PASSWORD=$(openssl rand -base64 24 | tr -d '/=+')
SECRET_KEY_BASE=$(openssl rand -hex 64)
VAULT_ENC_KEY=$(openssl rand -hex 32 | head -c 32)
MEILI_MASTER_KEY=$(openssl rand -hex 32)
IMGPROXY_KEY=$(openssl rand -hex 64)
IMGPROXY_SALT=$(openssl rand -hex 64)
# Generate Supabase ANON_KEY and SERVICE_ROLE_KEY (HS256 JWTs)
# Standard payload Supabase expects:
# iss: supabase ref: <project-ref> role: anon|service_role
# iat: now exp: now + 10 years
generate_jwt() {
local role="$1"
local now=$(date +%s)
local exp=$((now + 315360000)) # +10 years
local header_b64=$(printf '%s' '{"alg":"HS256","typ":"JWT"}' | openssl base64 -A | tr -d '=' | tr '/+' '_-')
local payload_b64=$(printf '{"iss":"supabase","ref":"disclosure","role":"%s","iat":%s,"exp":%s}' "$role" "$now" "$exp" | openssl base64 -A | tr -d '=' | tr '/+' '_-')
local signing_input="${header_b64}.${payload_b64}"
local sig=$(printf '%s' "$signing_input" | openssl dgst -sha256 -hmac "$JWT_SECRET" -binary | openssl base64 -A | tr -d '=' | tr '/+' '_-')
echo "${signing_input}.${sig}"
}
ANON_KEY=$(generate_jwt "anon")
SERVICE_ROLE_KEY=$(generate_jwt "service_role")
# Replace values in .env (only the lines that match these keys)
replace() {
local key="$1" value="$2"
# macOS sed needs '' after -i; this is portable enough for both BSD and GNU
if sed --version >/dev/null 2>&1; then
sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE"
else
sed -i '' "s|^${key}=.*|${key}=${value}|" "$ENV_FILE"
fi
}
replace POSTGRES_PASSWORD "$POSTGRES_PASSWORD"
replace JWT_SECRET "$JWT_SECRET"
replace DASHBOARD_PASSWORD "$DASHBOARD_PASSWORD"
replace SECRET_KEY_BASE "$SECRET_KEY_BASE"
replace VAULT_ENC_KEY "$VAULT_ENC_KEY"
replace MEILI_MASTER_KEY "$MEILI_MASTER_KEY"
replace IMGPROXY_KEY "$IMGPROXY_KEY"
replace IMGPROXY_SALT "$IMGPROXY_SALT"
replace ANON_KEY "$ANON_KEY"
replace SERVICE_ROLE_KEY "$SERVICE_ROLE_KEY"
echo "✓ secrets rotated in $ENV_FILE"
echo ""
echo "ANON_KEY (length=${#ANON_KEY}): ${ANON_KEY:0:40}"
echo "SERVICE_ROLE_KEY (length=${#SERVICE_ROLE_KEY}): ${SERVICE_ROLE_KEY:0:40}"
echo ""
echo "Both are JWTs signed with JWT_SECRET. Supabase uses them to authorize requests."
echo "Distribute ANON_KEY to clients (NEXT_PUBLIC_SUPABASE_ANON_KEY)."
echo "Keep SERVICE_ROLE_KEY private (server-only — bypasses RLS)."