Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

Hermes R2 Vault

IvanIvan86 downloads

Encrypts Obsidian notes locally and publishes them to Cloudflare R2 for Hermes.

Add to Obsidian
  • Overview
  • Scorecard
  • Updates5

Russian version: README.ru.md

Encrypted Obsidian vault with Cloudflare R2 sync.

Client-side encrypted note publishing to Cloudflare R2 via a control API (Hermes VPS). Supports bidirectional sync, revision history, safe deletion, and vault restore.


Architecture

Obsidian vault → client-side encryption (XChaCha20-Poly1305) → Cloudflare R2
                                                       ↕
                                       Hermes control API (VPS)
                                                     ↓
                                   Hermes‑R2‑File‑Resolver (Python)
  • Cloudflare R2 is the only persistent knowledge store.
  • The control API never receives plaintext Markdown content.
  • Plaintext exists only in Obsidian and briefly in plugin memory during encryption.
  • Bidirectional sync with LWW (Last-Writer-Wins) conflict resolution.

Features

Feature Status
Client-side encryption (XChaCha20-Poly1305 + Argon2id) ✅
Bidirectional sync ✅
Content-addressable storage (CAS) for manifests ✅
Multi-device enrollment ✅
Setup URI for device pairing ✅
File revision history ✅
Single-file restore ✅
Point-in-time vault restore ✅
History integrity scanner ✅
Retention planner ✅
Safe garbage collection ✅
Mass deletion protection ✅
Conflict Center UI ✅
Audit log ✅
Russian and English localization ✅

Project Structure

hermes-r2-vault/
├── src/                          # Plugin source code
│   ├── main.ts                   # Entry point, commands, modals
│   ├── sync.ts                   # Sync orchestrator (core)
│   ├── models.ts                 # Interfaces and state types
│   ├── constants.ts              # Constants and defaults
│   ├── crypto.ts                 # XChaCha20-Poly1305, Argon2id, X25519
│   ├── envelope.ts               # Binary envelope with AAD
│   ├── transport.ts              # HTTP client for presigned URLs
│   ├── cas-store-r2.ts           # Content-addressable storage (R2)
│   ├── manifest-snapshot.ts      # Manifest snapshots
│   ├── file-history.ts           # File revision history
│   ├── reference-graph.ts        # Revision reference graph
│   ├── retention-planner.ts      # Retention planner
│   ├── vault-restore.ts          # Vault restore
│   ├── integrity-scanner.ts      # Integrity scanner
│   ├── download.ts               # Download and decrypt
│   ├── conflict-center.ts        # Conflict resolution UI
│   ├── mass-deletion.ts          # Mass deletion protection
│   ├── deletion-metrics.ts       # Deletion counters
│   ├── audit-log.ts              # Event logging
│   ├── fault-handler.ts          # Error handling
│   ├── safety.ts                 # Empty manifest + stale device guards
│   ├── key-envelope.ts           # Key management
│   ├── path-utils.ts             # Path normalization
│   ├── filter.ts                 # File filtering
│   ├── queue.ts                  # Change queue
│   ├── ulid.ts                   # ULID generation
│   ├── settings.ts               # Settings UI
│   ├── log.ts                    # Structured logging
│   ├── errors.ts                 # Typed errors
│   ├── i18n/                     # Internationalization
│   │   └── index.ts              # Russian + English
│   └── protocol/                 # Protocol types
│       ├── manifest.ts           # SyncManifestV1
│       ├── manifest-snapshot.ts  # ManifestSnapshotV1
│       ├── revision.ts           # RevisionMetadataV1
│       ├── tombstone.ts          # TombstoneV1
│       ├── file-history.ts       # FileHistoryIndexV1
│       ├── differ.ts             # Diff + LWW resolution
│       ├── conflict.ts           # Conflict classification
│       ├── validation.ts         # Type validation
│       ├── identifiers.ts        # UUID/ULID validation
│       ├── paths.ts              # Path encoding
│       ├── canonical-json.ts     # Canonical JSON
│       ├── cas-store.ts          # CasStore interface
│       ├── device.ts             # Device metadata
│       ├── device-envelope.ts    # Device key envelope
│       ├── setup-uri.ts          # Setup URI
│       ├── setup-token.ts        # Setup token
│       └── index.ts              # Re-exports
├── tests/                        # Tests (379 tests, Vitest)
│   ├── revision-history.test.ts
│   ├── retention-planner.test.ts
│   ├── vault-restore.test.ts
│   ├── integrity-scanner.test.ts
│   ├── protocol.test.ts
│   ├── deletion-safety.test.ts
│   ├── crypto.test.ts
│   ├── key-envelope.test.ts
│   ├── device-identity.test.ts
│   ├── transport.test.ts
│   ├── queue.test.ts
│   ├── i18n.test.ts
│   ├── differ.test.ts
│   └── ... (21 files)
├── hermes-r2-file-resolver/      # Python resolver (Hermes VPS)
├── docs/                         # Documentation
│   ├── architecture.md
│   ├── sync-protocol-v1.md
│   ├── security-model.md
│   ├── threat-model.md
│   ├── revision-model-v1.md
│   ├── r2-layout-v1.md
│   ├── manifest-v1.md
│   ├── deletion-safety.md
│   └── ... (16 files)
├── package.json
├── tsconfig.json
├── vitest.config.ts
├── build.mjs
└── manifest.json

