Vaultwarden: Set "vault timeout" policy globally

In this guide, I want to show you a small bash script that I have written to set the vault timeout setting globally for all your created organisations in Vaultwarden.

For context: Some settings in vaultwaren can be set and entforced to all connected clients (also called Enterprise Policies). These settings can be set in cntext of organisations.

Why so complicated?

Because some Enterprise Policies are not AGPLv3 Licensed by Bitwarden and so Vaultwarden can not implement these features.

Prerequisites

  1. You need a running Vaultwarden server. Setup instructions can be found here: https://github.com/dani-garcia/vaultwarden?tab=readme-ov-file#installation
  2. You need to have setup at least one organisation on your Vaultwarden server. More infos about an organisation can be found here: https://bitwarden.com/help/getting-started-organizations/

Script

  1. Open a ssh session to your linux machine were the Vaultwarden container is running.

  2. Temporary stop your Vaultwarden container (because my script is adding/altering/deleting some table entries in the internal sqlite database of your Vaultwarden server.

  3. Make a backup of the Vaultwarden database. If you are using docker to run Vaultwarden, the database sould be here (... replace with your application name): /var/lib/docker/volumes/.../vw-data/db.sqlite3

  4. Create a sh script:

    nano modify_vault_timeout.sh

    Paste the following content into the nano editor and save (Strg+O and Strg+X)

    #!/bin/bash
    
    # Check if sqlite3 is installed
    if ! command -v sqlite3 &> /dev/null; then
       echo "Error: sqlite3 is not installed."
       echo "Please install sqlite3 before running this script."
       echo "On Debian-based systems, you can install it with:"
       echo "  sudo apt-get install sqlite3"
       echo "On Red Hat-based systems, you can install it with:"
       echo "  sudo yum install sqlite"
       exit 1
    fi
    
    # Function to remove all vault timeout entries
    remove_atype_9_entries() {
       local remove_query="DELETE FROM org_policies WHERE atype='9';"
       sqlite3 "$DB_FILE" "$remove_query"
       echo "Removed all existing vault timeout entries in table."
    }
    
    # Get the SQLite database file path from the user with error handling
    while true; do
       clear
       read -p $'Enter the path to the SQLite database file \n(Hint: /var/lib/docker/volumes/.../vw-data/db.sqlite3): ' DB_FILE
       if [ -f "$DB_FILE" ]; then
           break
       else
           clear
           echo "Error: The file does not exist. Please enter a valid file path."
       fi
    done
    
    # Get the removal option from the user with error handling
    while true; do
       clear
       read -p "Do you want to remove all existing vault timeout entries? (yes/no): " REMOVE_OPTION
       case "$REMOVE_OPTION" in
           [Yy]*)
               REMOVE_OPTION="yes"
               break
               ;;
           [Nn]*)
               REMOVE_OPTION="no"
               break
               ;;
           *)
               clear
               echo "Error: Invalid input. Please enter 'yes' or 'no'."
               ;;
       esac
    done
    
    # Get the vault timeout from the user with error handling
    while true; do
       clear
       read -p "Enter the vault timeout [in minutes] you want to set for all organizations: " LOCK_TIMEOUT
       if [[ "$LOCK_TIMEOUT" =~ ^[0-9]+$ ]]; then
           break
       else
           clear
           echo "Error: Invalid input. Please enter a valid integer value."
       fi
    done
    
    # Perform removal if requested
    if [ "$REMOVE_OPTION" == "yes" ]; then
       remove_atype_9_entries
       exit 0
    fi
    
    # SQL query to retrieve UUIDs from the organizations table
    UUID_QUERY="SELECT uuid FROM organizations;"
    
    # Execute the UUID query and store the result in an array
    UUID_ARRAY=()
    while IFS= read -r uuid; do
       UUID_ARRAY+=("$uuid")
    done < <(sqlite3 "$DB_FILE" "$UUID_QUERY")
    
    # Loop through the UUID array and execute the SQL insert or update query for each UUID
    for uuid in "${UUID_ARRAY[@]}"; do
       # Check if org_uuid and atype combination already exists
       if [[ $(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM org_policies WHERE org_uuid='$uuid' AND atype='9';") -gt 0 ]]; then
           # Update existing row with new lock timeout
           UPDATE_QUERY="UPDATE org_policies SET data='{\"minutes\":$LOCK_TIMEOUT}' WHERE org_uuid='$uuid' AND atype='9';"
           sqlite3 "$DB_FILE" "$UPDATE_QUERY"
           echo "Vault timeout entry already exists for UUID: $uuid. Updated vault timeout to $LOCK_TIMEOUT minutes."
       else
           # Create a random UUID for newly inserted org_policy
           RAND_UUID=$(cat /proc/sys/kernel/random/uuid)
           # Insert new row with lock timeout
           INSERT_QUERY="INSERT INTO org_policies (uuid, org_uuid, atype, enabled, data) VALUES ('$RAND_UUID', '$uuid', '9', '1', '{\"minutes\":$LOCK_TIMEOUT}');"
           sqlite3 "$DB_FILE" "$INSERT_QUERY"
           echo "Inserted new vault timeout entry for UUID: $uuid with a timeout of $LOCK_TIMEOUT minutes."
       fi
    done
  5. Make the script executable:

    chmod +x modify_vault_timeout.sh
  6. Run the script:

    ./modify_vault_timeout.sh
  7. Start the Vaultwarden container.

Previous Post Next Post

Add a comment