🔧 Add Bitwarden .env sync script for environment variable management
Some checks failed
CI/CD Pipeline (Reliable & Simple) / production (push) Has been cancelled
CI/CD Pipeline (Simple & Reliable) / production (push) Has been cancelled
CI/CD Pipeline (Fast) / production (push) Has been cancelled

- Introduced `sync-env.sh` to automate the synchronization of environment variables from Bitwarden.
- Implemented authentication with Bitwarden CLI, including session management and error handling.
- Added functionality to fetch environment variables from Bitwarden items and create/update a `.env` file in the specified target directory.
- Included logging for debugging and operational transparency.

 This script enhances the management of environment variables by integrating with Bitwarden, ensuring secure and efficient updates.
This commit is contained in:
2025-09-15 23:42:52 +02:00
parent ed95163f55
commit b06151739f

233
sync-env.sh Executable file
View File

@@ -0,0 +1,233 @@
#!/bin/bash
# === Bitwarden .env Sync (Advanced) ===
# Configuration
TARGET_DIR=""
SESSION_FILE="$HOME/.bw-session"
DEBUG=false
# Parse arguments
for arg in "$@"; do
case $arg in
--debug)
DEBUG=true
;;
*)
# If not a flag, treat as target directory
if [[ -z "$TARGET_DIR" ]] && [[ "$arg" != --* ]]; then
TARGET_DIR="$arg"
fi
;;
esac
done
# Set default target directory if not specified
if [[ -z "$TARGET_DIR" ]]; then
TARGET_DIR="$(pwd)"
fi
# Logging functions
log_info() {
echo "[INFO] $1"
}
log_debug() {
if [[ "$DEBUG" == "true" ]]; then
echo "[DEBUG] $1"
fi
}
log_error() {
echo "[ERROR] $1" >&2
}
# Check dependencies
check_dependencies() {
log_debug "Checking dependencies..."
if ! command -v bw &> /dev/null; then
log_error "Bitwarden CLI (bw) is not installed"
exit 1
fi
log_debug "bw found at: $(which bw)"
if ! command -v jq &> /dev/null; then
log_error "jq is not installed"
exit 1
fi
log_debug "jq found at: $(which jq)"
}
# Authenticate with Bitwarden
authenticate_bitwarden() {
log_debug "Starting Bitwarden authentication..."
# Check if we have a valid session
if [[ -f "$SESSION_FILE" ]]; then
log_debug "Session file found, loading session..."
export BW_SESSION=$(cat "$SESSION_FILE")
# Test if session is valid
if bw status --session "$BW_SESSION" 2>/dev/null | jq -e '.status == "unlocked"' &>/dev/null; then
log_debug "Session is valid and vault is unlocked"
return 0
else
log_debug "Session is invalid or vault is locked"
rm -f "$SESSION_FILE"
fi
else
log_debug "Session file does not exist"
fi
# Check login status
STATUS=$(bw status | jq -r '.status')
log_debug "Bitwarden status: $STATUS"
case "$STATUS" in
"unauthenticated")
log_info "Not logged in to Bitwarden. Please login:"
bw login
if [[ $? -ne 0 ]]; then
log_error "Login failed"
exit 1
fi
# After login, we need to unlock
STATUS="locked"
;;
esac
# Handle locked vault
if [[ "$STATUS" == "locked" ]]; then
log_info "Vault is locked. Unlocking..."
# Unlock and capture the session key
SESSION_OUTPUT=$(bw unlock --raw)
if [[ $? -ne 0 ]]; then
log_error "Failed to unlock vault"
exit 1
fi
# Save session to file and export
echo "$SESSION_OUTPUT" > "$SESSION_FILE"
export BW_SESSION="$SESSION_OUTPUT"
log_debug "Vault unlocked and session saved"
elif [[ "$STATUS" == "unlocked" ]]; then
# Vault is already unlocked but we don't have the session
log_info "Vault is already unlocked but session not found. Please unlock again:"
SESSION_OUTPUT=$(bw unlock --raw)
if [[ $? -ne 0 ]]; then
log_error "Failed to get session"
exit 1
fi
echo "$SESSION_OUTPUT" > "$SESSION_FILE"
export BW_SESSION="$SESSION_OUTPUT"
log_debug "Session retrieved and saved"
fi
# Final verification
if ! bw status --session "$BW_SESSION" 2>/dev/null | jq -e '.status == "unlocked"' &>/dev/null; then
log_error "Failed to authenticate with Bitwarden"
exit 1
fi
log_info "Successfully authenticated with Bitwarden"
}
# Sync environment variables
sync_env_vars() {
log_info "Starting .env sync to: $TARGET_DIR"
# Ensure BW_SESSION is set
if [[ -z "$BW_SESSION" ]]; then
log_error "No Bitwarden session available"
exit 1
fi
# Sync with Bitwarden to get latest data
log_info "Syncing with Bitwarden to get latest data..."
if bw sync --session "$BW_SESSION" &>/dev/null; then
log_debug "Successfully synced with Bitwarden"
else
log_error "Failed to sync with Bitwarden"
exit 1
fi
# Create .env file path
ENV_FILE="$TARGET_DIR/.env"
# Backup existing .env if it exists
if [[ -f "$ENV_FILE" ]]; then
cp "$ENV_FILE" "${ENV_FILE}.backup"
log_debug "Backed up existing .env to .env.backup"
fi
# Search for items with .env in notes or custom fields
# Adjust the search query based on how you store your env vars
log_info "Fetching environment variables from Bitwarden..."
# Example: Get a specific item by name (adjust based on your setup)
# You might want to search by folder, collection, or specific naming convention
ITEM_NAME="portfolio-env" # Adjust this to your item name
ITEM=$(bw get item "$ITEM_NAME" --session "$BW_SESSION" 2>/dev/null)
if [[ -z "$ITEM" ]]; then
log_error "Could not find item '$ITEM_NAME' in Bitwarden"
log_info "Make sure you have an item named '$ITEM_NAME' with your environment variables"
exit 1
fi
# Extract notes (assuming env vars are in notes field)
NOTES=$(echo "$ITEM" | jq -r '.notes // empty')
if [[ -z "$NOTES" ]]; then
# Try custom fields if notes are empty
log_debug "Notes empty, checking custom fields..."
# Extract all custom fields and format as KEY=VALUE
echo "$ITEM" | jq -r '.fields[]? | select(.type == 0) | "\(.name)=\(.value)"' > "$ENV_FILE"
if [[ ! -s "$ENV_FILE" ]]; then
log_error "No environment variables found in item '$ITEM_NAME'"
exit 1
fi
else
# Write notes directly to .env file
echo "$NOTES" > "$ENV_FILE"
fi
# Validate .env file
if [[ -f "$ENV_FILE" ]] && [[ -s "$ENV_FILE" ]]; then
log_info "Successfully created .env file at: $ENV_FILE"
log_debug "Environment variables written:"
if [[ "$DEBUG" == "true" ]]; then
# Show keys only, not values for security
grep -E '^[A-Z_]+=' "$ENV_FILE" | cut -d'=' -f1 | while read -r key; do
echo " - $key"
done
fi
else
log_error "Failed to create .env file or file is empty"
exit 1
fi
}
# Main execution
main() {
log_info "=== Bitwarden .env Sync (Advanced) ==="
log_info "Target directory: $TARGET_DIR"
log_debug "Session file: $SESSION_FILE"
check_dependencies
authenticate_bitwarden
sync_env_vars
log_info "=== Sync completed successfully ==="
}
# Run main function
main