Installation

  1. Community plugin store (once approved): Settings → Community plugins → Browse → search for "Hermes R2 Vault" → Install → Enable.

  2. Manual install: copy main.js, manifest.json, and styles.css to <vault>/.obsidian/plugins/hermes-rvault/.

  3. Enable the plugin in Obsidian settings.

  4. Configure the API Base URL, Vault ID, and secret names.

  5. Run "Initialize encrypted vault" to generate the master key.

  6. Store the access token via the settings tab (SecretStorage).

  7. Run "Test connection" to verify connectivity.

  8. Run "Run full scan" to upload existing notes.

Note: This plugin is desktop-only. The Obsidian mobile app does not expose the SecretStorage API required for keys and tokens.

Configuration

Plugin settings are available under Hermes R2 Vault Settings in Obsidian settings.

General Settings

Setting Description Default
API Base URL Control API URL (HTTPS) —
Vault ID Vault UUID —
Device ID Device identifier (auto-generated) randomUUID()
Access Token Secret Name SecretStorage key name —
Auto-upload Automatically upload changes false
Debounce delay (ms) Change processing delay 1500
Max concurrent uploads Parallel upload limit 2

Deletion Safety

Setting Description Default
Enable remote trash Keep deleted files in manifest true
Deleted retention (days) Deleted metadata retention period 90
Mass deletion threshold Deletion count threshold 10
Require deletion approval Prompt for confirmation true
Empty manifest protection Block sync on empty remote manifest true
Stale device guard Block stale device sync true
Pre-deletion snapshot Capture hash before deletion false

Revision History

Setting Description Default
Revision history enabled Enable revision history false
Max revisions per file Max revisions per file 100
Max snapshot generations Max snapshot count 50
Revision TTL (days) Revision time-to-live 365
Revision retention (days) Guaranteed retention period 90
Minimum retained revisions Minimum revisions to keep 20

Commands

Command Description
Test connection Verify API connectivity
Initialize encrypted vault Generate vault master key
Recover vault key Recover key from passphrase
Change recovery passphrase Change recovery passphrase
Upload current note Upload active note
Run full scan Full file scan
Pause automatic uploads Pause upload queue
Resume automatic uploads Resume upload queue
Show sync status Display sync status
View sync conflicts Show sync conflicts
Open Conflict Center Open conflict resolution UI
Undo latest deletion Undo last deletion
Purge deleted file Safe permanent purge
Preview retention plan Retention plan preview
Apply retention plan Execute retention GC
List vault restore points List available snapshots
Preview vault restore Preview vault state restore
Scan history integrity Check history integrity
Show deletion safety metrics Display deletion statistics
Show recent faults Show recent fault records
Clear local sync metadata Clear local sync state

Sync Protocol

