S3 Sync + Backup

by ceilaolabs
5
4
3
2
1
Score: 35/100

Description

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.

Reviews

No reviews yet.

Stats

stars
302
downloads
0
forks
8
days
NaN
days
NaN
days
0
total PRs
0
open PRs
0
closed PRs
0
merged PRs
0
total issues
0
open issues
0
closed issues
0
commits

Latest Version

Invalid date

Changelog

README file from

Github

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.

Latest Release Obsidian License Conventional Commits Codecov

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_ and REMOTE_ 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

  1. Open SettingsCommunity plugins
  2. Search for "S3 Sync + Backup"
  3. Click Install then Enable

Manual Installation

  1. Download main.js, manifest.json, and styles.css from the latest release.
  2. Create the folder: <VaultPath>/.obsidian/plugins/simple-storage-sync-and-backup/
  3. Copy the downloaded files into this folder.
  4. Reload Obsidian and enable the plugin in SettingsCommunity plugins.

Quick Start

1. Configure S3 Connection

  1. Open SettingsS3 Sync + Backup.
  2. Select your provider (AWS S3, Cloudflare R2, RustFS, or Other S3-compatible).
  3. Enter your credentials:
    • Endpoint URL: Required for non-AWS providers.
    • Region: Use auto for 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).
  4. Click Test Connection to verify credentials and bucket access.

2. Enable Sync

  1. In the Sync section, toggle Enable sync (on by default).
  2. Set the Sync prefix (default: vault) — this is the S3 folder where your files live.
  3. Toggle Auto-sync and choose a Sync interval (1 min to 30 min, default: 5 min).
  4. Enable Sync on startup to sync immediately when Obsidian opens.
  1. In the Backup section, toggle Enable backups (on by default).
  2. Set the Backup prefix (default: backups).
  3. Choose a Backup interval (every hour, 6 hours, 12 hours, daily, every 3 days, or weekly).
  4. Enable Retention and configure a policy to auto-delete old backups.
  5. 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.

  1. Toggle Enable end-to-end encryption.
  2. Enter a strong passphrase (minimum 8 characters — a strength indicator guides you).
  3. Optionally enable Remember passphrase to auto-unlock the vault on startup.
  4. 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:9000 for 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., vaults3://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., backupss3://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_ and REMOTE_ 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


Support & Contributing

License

MIT © Ceilão Labs

Made with love for the Obsidian community