82 lines
3.1 KiB
Bash
Executable file
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)."
|