# Automatic Bitwarden Backup


![](https://camo.githubusercontent.com/96311d24b348f8f33f3854fb0f3522ca178d7b3c06294845470f6fbe8b7c0de9/68747470733a2f2f692e696d6775722e636f6d2f6b3456576d6e372e706e67 align="center")

## Secure, Automated, and Multi-Cloud Bitwarden Backup and Import System

Lazywarden is a Python automation tool designed to Backup and Restore data from your vault, including Bitwarden attachments. It allows you to upload backups to multiple cloud storage services and receive notifications across multiple platforms. It also offers AES encrypted backups and uses key derivation with Argon2, ensuring maximum security for your data.

## Features

* 🔒 **Maximum Security:** Data protection with AES-256 encryption and Argon2 key derivation.
    
* 🔄 **Automated Backups and Imports:** Keep your Bitwarden vault up to date and secure.
    
* ✅ **Integrity Verification:** SHA-256 hash to ensure data integrity on every backup.
    
* ☁️ **Multi-Cloud Support:** Store backups to services such as Dropbox, Google Drive, pCloud, MEGA, NextCloud, Seafile, Filebase (IPFS) and via SMTP.
    
* 🖥️ **Local Storage:** Save backups to a local path for greater control.
    
* 🔔 **Real-Time Alerts:** Instant notifications on Discord, Telegram and Slack.
    
* 🗓️ **Schedule Management:** Integration with Todoist and CalDAV to manage your schedule.
    
* 🐳 **Easy Deployment:** Quick setup with Docker Compose.
    
* 🤖 **Full Automation and Custom Scheduling:** Automatic backups with flexible scheduling options (daily, weekly, monthly, yearly). Integration with CalDAV and Todoist for complete tracking and email notifications.
    
* 🔑 **Bitwarden Export to KeePass:** Export Bitwarden items to a KeePass database (kdbx), including TOTP-seeded logins, URI, custom fields, card, identity attachments and secure notes.
    

## Demo Backup

![](https://raw.githubusercontent.com/querylab/svg/main/lazy-oficial.gif align="left")

![](https://raw.githubusercontent.com/querylab/svg/main/lazy-video.gif align="left")

## Demo Import

![](https://raw.githubusercontent.com/querylab/svg/main/bitwarden-demo1.gif align="left")

![](https://raw.githubusercontent.com/querylab/svg/main/bitwarden-demo2.gif align="left")

## Demo Schedule

![](https://raw.githubusercontent.com/querylab/svg/main/schedule_beta.gif align="left")

## Demo Import Keepass

![](https://raw.githubusercontent.com/querylab/svg/main/demo_keepass.gif align="left")

![](https://raw.githubusercontent.com/querylab/svg/main/keepass_import.gif align="left")

## Demo Decrypting All Zip and JSON

![](https://raw.githubusercontent.com/querylab/svg/main/demo_decrypt.gif align="left")

### SMTP Backup

[![](https://camo.githubusercontent.com/345d5ca98b1a14003cabbc2eafa838cbe655877d6286ce7704649a6d7755cd50/68747470733a2f2f692e696d6775722e636f6d2f6d736c514b46312e706e67 align="left")](https://imgur.com/mslQKF1)

### SMTP Scheduled

[![](https://camo.githubusercontent.com/bd9be9382295049bac9e337c855773aed2081f311995391f8f308cc4fdd96591/68747470733a2f2f692e696d6775722e636f6d2f48614863437a322e706e67 align="left")](https://imgur.com/HaHcCz2)

### CalDAV Backup

[![](https://camo.githubusercontent.com/31fdef9f25ba273ba973375a39834ca2488580cc41f76d31cb6f8404b5e49b75/68747470733a2f2f692e696d6775722e636f6d2f556c51383579732e706e67 align="left")](https://imgur.com/UlQ85ys)

### CalDAV Schedule

[![](https://camo.githubusercontent.com/656ed0da2b54700e5923892c5068cfefd20286bbb94fca4d2aa59ae5143b8965/68747470733a2f2f692e696d6775722e636f6d2f3634414c5a646a2e706e67 align="left")](https://imgur.com/64ALZdj)

### Todoist Backup

[![](https://camo.githubusercontent.com/153cf1277ad9e90539016c56f421b2deaa22f4552cb801dfe3bebb40f289287e/68747470733a2f2f692e696d6775722e636f6d2f525067713779682e706e67 align="left")](https://imgur.com/RPgq7yh)

### Todoist Schedule

[![](https://camo.githubusercontent.com/900d7efae61bd7f1177ff8b07b80848d82ed6e1e14ea0320d50203c7091f69e7/68747470733a2f2f692e696d6775722e636f6d2f696f6661534c702e706e67 align="left")](https://imgur.com/iofaSLp)

### Slack

[![](https://camo.githubusercontent.com/0b7c0a673eadccd44cf9a32f3a45075fb698335762ca9923b2ee344fa58e5153/68747470733a2f2f692e696d6775722e636f6d2f634e75797967422e706e67 align="left")](https://imgur.com/cNuyygB)

### Discord

[![](https://camo.githubusercontent.com/96dabc062b85d895d9898a8eaed53a06bc0e5104b64f286e67b249c0a8619512/68747470733a2f2f692e696d6775722e636f6d2f6a5971525936742e706e67 align="left")](https://imgur.com/jYqRY6t)

### Telegram

[![](https://camo.githubusercontent.com/291929524768d72b40d900ebf8976192670eca8dbfaafde2734365a8a2516573/68747470733a2f2f692e696d6775722e636f6d2f53535842574a542e706e67 align="left")](https://imgur.com/SSXBWJT)

## System Requirements

* **Operating System**: Compatible with major Linux distributions
    
    * ✅ Ubuntu
        
    * ✅ Debian
        

## Installation

### Clone the repository

```basic
   git clone https://github.com/querylab/lazywarden.git
   cd lazywarden
```

### Configure Environment Variables & Bitwarden Secrets Manager

* Create a `.env` file based on the on this `.env.sample` example file and fill in the necessary variables.
    

```basic
GOOGLE_SERVICE_ACCOUNT_FILE=/root/lazywarden/config/bitwarden-drive-backup-google.json
GOOGLE_FOLDER_ID=1oWWis8QR3VTz5qRA3W4YTtO0LjvXFvoB
BACKUP_DIR=/root/lazywarden/backup-drive/
TELEGRAM_TOKEN=
TELEGRAM_CHAT_ID=
DISCORD_WEBHOOK_URL=
SLACK_WEBHOOK_URL=
SMTP_SERVER=mail.smtp2go.com
SMTP_PORT=8025
SMTP_USERNAME=
SMTP_PASSWORD=
EMAIL_RECIPIENT=
SENDER_EMAIL=
API_URL=https://vault.bitwarden.com/api   # No Modify No Touch
IDENTITY_URL=https://vault.bitwarden.com/identity   # No Modify No Touch
ORGANIZATION_ID=232c1123-78f9-4124-b769-b195122f78bf
ACCESS_TOKEN=0.3a22t111a-c111-1111-8fa2-b1c12341236a.1QTvdFZ12333ZEVSGM8azrOns7Wux:H+5prum123OQb28123KvUw==  # Access Token from Bitwarden Secrets Manager Ubuntu-Lazywarden Machine
CRON_SCHEDULE="0 0 23 * *" #Cron Every 24 hours for Docker 
TIMEZONE=America/New_York
TIMESTAMP=2024_09_18_19_45_40 # To decrypt all zip files in your backup or import them, just use the timestamp that was generated in the backup. For example, use the files that are generated in the backup like this: bw-backup_2024_09_18_19_45_40.zip.
```

### Ubuntu Configuration

* Run the script to install all system dependencies and requirements
    

```basic
cd lazywarden/scripts
chmod +x setup-ubuntu-env.sh
./setup-ubuntu-env.sh
```

* Run this script to automatically install Docker & Docker-Compose:
    

```basic
chmod +x docker-ubuntu.sh
./docker-ubuntu.sh
```

* First, ensure you are in the root directory of the project `lazywarden/`:
    

```basic
cd .. 
source venv/bin/activate
```

* Now Install Bitwarden CLI using the [`bitwarden-cli-install.py`](http://bitwarden-cli-install.py) script, which will install all CLI dependencies:
    

```basic
python3 scripts/bitwarden-cli-install.py
```

* Change the system timezone using the following command. Replace `Region/City` with the desired timezone (e.g., `America/New_York`):
    

```basic
timedatectl set-timezone Region/City
```

* For example, to set the timezone to `America/New_York`, you would run:
    

```basic
timedatectl set-timezone America/New_York
```

* Run the Lazywarden program. Navigate to the `app/` folder and execute [`main.py`](http://main.py):
    

```basic
cd app
python3 main.py
```

---

### Debian Configuration

* Run the script to install all system dependencies and requirements:
    

```basic
cd lazywarden/scripts
chmod +x setup-debian-env.sh
./setup-debian-env.sh
```

* Run this script to automatically install Docker & Docker-Compose:
    

```basic
chmod +x docker-debian.sh
./docker-debian.sh
```

* First, ensure you are in the root directory of the project `lazywarden/`:
    

```basic
cd .. 
source venv/bin/activate
```

* Install Bitwarden CLI using the [`bitwarden-cli-install.py`](http://bitwarden-cli-install.py) script, which will install all CLI dependencies:
    

```basic
python3 scripts/bitwarden-cli-install.py
```

* Change the system timezone using the following command. Replace `Region/City` with the desired timezone (e.g., `America/New_York`):
    

```basic
timedatectl set-timezone Region/City
```

* For example, to set the timezone to `America/New_York`, you would run:
    

```basic
timedatectl set-timezone America/New_York
```

* Run the Lazywarden program. Navigate to the `app/` folder and execute [`main.py`](http://main.py):
    

```basic
cd app
python3 main.py
```

* In Debian, if you encounter an error when running [`main.py`](http://main.py), it may be related to missing or outdated libraries. To fix this, I recommend running the following command to install all the necessary dependencies:
    

```basic
 pip install -r requirements.txt
```

## Steps to Configure Bitwarden Secrets Manager

To set up Secret Management in Bitwarden, first create a new organization in your account to serve as a container for shared secrets. Next, subscribe to the Secret Manager service, which allows you to securely store an unlimited number of secrets, such as API keys, passwords and certificates. This service provides end-to-end encryption, centralized management and access control.

[![](https://camo.githubusercontent.com/35ebd5038857be77ad19a6501662b00052360ef6590e6b794a4330afeae5fc14/68747470733a2f2f692e696d6775722e636f6d2f38726668546e752e706e67 align="left")](https://imgur.com/8rfhTnu)

* After creating your Organization, go to Secret Manager in the tab at the top right.
    

[![](https://camo.githubusercontent.com/ee2ada76b0ded7b4fa4dbf942fc7c102eee6c267199373444591f6282346beac/68747470733a2f2f692e696d6775722e636f6d2f625431357857332e706e67 align="left")](https://imgur.com/bT15xW3)

* Then create your lazywarden Project.
    

[![](https://camo.githubusercontent.com/cb5f7d8c06b146a564e73327b8b1299dfba792918a07f620cfd9aaada06e3f42/68747470733a2f2f692e696d6775722e636f6d2f6f7a7149794f752e706e67 align="left")](https://imgur.com/ozqIyOu)

* After creating your lazywarden Project, you need to create the secrets that will be in the lazywarden project. Here are some examples:
    

[![](https://camo.githubusercontent.com/5f90baa724baebe1a5d02e602a01272278ea53207539ada9b05293ad302b61a1/68747470733a2f2f692e696d6775722e636f6d2f54465935486d752e706e67 align="left")](https://imgur.com/TFY5Hmu)

[![](https://camo.githubusercontent.com/530130d8d6b33c27d74f360007e4e5d6b748d728265980695f5e0d0359d2fca0/68747470733a2f2f692e696d6775722e636f6d2f43387249364c632e706e67 align="left")](https://imgur.com/C8rI6Lc)

[![](https://camo.githubusercontent.com/d41d917939b39b8f33281e9639249af6d6e564565a31add8873c655f5ee996a7/68747470733a2f2f692e696d6775722e636f6d2f5673563653346b2e706e67 align="left")](https://imgur.com/VsV6S4k)

* If you have TOTP enabled on your Bitwarden account, put the seeds of your TOTP in the **BW\_TOTP\_SECRET** variable.
    

[![](https://camo.githubusercontent.com/75f28a95e0bc1820e009fbcdd8f9fc956b045ddb9cf2fa915ceec583e94a2bf9/68747470733a2f2f692e696d6775722e636f6d2f4c304b71754a332e706e67 align="left")](https://imgur.com/L0KquJ3)

* If you do not have TOTP enabled on your Bitwarden account, just put random characters as shown in the image below.
    

[![](https://camo.githubusercontent.com/b13f0993e28ad0dfb12fab5531c042e7e09d116e9a58ef214289ec41ba246c2c/68747470733a2f2f692e696d6775722e636f6d2f435753657149562e706e67 align="left")](https://imgur.com/CWSeqIV)

* Continue filling in the other variables one by one. If you do not have an account, for example for pCloud, MEGA, Filebase, Seafile, NextCloud or Dropbox fill in the variables with some random characters. For example, if you don't have a MEGA account, put the following:
    

[![](https://camo.githubusercontent.com/9b19d41f5d06b50039db73c434c1a1a5c1f03b584f4a316203f870dd141cc40f/68747470733a2f2f692e696d6775722e636f6d2f617074746962522e706e67 align="left")](https://imgur.com/apttibR)

[![](https://camo.githubusercontent.com/9fca4c93b00201969ee8be8e96c8aa8286aa5fd0d825e4ec7a28d35f1f74ad44/68747470733a2f2f692e696d6775722e636f6d2f6f7243555a6f472e706e67 align="left")](https://imgur.com/orCUZoG)

* As you can see in the images above, I don't have a MEGA account, so I used random strings. You always have to have something in the Secret Variables for the program to work. Now, the backup will only be stored locally in the chosen directory and in Google Drive, Dropbox, pCloud, NextCloud, Seafile and Filebase but not in MEGA as my account is not configured
    
* After creating all your secrets, create a Machine Account that will hold our ACCESS\_TOKEN.
    

[![](https://camo.githubusercontent.com/1b891b96b48eb8e267b847bd54d0f53e516460d3e16b34a2823073c986b66e5f/68747470733a2f2f692e696d6775722e636f6d2f6e41545a6368682e706e67 align="left")](https://imgur.com/nATZchh)

[![](https://camo.githubusercontent.com/d3c20fcb0cdfd1b68ac22b1ae143a7948c26a02ff604c144df55e5e5ec2fc267/68747470733a2f2f692e696d6775722e636f6d2f7053574a6671522e706e67 align="left")](https://imgur.com/pSWJfqR)

* Add and save the lazywarden project to your Machine Account.
    

[![](https://camo.githubusercontent.com/6d1dab541f045f200151204a6bcc88223295020e0fc98ff0313423b257c3a289/68747470733a2f2f692e696d6775722e636f6d2f536279446b376d2e706e67 align="left")](https://imgur.com/SbyDk7m)

[![](https://camo.githubusercontent.com/e409f56092bbff9e09cfb5bcbae3359ec0a9bad2f60b9e19bbb9cb8fd89a7668/68747470733a2f2f692e696d6775722e636f6d2f6970764958684d2e706e67 align="left")](https://imgur.com/ipvIXhM)

* Finally, go to Access Tokens and create one to use in our lazywarden project.
    

[![](https://camo.githubusercontent.com/a883f2d0a96581a17236279e60ed11066afc9fe761ae7d5263abff351991bae4/68747470733a2f2f692e696d6775722e636f6d2f4b31774b434f522e706e67 align="left")](https://imgur.com/K1wKCOR)

* With these secrets added, we can now modify our **secrets\_**[**manager.py**](http://manager.py) file to contain our secrets.
    

```basic
	
    "BW_URL": "00000000-0000-0000-0000-000000000000",
    "BW_USERNAME": "00000000-0000-0000-0000-000000000000",
    "BW_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "BW_TOTP_SECRET": "00000000-0000-0000-0000-000000000000",
    "ENCRYPTION_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "ZIP_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "ZIP_ATTACHMENT_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "PCLOUD_USERNAME": "00000000-0000-0000-0000-000000000000",
    "PCLOUD_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "MEGA_EMAIL": "00000000-0000-0000-0000-000000000000",
    "MEGA_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "DROPBOX_ACCESS_TOKEN": "00000000-0000-0000-0000-000000000000",
    "DROPBOX_REFRESH_TOKEN": "00000000-0000-0000-0000-000000000000",
    "DROPBOX_APP_KEY": "00000000-0000-0000-0000-000000000000",
    "DROPBOX_APP_SECRET": "00000000-0000-0000-0000-000000000000",
    "TODOIST_TOKEN": "00000000-0000-0000-0000-000000000000",
    "CALDAV_URL": "00000000-0000-0000-0000-000000000000",
    "CALDAV_USERNAME": "00000000-0000-0000-0000-000000000000",
    "CALDAV_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "NEXTCLOUD_URL": "00000000-0000-0000-0000-000000000000",
    "NEXTCLOUD_USERNAME": "00000000-0000-0000-0000-000000000000",
    "NEXTCLOUD_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "SEAFILE_SERVER_URL": "00000000-0000-0000-0000-000000000000",
    "SEAFILE_USERNAME": "00000000-0000-0000-0000-000000000000",
    "SEAFILE_PASSWORD": "00000000-0000-0000-0000-000000000000",
    "FILEBASE_ACCESS_KEY": "00000000-0000-0000-0000-000000000000",
    "FILEBASE_SECRET_KEY": "00000000-0000-0000-0000-000000000000",
    "KEEPASS_PASSWORD": "00000000-0000-0000-0000-000000000000"
    
```

* To find the **ORGANIZATION\_ID** variable for our **.env** you can get it by visiting the URL when you are in your organization or by running the following command:
    

```basic
bw list organizations
```

```basic
ORGANIZATION_ID=212A4880-22f9-1114-b00e-12345234278ac

ACCESS_TOKEN=0.345f5e9c-8730-4a4c-917b-b100003312356.Oj4XzcyGFF222212345kwzV:e5mC4d1111111128/3EQ==
```

# Attention: Security Critical Variables

```basic
### These variables contain the passwords for encrypting the backup.
### Change the passwords according to your preferences.

#Contains the encryption password for the JSON file
ENCRYPTION_PASSWORD=p3mTd5SqDqkXQqE!Tpwv27Ecx  


#Contains the encryption password for the first ZIP file
ZIP_PASSWORD=ZCGvq@gwS7QhV@&R3k*x*xN72anybyFHW2RWiBTr  


# Contains the encryption password for the attached ZIP file.
# Where our files will be stored if Bitwarden Premium is enabled.
# If Bitwarden Premium is not enabled, the attachment folder will be empty.
ZIP_ATTACHMENT_PASSWORD=HBLXL9!grer@Uay2edkwTXeZx!E9DxKphNxsNak1knb3dcfx2o   

```

## Dropbox API Configuration

By following these steps, your Dropbox Token will remain active and will not expire every 4 hours.

1. Go to [https://www.dropbox.com/developers/apps/create](https://www.dropbox.com/developers/apps/create)
    

* Create a new project.
    

[![](https://camo.githubusercontent.com/e8e9abf98a746b21c956f370e5e4b6917ef409979430b5e442ecaaaea9a5bfd1/68747470733a2f2f692e696d6775722e636f6d2f315963536b64762e706e67 align="left")](https://imgur.com/1YcSkdv)

[![](https://camo.githubusercontent.com/298ef8406f753093be0c37e409f499c1962f12c52815f2bfdeb8d1fbd1cdf5b7/68747470733a2f2f692e696d6775722e636f6d2f473062346d6f552e706e67 align="left")](https://imgur.com/G0b4moU)

* Create Permissions
    

[![](https://camo.githubusercontent.com/34fbd099c8c930f5dee59df3eeb66ff00bc627c766da16c9b8e11ef0b2187dde/68747470733a2f2f692e696d6775722e636f6d2f74306e436739682e706e67 align="left")](https://imgur.com/t0nCg9h)

2. Obtain the Authorization Code
    

* Open a browser and navigate to the following URL, replacing `<App key>` with your App Key:
    

```basic
https://www.dropbox.com/oauth2/authorize?token_access_type=offline&response_type=code&client_id=<App key>
```

[![](https://camo.githubusercontent.com/faf44748e5e115f0e8575fedda7df13caa6698e8b6fbe06af8ac8fdafd9933b3/68747470733a2f2f692e696d6775722e636f6d2f49576a49684e612e706e67 align="left")](https://imgur.com/IWjIhNa)

[![](https://camo.githubusercontent.com/8c67b2f437d8628576ba64e4c1cccd2c9c2520ee33f11c4018421262fd7e76ee/68747470733a2f2f692e696d6775722e636f6d2f717454683644472e706e67 align="left")](https://imgur.com/qtTh6DG)

[![](https://camo.githubusercontent.com/06f6d133035099ce0e1c7b03ffa7411e83b323333a27aa12402eac0179e4ddfb/68747470733a2f2f692e696d6775722e636f6d2f746a6c4438457a2e706e67 align="left")](https://imgur.com/tjlD8Ez)

3. Obtain the Authorization Token
    

Run the following command in the terminal, making sure to replace `<received code>`, `<App key>`, and `<App secret>` with the correct values:

```basic
curl https://api.dropbox.com/oauth2/token \
-d code=<received code> \
-d grant_type=authorization_code \
-u <App key>:<App secret>

#Example
curl https://api.dropbox.com/oauth2/token \
-d code=G4sTbrY9DMoAAAAAAAAAQTeLtVHACmv1tVaWYLYCGvA \
-d grant_type=authorization_code \
-u 7on1ofs1236ki:b6bl6jg123lm8iz
```

* When you run the command, you will receive a response like this:
    

```basic
 "access_token": "sl.B3hxfHXr123459z8_TS230pcLcLNbJ1234Hj-ccZmG5XCcQrN-Wb6ESMs0PSzwOtROxLb6XRaj6mUzHU1g8G60canTvjkWBBaNzVY1234hH2FEOhlwseaNcnQ9RyPn6vh",
  "token_type": "bearer",
  "expires_in": 14400,
  "refresh_token": "WtG6MI5YdccAAAAAAAAAAcAvu1234nB6skR3BmpgH3x5Reb-ae7FsLuNQ5-mZkk",
  "scope": "account_info.read",
  "uid": "143786425",
  "account_id": "dbid:BBAnJyzGYtm3-WP9a2HkL1TL8FVgPl5s-VM"
```

* Now use this new `refresh_token`, `access_token` along with the previous `<App key>`, and `<App secret>` to fill in the secret variables needed in Bitwarden Secret Manager:
    

```basic
#Example
      DROPBOX_ACCESS_TOKEN=sl.B3hxfHXrU12345z8_TS230pcLcLNbJj019MyrVHj-ccZmG5XCcQrN-Wb6ESMs0PSzwOtROxLb612345g8G60canTvjkWBBaNzVYP15cx5h12345NcnQ9RyPn6vh
      DROPBOX_REFRESH_TOKEN=WtG6MI5Yd1234AAAAAAcAvuFd9usnB6skR3BmpgH3x5Reb-ae7FsLuNQ5-mZkk
      DROPBOX_APP_KEY=1on14fs123456ki
      DROPBOX_APP_SECRET=b1bl12345m8iz
```

## Google Drive API Configuration

1. Go to this web page [https://console.developers.google.com/iam-admin/serviceaccounts](https://console.developers.google.com/iam-admin/serviceaccounts)
    
2. Create a New Project.
    

[![](https://camo.githubusercontent.com/5ff4a0e132746df4bdbe19c915bda5be3cc832f6c686e3ad5fe7d9c8b3b79608/68747470733a2f2f692e696d6775722e636f6d2f657668796633312e706e67 align="left")](https://imgur.com/evhyf31)

3. Then go to "Service Accounts" and create a new service.
    

[![](https://camo.githubusercontent.com/2ffaeed0be62a083bdfaab11567a6cdf10b85901f7592d61aa80dd368997170b/68747470733a2f2f692e696d6775722e636f6d2f6838484f654a492e706e67 align="left")](https://imgur.com/h8HOeJI)

[![](https://camo.githubusercontent.com/b9cd8fa7f8b899d8d6f00c55e6c96a2182a588958f056920b8ba918e321f4524/68747470733a2f2f692e696d6775722e636f6d2f427174543830582e706e67 align="left")](https://imgur.com/BqtT80X)

[![](https://camo.githubusercontent.com/a28adcbaa3f8d11fbe1fcc825bf5d124526611cdc27219588cb949949e35b198/68747470733a2f2f692e696d6775722e636f6d2f703435735658352e706e67 align="left")](https://imgur.com/p45sVX5)

4. Select the role "Actions Admin".
    

[![](https://camo.githubusercontent.com/fe0c2e5a3db2080c47b26cc50aac90dfddeefb3680da333a8a7fd12877c2cc99/68747470733a2f2f692e696d6775722e636f6d2f657739685852712e706e67 align="left")](https://imgur.com/ew9hXRq)

5. Download the key in JSON format. This key will be used in our project to upload the Bitwarden backup to Google Drive. Once you obtain the JSON file, store it in the **/config** folder of the project. Name the JSON file **bitwarden-drive-backup-google.json**.
    

```basic
# Place the Google credentials file in the specified path /config

GOOGLE_SERVICE_ACCOUNT_FILE=/home/lazywarden/config/bitwarden-drive-backup-google.json
```

[![](https://camo.githubusercontent.com/ff8033675455d5d8c69e057221258583db47ba60812aabed563a4ebcedfd7b92/68747470733a2f2f692e696d6775722e636f6d2f4168685767444d2e706e67 align="left")](https://imgur.com/AhhWgDM)

[![](https://camo.githubusercontent.com/dc59db9151d3e2e07d9248e30d646f860c3d7828b278f64f19713e78feb35308/68747470733a2f2f692e696d6775722e636f6d2f4777626e4679722e706e67 align="left")](https://imgur.com/GwbnFyr)

6. Go to the following link and enable the Google Drive API:[https://console.cloud.google.com/apis/library](https://console.cloud.google.com/apis/library)
    

[![](https://camo.githubusercontent.com/b30612927fb3270f8ecee0f8c1ce410bf13830d17c1aaa96b196fc878f45f618/68747470733a2f2f692e696d6775722e636f6d2f735752773073622e706e67 align="left")](https://imgur.com/sWRw0sb)

7. Now that you have enabled the API, go to your Google Drive and create a folder named "Bitwarden-Backup".
    

[![](https://camo.githubusercontent.com/d2bce1c9e219bb04b8c3fe0227154c3ea3196ccd9a02554a7d47a00663f00857/68747470733a2f2f692e696d6775722e636f6d2f3770436c3038622e706e67 align="left")](https://imgur.com/7pCl08b)

8. Share the "Bitwarden-Backup" folder by clicking on "Share" and share it with the email address created in the Service Account when you set up the project.
    

[![](https://camo.githubusercontent.com/db51a7d649d8f3e5eee9466b7b687e182dfa102bca2e2327b0c06f9b523e044d/68747470733a2f2f692e696d6775722e636f6d2f6f7a61776a62372e706e67 align="left")](https://imgur.com/ozawjb7)

[![](https://camo.githubusercontent.com/f2f7cfb566032801a6cb18794bf40a30d7ac8e353f8f1aa1a7b3084365b636c7/68747470733a2f2f692e696d6775722e636f6d2f423477384d74752e706e67 align="left")](https://imgur.com/B4w8Mtu)

[![](https://camo.githubusercontent.com/9ae82827628a9289b9e1afb9740fa8819af957bbd41ed51af69b01194865bfe3/68747470733a2f2f692e696d6775722e636f6d2f6b6b6f35766b682e706e67 align="left")](https://imgur.com/kko5vkh)

9. After sharing the folder, you need to get the ID of this folder to store it in your **.env** file. To find the ID of the “Bitwarden-Backup” folder, open the folder and look at the URL in your browser.
    

```basic
GOOGLE_FOLDER_ID=1qtV4vfIjmXyhDdzIzJ6RiCc-b0M22vsF
```

[![](https://camo.githubusercontent.com/64efe3cb4914300f1ed2fcaf0b0442a7e8b365c567c4cc0b1d7154aac8234406/68747470733a2f2f692e696d6775722e636f6d2f664e4a303759622e706e67 align="left")](https://imgur.com/fNJ07Yb)

### Tree Structure

```basic
lazywarden/
├── app/                           # This directory appears to contain the main application code
│   ├── backup.py                  # Backup functions
│   ├── bitwarden_client.py        # Client to interact with Bitwarden
│   ├── config.py                  # General application configurations
│   ├── imports.py                 # Handles common imports
│   ├── main.py                    # Main entry point of the application
│   ├── notifications.py           # Handles notifications
│   ├── secrets_manager.py         # Manages secrets
│   ├── import_to_bitwarden.py     # Import your bitwarden vault
│   ├── import_to_keepass.py       # Create kdbx database 
│   ├── schedule_backup.py         # For create Schedule Backup
├── config/                        # Directory for configuration files
│   ├── bitwarden-drive-backup-google.json # Configuration for Google Drive
├── scripts/                       # Directory for installation and setup scripts
│   ├── bitwarden-cli-install.py   # Script to install the Bitwarden CLI
│   ├── docker-debian.sh           # Setup script for Debian with Docker
│   ├── docker-ubuntu.sh           # Setup script for Ubuntu with Docker
│   ├── setup-debian-env.sh        # Environment setup for Debian
│   ├── setup-ubuntu-env.sh        # Environment setup for Ubuntu
│   ├── alldecrypt-zip.py          # Decrypt all zip files 
│   ├── json-only-decrypt.py       # Decrypt only json files (optional)
├── backup-drive/
│   ├── (This is where the generated backups will be stored local)
├── .env                           # File for environment variables
├── Dockerfile                     # Docker configuration file to create an application image
├── docker-compose.yml             # Docker Compose Configuration
├── entrypoint.sh                  # Entrypoint script for Docker
└── requirements.txt               # File that lists the project Python dependencies
```

### Cron Job for Python (optional)

To automatically run the backup script in the background using cron, every 24 hours follow these steps:

1. Open the crontab for editing:
    

```basic
crontab -e
```

2. Select an editor if you dont have one configured:
    

```basic
Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed
Choose 1-4 [1]: 1
```

3. Add the following line to schedule the `lazywarden.py` script to run at midnight every day:
    

```basic
0 0 23 * * /root/lazywarden/venv/bin/python3 /root/lazywarden/app/main.py >> /var/log/lazywarden-cron.log 2>&1
```

4. Save & Close and reload the file. Verify that the cron job is set up correctly:
    

```basic
service cron reload

crontab -l
```

### Docker Compose

The Docker container will run the `main.py` script every 24 hours to back up Bitwarden and upload it to the configured cloud services. Notifications will be sent to the specified services in case of success or failure. You can modify the backup frequency according to your needs, such as monthly, daily, or hourly.

```basic
services:
  lazywarden:
    container_name: lazywarden_backup
    hostname: lazywarden_backup
    build: .
    env_file:
      - .env
    environment:
      UNLOCK_VAULT: "true"
    volumes:
      - /root/lazywarden/config:/config
      - /root/lazywarden/backup-drive:/root/lazywarden/backup-drive
    restart: unless-stopped

```

#### Run Docker Compose

* Run the Docker container
    

```basic
docker compose up -d
```

#### Dockerfile

* The `Dockerfile` sets up the environment, installs dependencies, and copies necessary files into the container.
    

#### docker-compose.yml

* The `docker-compose.yml` file defines the lazywarden service and sets up environment variables and volumes for persistent storage.
    

### Security Recommendation: Run in Local Environment

* For security, run this project only in a local environment within your personal network. This significantly reduces the risk of exposure to external attacks, ensuring that sensitive data and credentials remain protected within a controlled environment.
    

### 📢 Warning

##### **Important Note**

* Large attachments in your Bitwarden account (e.g., MP4 videos, MP3 files, high-resolution photos) may cause the backup process to take longer. Uploading these larger backups to cloud services will also be slower. Local storage and importing data are much faster in comparison.
    
* A high number of attachments can significantly extend the total backup time. Upload errors may occur when sending files to Dropbox, Google Drive, pCloud, MEGA, Seafile, Nextcloud, or Filebase. If an error occurs, retrying the backup often resolves the issue.
    
* Configuring the Bitwarden Secret Manager is required for the program to function correctly. Even if you don't have an account, you must set a random variable to ensure proper operation.
    
* This program is compatible with both self-hosted Bitwarden and Vaultwarden instances.
    
* Import functionality for Vaultwarden and self-hosted Bitwarden is not yet implemented in the Bitwarden API.
    
* CalDAV calendar integration has only been tested with the following providers: [Baikal](https://github.com/sabre-io/Baikal), [Fruux](https://fruux.com/), [Memotoo](https://www.memotoo.com/), [Posteo](https://posteo.de/), and [SOGo](https://www.sogo.nu/).
    
* Rotate the secrets stored in Bitwarden Secret Manager regularly for enhanced security.
    
* If you switch Bitwarden Accounts, make sure to run the `bw logout` command before logging into a new account.
    
* I run the program using the root user.
    

### Motivations

* I created Lazywarden to Automate Bitwarden Backups without manual effort or exposing sensitive data. After struggling with complex tools, I leveraged Bitwarden Secret Manager to securely manage secrets. Lazywarden automates backups and uploads them to multiple cloud services (Google Drive, Dropbox, pCloud, MEGA, Seafile, Nextcloud, Filebase), and integrates with Telegram, Discord, Slack, Todoist, and CalDAV for notifications and tracking. Its standout feature is the ability to restore encrypted backups back into Bitwarden, making backup management simple, secure, and efficient.
    
* If you like this project, please consider giving it a ⭐
