S3 Sync & Backup
approvedby ceilaolabs
This plugin has not been manually reviewed by Obsidian staff. Vault synchronization and scheduled backups across devices using S3-compatible storage (AWS S3, Cloudflare R2, RustFS, etc.) with optional end-to-end encryption.
Obsidian S3 Sync & Backup
Vault synchronization and scheduled backups across devices using S3-compatible storage (AWS S3, Cloudflare R2, RustFS, etc.) with optional end-to-end encryption.
Features
- Bi-directional Sync — Three-way reconciliation keeps your vault synchronized across devices via S3. Per-file SHA-256 baselines stored locally in IndexedDB detect changes accurately — no cloud manifest required.
- S3-Compatible Storage — Works with AWS S3, Cloudflare R2, RustFS, and any other S3-compatible endpoint.
- End-to-End Encryption — Optional XSalsa20-Poly1305 encryption with Argon2id key derivation. Encrypts both synced files and backup snapshots. Passphrase can be remembered for auto-unlock on startup.
- Scheduled Backups — Full vault snapshot backups with configurable intervals (hourly to weekly). Download any backup as a ZIP from settings.
- Smart Conflict Resolution — When the same file changes on two devices while offline, the plugin creates
LOCAL_andREMOTE_copies so you never lose data. - Status Bar Integration — Real-time sync and backup status at a glance, with clickable actions.
- Flexible Retention — Automatically clean up old backups by age (days) or number of copies.
- Plugin Settings Protection — The plugin's own settings directory is hardcoded-excluded from sync to prevent credential or passphrase leakage.
- Mobile Support — Works on iOS and Android. No desktop-only APIs used.
- Command Palette — Sync now, Backup now, Pause/Resume sync, and more — all available from the command palette with customizable hotkeys.
Installation
From Community Plugins
- Open Settings → Community plugins
- Search for "S3 Sync & Backup"
- Click Install then Enable
Manual Installation
- Download
main.js,manifest.json, andstyles.cssfrom the latest release. - Create the folder:
<VaultPath>/.obsidian/plugins/simple-storage-sync-and-backup/ - Copy the downloaded files into this folder.
- Reload Obsidian and enable the plugin in Settings → Community plugins.
Quick Start
1. Configure S3 Connection
- Open Settings → S3 Sync & Backup.
- Select your provider (AWS S3, Cloudflare R2, RustFS, or Other S3-compatible).
- Enter your credentials:
- Endpoint URL: Required for non-AWS providers.
- Region: Use
autofor Cloudflare R2. - Bucket name: Your S3 bucket.
- Access Key ID & Secret Access Key.
- Force Path Style: Only shown for the Other S3-compatible provider — AWS S3, Cloudflare R2, and RustFS each use a fixed addressing mode (path-style for R2/RustFS, virtual-hosted for AWS).
- Click Test Connection to verify credentials and bucket access.
2. Enable Sync
- In the Sync section, toggle Enable sync (on by default).
- Set the Sync prefix (default:
vault) — this is the S3 folder where your files live. - Toggle Auto-sync and choose a Sync interval (1 min to 30 min, default: 5 min).
- Enable Sync on startup to sync immediately when Obsidian opens.
3. Enable Backups (Optional but Recommended)
- In the Backup section, toggle Enable backups (on by default).
- Set the Backup prefix (default:
backups). - Choose a Backup interval (every hour, 6 hours, 12 hours, daily, every 3 days, or weekly).
- Enable Retention and configure a policy to auto-delete old backups.
- Use Backup now for an immediate snapshot at any time.
4. Enable Encryption (Optional)
⚠️ Important: If you enable encryption, you MUST remember your passphrase. There is no recovery if it is lost.
- Toggle Enable end-to-end encryption.
- Enter a strong passphrase (minimum 8 characters — a strength indicator guides you).
- Optionally enable Remember passphrase to auto-unlock the vault on startup.
- Use the same passphrase on all devices syncing this vault.
When encryption is enabled:
- All synced files are encrypted before upload to S3.
- All backup snapshots are encrypted (the backup manifest remains plain JSON for metadata).
- Other devices detect the encryption state automatically and prompt for the passphrase.
- Disabling encryption re-uploads all files as plaintext (with a confirmation dialog).
Permissions and data access
The plugin is a sync and backup tool, so by design it enumerates every file in your vault and then reads / uploads / downloads the files inside your configured sync and backup scope. This section spells out exactly what each piece of the plugin touches so you can make an informed decision before enabling it.
What the plugin reads
| API | Why the plugin uses it |
|---|---|
vault.getFiles() | Enumerates every file in the vault during sync planning and during backup snapshots. Without this the plugin cannot know what to sync or back up. |
vault.read() / vault.readBinary() | Reads file content so it can be uploaded to S3. Triggered only for files inside the sync/backup scope (every vault file minus your Exclude patterns minus the plugin's own settings directory). |
vault.on('create' / 'modify' / 'delete' / 'rename') | Tracks which files changed since the last sync so the next cycle only re-checks dirty paths. |
| Bulk re-read on encryption toggle | When you enable, disable, or rotate the passphrase, the plugin reads every in-scope vault file and re-uploads it in the new payload format. |
What the plugin writes
| Destination | What ends up there |
|---|---|
S3 (under your configured sync prefix, default vault) | A copy of every vault file inside the sync scope. File payloads are end-to-end encrypted when Enable encryption is on; plain otherwise. |
S3 (under your configured backup prefix, default backups) | Timestamped full-vault snapshots. File payloads are encrypted when encryption is enabled; the per-snapshot .backup-manifest.json is always plaintext so the plugin can list and inspect backups without the passphrase (it contains file paths, sizes, SHA-256 checksums, the encryption flag, and the originating device ID). |
Local vault (vault.create / vault.modify / vault.createBinary / vault.modifyBinary / vault.rename / vault.createFolder) | Files downloaded from S3 on the receiving end of a sync, plus LOCAL_* / REMOTE_* conflict artifacts when a file diverged on two devices. Parent folders are auto-created top-down as needed; the rename API is used to stage LOCAL_* conflict copies. |
Local vault trash (via fileManager.trashFile) | Files that were deleted on another device and propagated by sync. Honours Obsidian's Files and Links → Deleted files preference (system trash vs. .trash/ folder vs. permanent). |
IndexedDB (database obsidian-s3-sync-journal-{vaultName}) | Per-file sync baselines (path, hash, size, mtime, ETag) used for three-way reconciliation, plus a destination fingerprint that detects when you reconnect to a different bucket/prefix. Vault-scoped so two vaults on the same device never share state. |
Obsidian vault-scoped storage (key s3-sync-device-id) | A randomly generated per-vault device identifier. The same ID is written into every uploaded S3 object's obsidian-device-id custom metadata for last-writer attribution, and into the deviceId field of every backup manifest. |
data.json (Obsidian plugin settings) | All plugin settings (S3 credentials, optional saved passphrase, sync/backup toggles, exclude patterns) plus the last-completed backup timestamp used by the scheduler. The plugin's own settings directory is hardcoded-excluded from sync so this file never leaves your device. |
What is sent off your device
- HTTP traffic goes only to the S3 endpoint you configure (AWS S3, Cloudflare R2, RustFS, or any other S3-compatible endpoint). The transport scheme matches the endpoint you set — HTTPS for hosted providers; the plugin accepts plain HTTP if you choose it (e.g.
http://localhost:9000for a local RustFS). - No telemetry, no analytics, no error reporting, no update polling. The Security section below covers the network-use detail.
- No remote code execution. The plugin never downloads or evaluates code from the network — all cryptography runs locally in the browser.
What is not read or written
- The plugin does not access the operating system shell, filesystem, or any APIs beyond those Obsidian exposes.
- It does not touch files outside the configured vault.
- It does not contact any host other than the S3 endpoint you configure.
Important — Obsidian config files are in scope by default. Only the plugin's own settings directory (
.obsidian/plugins/simple-storage-sync-and-backup/) is hard-excluded. Other files under.obsidian/(workspace layout, hotkeys, third-party plugin settings, etc.) are vault files from Obsidian's point of view and are enumerated and synced unless you add them to Exclude patterns in settings. If you do not want those propagated across devices, add patterns such as.obsidian/workspace*,.obsidian/hotkeys.json,.obsidian/plugins/**, etc. The defaults (**/workspace*,.trash/**) cover the workspace layout but not other config files.
Settings Reference
Connection
| Setting | Description |
|---|---|
| Provider | Storage provider: AWS S3, Cloudflare R2, RustFS, or Other S3-compatible. |
| Endpoint URL | S3-compatible endpoint URL. Required for non-AWS providers (e.g., https://<ACCOUNT_ID>.r2.cloudflarestorage.com for R2, http://localhost:9000 for RustFS). Hidden when provider is AWS. |
| Region | AWS region (e.g., us-east-1). Use auto for Cloudflare R2. |
| Bucket | Name of your S3 bucket. |
| Access key ID | Your S3 access key ID. Displayed as a password field. |
| Secret access key | Your S3 secret access key. Displayed as a password field. |
| Force path style | Use path-style URLs instead of virtual-hosted. Required for some self-hosted S3-compatible endpoints. Only shown for the Other S3-compatible provider — AWS, R2, and RustFS each pin a fixed addressing mode internally. |
| Test connection | Verify credentials, bucket access, and required permissions. |
Encryption
| Setting | Description |
|---|---|
| Enable end-to-end encryption | Encrypt all files with XSalsa20-Poly1305 before uploading to S3. Requires a passphrase (minimum 8 characters). Shows a strength indicator while typing. |
| Remember passphrase | Save the passphrase locally so the vault unlocks automatically on startup. The passphrase is stored in the plugin's data.json, which is hardcoded-excluded from sync. |
| Unlock | When the vault is encrypted but locked (e.g., after restarting Obsidian without "Remember passphrase"), enter your passphrase to unlock sync and backup. |
| Disable encryption | Re-upload all files as plaintext and remove the encryption marker. Shows a confirmation dialog. Other devices switch to plaintext mode automatically on next sync. |
Sync
| Setting | Description | Default |
|---|---|---|
| Enable sync | Master switch for bi-directional vault synchronization. | On |
| Sync prefix | S3 folder path for synced files (e.g., vault → s3://bucket/vault/). | vault |
| Auto-sync | Automatically sync at regular intervals. | On |
| Sync interval | How often to auto-sync. Options: 1, 2, 5, 10, 15, or 30 minutes. Only shown when auto-sync is enabled. | 5 min |
| Sync on startup | Run a sync immediately when Obsidian starts. | On |
Backup
| Setting | Description | Default |
|---|---|---|
| Enable backups | Master switch for scheduled vault backup snapshots. | On |
| Backup prefix | S3 folder path for backups (e.g., backups → s3://bucket/backups/). | backups |
| Backup interval | How often to create snapshots. Options: every hour, 6 hours, 12 hours, daily, every 3 days, or weekly. | Daily |
| Enable retention | Automatically delete old backups based on the retention policy. | Off |
| Retention mode | How to determine which backups to keep: By days (delete backups older than N days) or By copies (keep only the latest N backups). Only shown when retention is enabled. | By copies |
| Retention days | Delete backups older than this many days (1–360). Only shown in "By days" mode. | 30 |
| Retention copies | Keep only the latest N backups (1–1000). Only shown in "By copies" mode. | 30 |
| Backup now | Create a backup snapshot immediately. | |
| View backups | Open a modal listing the 5 most recent backups with per-backup download buttons. Each entry shows timestamp, file count, size, and encryption status. |
Advanced
| Setting | Description | Default |
|---|---|---|
| Debug logging | Enable verbose console logging for troubleshooting. | Off |
| Exclude patterns | Comma-separated glob patterns for files/folders to exclude from sync (e.g., workspace*, .trash/*). The plugin's own settings directory is always excluded regardless of this setting. | **/workspace*, .trash/** |
| Reset to defaults | Reset all settings to defaults, preserving S3 connection credentials. Shows a confirmation dialog. |
Command Palette
All commands are available via the Obsidian command palette (Ctrl/Cmd + P) and can be bound to custom hotkeys.
| Command | Description |
|---|---|
| S3 Sync & Backup: Sync now | Trigger an immediate sync. |
| S3 Sync & Backup: Backup now | Trigger an immediate backup snapshot. |
| S3 Sync & Backup: Pause sync | Pause automatic sync (shown only when sync and auto-sync are enabled). |
| S3 Sync & Backup: Resume sync | Resume automatic sync after pausing. |
| S3 Sync & Backup: View sync log | Open the sync log viewer. |
| S3 Sync & Backup: View backups | Open a modal listing recent backups with download buttons. |
| S3 Sync & Backup: Open settings | Open the plugin settings page. |
Multi-Device Sync
This plugin is designed for multi-device use. Each device gets a unique ID on first run, and all S3 uploads are tagged with the writing device's ID.
How it works:
- Each device maintains its own local sync journal (IndexedDB) with per-file baselines.
- On sync, the engine compares local state, remote state (S3), and the last-known baseline to determine what changed and where.
- If the same file changed on two devices while both were offline, a conflict is created with
LOCAL_andREMOTE_copies of the file.
Encryption across devices:
- When encryption is enabled on one device, other devices detect the encrypted state on next sync and prompt for the passphrase.
- Use the same passphrase on all devices. If the wrong passphrase is entered, the plugin notifies you and clears any saved passphrase.
- Encryption enable/disable operations use an advisory lock to prevent two devices from migrating simultaneously.
S3 Bucket Structure
your-bucket/
├── vault/ # LIVE DATA (synced)
│ ├── .obsidian-s3-sync/
│ │ └── .vault.enc # Encryption marker (if enabled)
│ ├── Notes/
│ │ └── my-note.md
│ └── Attachments/
│ └── image.png
│
└── backups/ # SNAPSHOTS (read-only)
├── backup-2024-12-25T14-30-00/
│ ├── .backup-manifest.json # Plain JSON: file count, checksums, encrypted flag
│ └── ... (full vault copy)
└── backup-2024-12-24T14-30-00/
Note: The plugin's own settings directory (
.obsidian/plugins/simple-storage-sync-and-backup/) is never uploaded to S3, regardless of exclude pattern configuration.
Security
- Encryption algorithm: XSalsa20-Poly1305 (via tweetnacl) with Argon2id key derivation (via hash-wasm).
- Content identity: SHA-256 fingerprints of plaintext content, stored in S3 custom metadata.
- Network use: Outbound network requests go only to the S3-compatible endpoint you configure (AWS S3, Cloudflare R2, or RustFS) over HTTPS. No third-party services, telemetry endpoints, analytics, or update servers are contacted. The plugin performs the following kinds of network activity, all under your control:
- Periodic sync polls your bucket on a user-configurable interval (default 5 minutes, range 1–30 minutes). Controlled by the Enable sync and Auto-sync toggles plus the Sync interval dropdown in Settings — turning either toggle off stops all scheduled sync traffic.
- Periodic backups snapshot your vault on a user-configurable schedule (default daily, options from hourly to weekly). Controlled by the Enable backups toggle and the Backup interval dropdown.
- Manual operations (sync now, backup now, test connection, download backup) only run when you invoke them from the command palette, status bar, or settings.
- No telemetry: The plugin sends no usage data, error reports, or identifiers anywhere. Disabling sync and backups stops all network activity completely.
- No remote code execution: All encryption and hashing runs locally in the browser. The plugin never fetches or evaluates code from the network.
- Credential protection: S3 credentials and saved passphrases are stored in Obsidian's
data.json, which is hardcoded-excluded from sync to prevent leakage.
Testing
The plugin includes 565+ automated tests: unit tests covering sync, encryption, backup, and utility modules, pipeline end-to-end tests, and integration tests against live S3 endpoints. CI runs linting, type-checking, and the full test suite on every pull request.
FAQ
Does this work on mobile?
Yes! The plugin works on both iOS and Android versions of Obsidian. No desktop-only APIs are used. Note that mobile operating systems may restrict background activity, so open the app periodically to ensure sync completes.Can I use this alongside Obsidian Sync?
It is not recommended. Using two sync solutions simultaneously can cause race conditions and data conflicts. Choose one primary sync method.How do I restore from a backup?
Go to Settings → S3 Sync & Backup → Backup → View backups, or use the View backups command from the command palette. The modal lists the 5 most recent backups — click "Download zip" to export one as a ZIP file. Extract it and manually copy files back into your vault.Why do I see LOCAL_ and REMOTE_ files?
This means the same file changed on two devices while both were offline (a sync conflict). Open both files, manually merge the content into the original filename, then delete theLOCAL_ and REMOTE_ copies. The conflict resolves on the next sync.
Are my backups encrypted?
Yes — when encryption is enabled and the vault is unlocked, all backup files are encrypted before upload. The backup manifest (.backup-manifest.json) is always plain JSON so the plugin can read backup metadata, but it contains only file names, checksums, and the encrypted flag — no file content.
What happens if I forget my passphrase?
There is no recovery. The passphrase is never sent to S3. If you lose it, encrypted files in S3 cannot be decrypted. Always use a password manager to store your passphrase securely.Can I change the sync or backup prefix after setup?
Yes, but existing files under the old prefix won't be moved. The plugin will treat the new prefix as a fresh location. You'd need to manually move or re-sync files if you change prefixes.What files are excluded from sync?
By default,**/workspace* and .trash/** are excluded. You can customize this in Settings → Advanced → Exclude patterns. The plugin's own settings directory (.obsidian/plugins/simple-storage-sync-and-backup/) is always excluded and cannot be overridden.
Support & Contributing
- Issues: Report bugs or request features
- Contributing: See CONTRIBUTING.md for development setup and guidelines.
License
MIT © Ceilão Labs
Made with love for the Obsidian community
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.