Full protocol specification: docs/sync-protocol-v1.md.

Protocol version: 1 (marker: docs/protocol-version-v1.json)

Feature Flags

Flag Status
revisionHistory ✅ true
fileRevisionRestore ✅ true
pointInTimeRestore ✅ true
historyIntegrityScan ✅ true
retentionPlanner ✅ true
safeGarbageCollection ✅ true
resumableRestore ✅ true
hermesReadWrite ❌ false

R2 Layout

vaults/{vaultId}/
├── manifests/
│   ├── current.json              # Manifest pointer
│   ├── by-hash/{sha256}.json     # Content-addressable manifests
│   └── snapshots/{generation}.json  # Per-generation snapshots
├── history/
│   ├── manifests/index.v1.json   # Snapshot index
│   └── files/{fileId}/index.v1.json  # File history indices
├── revisions/{fileId}/{revisionId}.hvr  # Immutable revisions
├── tombstones/{fileId}.hvr       # Tombstones
└── config/
    ├── owner-key-envelope.v1.json
    └── recipients/{recipientId}.key-envelope.v1.json

Security

  • Encryption: XChaCha20-Poly1305 with 24-byte nonce
  • KDF: Argon2id (64MB memory, 3 iterations)
  • Key derivation: HKDF-SHA256 (path key, content key)
  • Key exchange: X25519 ECDH
  • Authentication: HMAC-SHA256 for path identity

Details: docs/security-model.md, docs/threat-model.md.

Development

Scripts

Command Description
npm run build Build plugin (esbuild)
npm run test Run tests (Vitest)
npm run test:coverage Coverage report
npm run typecheck TypeScript type check
npm run lint ESLint

Dependencies

  • Runtime: @noble/ciphers, @noble/curves, @noble/hashes
  • Dev: TypeScript, esbuild, Vitest, ESLint, Obsidian API

Python Resolver

The hermes-r2-file-resolver/ subproject implements the protocol in Python for the Hermes VPS backend.

Testing

Before committing:

npm run typecheck   # TypeScript — clean
npm run lint        # ESLint — clean
npm run test        # 379 tests, 21 files
npm run build       # esbuild — success

License

MIT

HealthExcellent
ReviewSatisfactory
About
Encrypt and sync your Obsidian vault to Cloudflare R2 with client-side XChaCha20-Poly1305 and Argon2id key derivation. Use bidirectional sync with Last-Writer-Wins conflict resolution, content-addressable storage, revision history, safe garbage collection, retention planning, integrity scanning and point-in-time recovery.
BackupSyncingIntegrations
Details
Current version
1.0.4
Last updated
2 months ago
Created
2 months ago
Updates
5 releases
Downloads
86
Compatible with
Obsidian 1.8.7+
Platforms
Desktop only
License
Apache-2.0
Report bugRequest featureReport plugin
Author
IvanIvanivana331100
GitHubivana331100
  1. Community
  2. Plugins
  3. Backup
  4. Hermes R2 Vault

Related plugins

Remotely Save

Sync notes between local and cloud with smart conflict: S3, Dropbox, webdav, OneDrive, Google Drive, Box, pCloud, Yandex Disk, Koofr, Azure Blob Storage.

Self-hosted LiveSync

Sync vaults securely to self-hosted servers or WEBRTC.

Fast Note Sync

Real-time sync of your vaults across server, mobile, and web; shareable with anyone; supports REST and MCP integrations to build your personal AI knowledge base.

Google Drive Sync

Syncs a vault into Google Drive for cross-platform use (works for iOS).

YAOS

Simple real-time sync powered by your own Cloudflare Worker.

Sync Engine

The extensible vault synchronization engine: Fast · Free · Reliable. Supports WebDAV, S3, and Google Drive.

Nutstore Sync

Sync your vault with Nutstore (坚果云) using WebDAV protocol.

OneDrive Sync

Sync your Obsidian vault with OneDrive Personal/Consumer

GitHub

GitHub Sync

Sync vault to personal GitHub.

Nextcloud Sync

Bidirectional sync between Obsidian and Nextcloud using hash-based change detection.