by Nick
Sync file contents with Google Drive using AES-256-GCM encryption, with encryption keys kept on your device.
Encrypted Google Drive Sync
Sync file contents with Google Drive using AES-256-GCM encryption, with encryption keys kept on your device.
Requires Obsidian 1.13.0 or later on desktop. Settings are indexed by Obsidian's global settings search.
This plugin needs your own Google account and a Google Cloud OAuth client. It sends authorization and encrypted file data only to Google (accounts.google.com, oauth2.googleapis.com, and www.googleapis.com). It does not upload your vault to any other server.
Access and privacy
- Synchronization enumerates the vault's note and attachment paths to find changes, then reads non-excluded files for hashing and encryption. This is required to sync the whole vault. Runs are manual unless you enable auto-sync.
- File contents are encrypted. Filenames, folder structure, encrypted file sizes, and modification times remain visible to Google Drive.
- Vault configuration, trash, and Git metadata are excluded. Additional exclusions are available in the plugin's settings.
- Authorization uses a temporary server bound to
127.0.0.1, protected by OAuth state and PKCE. No telemetry is collected.
Features
- End-to-end encryption — AES-256-GCM via Web Crypto API. Files are encrypted before leaving your machine.
- Two-layer key hierarchy — A random master key encrypts your files; a password-derived key (PBKDF2, 600 000 iterations) protects the master key. Changing your password does not require re-encrypting the entire vault.
- Bidirectional sync — Uploads local changes, downloads remote changes, detects and resolves conflicts.
- Folder structure preserved — Your vault's directory tree is mirrored on Google Drive.
- Auto-sync — Optional periodic sync at a configurable interval.
- Desktop only — Uses Node.js for the OAuth loopback flow.
How it works
Password
│ PBKDF2 (SHA-256, 600K iterations, random salt)
▼
Password-Derived Key
│ AES-256-GCM wrap/unwrap
▼
Master Encryption Key ← stored wrapped in plugin data
│ AES-256-GCM (unique 12-byte IV per file)
▼
Encrypted file: [version · 1B] [IV · 12B] [ciphertext + auth tag]
Each file is encrypted independently with a fresh IV. The master key never leaves your device in plaintext.
Installation
From Community Plugins (once published in the app catalog)
- Open Settings → Community plugins → Browse.
- Search for Encrypted Google Drive Sync.
- Click Install, then Enable.
Manual
- Download
main.js,manifest.json, andstyles.cssfrom the latest release. - Create a folder:
<your-vault>/.obsidian/plugins/encrypted-gdrive-sync/(use your vault's configured settings folder if it is not.obsidian). - Place the three files inside it.
- Reload Obsidian and enable the plugin in Settings → Community plugins.
Upgrading a manually installed version 1.0.x
Version 1.1.0 and later use the directory-compliant ID encrypted-gdrive-sync, and version 1.1.1 adopts the name Encrypted Google Drive Sync. The encrypted file format is unchanged.
- Disable the old plugin and close Obsidian.
- Back up the old
e2e-gdrive-syncplugin folder, including itsdata.json. - Install the new release in
encrypted-gdrive-syncas described above. - Copy the existing
data.jsonto the new plugin folder. It contains your wrapped encryption key, Google authorization, and sync state. Keep the original key data to decrypt the existing backup. - Reopen Obsidian and enable only the new installation. Unlock it using your existing password.
Setup
1. Create a Google Cloud project
- Go to Google Cloud Console.
- Create a new project (or use an existing one).
- Navigate to APIs & Services → Library and enable Google Drive API.
- Go to APIs & Services → Credentials → Create Credentials → OAuth client ID.
- Select application type Desktop app.
- Copy the Client ID and Client Secret.
If your app is in "Testing" mode, add your Google account as a test user under OAuth consent screen → Test users.
2. Configure the plugin
Open Settings → Encrypted Google Drive Sync:
- Encryption — Set a password (minimum 8 characters). This generates your master encryption key.
- Google Drive — Paste the Client ID and Client Secret, then click Connect Google Drive. A browser window will open for authorization.
- Sync — Click Sync or use the ribbon icon. Optionally enable auto-sync.
Sync behavior
| Scenario | Action |
|---|---|
| New local file | Encrypt → upload |
| New remote file | Download → decrypt |
| Local file modified | Re-encrypt → upload |
| Remote file modified | Download → re-decrypt |
| File deleted locally | Restore from Google Drive (no automatic deletion) |
| File deleted remotely | Re-upload local copy (no automatic deletion) |
| Both sides modified or both exist without a previous sync record | Create a local conflict copy of the remote version, upload local version |
Default exclusions: .obsidian/, .trash/, .git/. Additional patterns can be configured in settings.
Deletion is intentionally not propagated: removing a file on one side restores it from the other. To remove a synced file permanently, delete it on every device and on Google Drive before syncing again. Back up your vault before the first sync. To decrypt an existing Drive backup on a second device, securely transfer the original plugin's key data (keyData in its data.json) and use the same Google Cloud OAuth client; a new password/key or an unrelated Google OAuth app cannot access the existing backup.
Security
- Encryption uses the Web Crypto API (
crypto.subtle), not a custom implementation. - AES-256-GCM provides authenticated encryption — any tampering is detected.
- The master key is wrapped (encrypted) with a key derived from your password. The raw master key is never written to disk.
- By default the password is kept only for the current session. "Remember password" stores it in Obsidian's plugin data for auto-unlock; turn this on only if you accept that anyone with access to the vault configuration can read it.
- Google Drive scope is
drive.file— the plugin can only access files it created.
Building from source
npm ci
npm run lint
npm test
npm run build # production build
npm run dev # watch mode
Tagged releases are built and tested in GitHub Actions. The workflow verifies the committed bundle and publishes signed artifact attestations for main.js, manifest.json, and styles.css.
License
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.