docs: refresh README, ARCHITECTURE, overview for current state
Apply trivial-fix findings from the 2026-05-02 doc audit: - README: items/ vs entries/, settings.enc + attachments/ + revoked.json in vault layout, full crate tree (relicario-wasm + relicario-server + typed-items modules), 16-char hex IDs, roadmap reflects shipped trains - ARCHITECTURE.md: git-server box reflects items/ + 16-char IDs; relicario-core inner box lists typed-items modules - architecture/overview.md: ID width / 128-bit AttachmentId 8 deeper findings still proposed for v0.5.0 release prep. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
54
README.md
54
README.md
@@ -33,7 +33,9 @@ To unlock the vault, you provide your passphrase and point the client at the ref
|
||||
|
||||
A git repository containing:
|
||||
- `manifest.enc` — opaque binary blob
|
||||
- `entries/*.enc` — more opaque binary blobs
|
||||
- `items/*.enc` — more opaque binary blobs
|
||||
- `attachments/<item-id>/*.enc` — encrypted attachment blobs
|
||||
- `settings.enc` — encrypted vault settings
|
||||
- `.relicario/salt` — a random 32-byte value (not secret)
|
||||
- `.relicario/params.json` — Argon2id parameters (not secret)
|
||||
- `.relicario/devices.json` — authorized device public keys
|
||||
@@ -114,12 +116,23 @@ relicario/
|
||||
│ ├── relicario-core/ # Platform-agnostic library (no filesystem, no network)
|
||||
│ │ ├── crypto.rs # Argon2id KDF + XChaCha20-Poly1305 AEAD
|
||||
│ │ ├── imgsecret.rs # DCT steganography: embed/extract 256-bit secrets in JPEGs
|
||||
│ │ ├── entry.rs # Entry, Manifest data model (serde)
|
||||
│ │ └── vault.rs # Encrypt/decrypt entries and manifests
|
||||
│ └── relicario-cli/ # CLI binary: filesystem, git, terminal I/O
|
||||
│ │ ├── item.rs # Item, Field, Manifest data model (serde)
|
||||
│ │ ├── item_types/ # Per-type cores (Login, SecureNote, Card, Identity, Key, Document, Totp)
|
||||
│ │ ├── attachment.rs # Encrypted attachment helpers (content-addressed)
|
||||
│ │ ├── settings.rs # VaultSettings (retention, generator defaults, caps)
|
||||
│ │ ├── backup.rs # `.relbak` encrypted-backup envelope
|
||||
│ │ ├── device.rs # ed25519 device keys + revocation entries
|
||||
│ │ └── vault.rs # Encrypt/decrypt items, manifest, settings
|
||||
│ ├── relicario-cli/ # CLI binary: filesystem, git, terminal I/O
|
||||
│ ├── relicario-wasm/ # Thin wasm-bindgen wrapper for the browser extension
|
||||
│ └── relicario-server/ # Pre-receive hook: device-signature verification
|
||||
├── extension/ # Chrome MV3 / Firefox WebExtension (TypeScript)
|
||||
└── docs/
|
||||
├── ARCHITECTURE.md # System overview + flow diagrams
|
||||
├── SECURITY.md # Manifest integrity model + threat notes
|
||||
├── architecture/ # Cross-codebase + per-codebase architecture docs
|
||||
└── superpowers/
|
||||
└── specs/ # Design specification with full threat model
|
||||
└── specs/ # Design specifications with full threat model
|
||||
```
|
||||
|
||||
`relicario-core` takes bytes and returns bytes. It has no knowledge of filesystems, git, or networks. This makes it portable to WASM (browser extension), Android (JNI), and iOS (Swift bridge).
|
||||
@@ -144,17 +157,22 @@ Every write generates a fresh random nonce. The version byte allows future forma
|
||||
|
||||
```
|
||||
my-vault.git/
|
||||
├── manifest.enc # Encrypted entry index (names, URLs, timestamps)
|
||||
├── entries/
|
||||
│ ├── a1b2c3d4.enc # One encrypted entry per file
|
||||
│ └── e5f6a7b8.enc
|
||||
├── manifest.enc # Encrypted item index (names, URLs, timestamps)
|
||||
├── settings.enc # Encrypted vault settings (retention, caps, generator defaults)
|
||||
├── items/
|
||||
│ ├── a1b2c3d4e5f6a7b8.enc # One encrypted item per file
|
||||
│ └── …
|
||||
├── attachments/
|
||||
│ └── <item-id>/
|
||||
│ └── <aid>.enc # Content-addressed encrypted attachment blob
|
||||
└── .relicario/
|
||||
├── salt # 32-byte random salt (not secret)
|
||||
├── params.json # KDF parameters
|
||||
└── devices.json # Authorized device public keys
|
||||
├── devices.json # Authorized device public keys
|
||||
└── revoked.json # Revoked device records (when device auth is enabled)
|
||||
```
|
||||
|
||||
Entry IDs are random hex strings. Git history is preserved — every add/edit/delete is a commit. "When was this password last rotated?" is answered by `git log`.
|
||||
Item IDs are random 16-char hex strings (64 bits of entropy). Git history is preserved — every add/edit/delete is a commit. "When was this password last rotated?" is answered by `git log` and by the per-item field history.
|
||||
|
||||
## Device management
|
||||
|
||||
@@ -183,13 +201,17 @@ The binary is at `target/release/relicario`.
|
||||
|
||||
## Roadmap
|
||||
|
||||
- [ ] WASM build + Chrome browser extension (inline crypto, no native messaging)
|
||||
- [ ] Secure notes (free-form encrypted text entries)
|
||||
- [ ] Secure document storage (encrypted file attachments up to 5-10 MB)
|
||||
- [x] WASM build + Chrome MV3 browser extension (inline crypto, no native messaging)
|
||||
- [x] Firefox WebExtension build
|
||||
- [x] Typed items: Login, SecureNote, Identity, Card, Key, Document, TOTP
|
||||
- [x] Secure document storage (encrypted file attachments)
|
||||
- [x] Backup & restore (`.relbak` encrypted envelope)
|
||||
- [x] LastPass CSV import
|
||||
- [x] Device authentication (ed25519 commit signing + pre-receive hook)
|
||||
- [ ] Import from Bitwarden / 1Password
|
||||
- [ ] `relicario unlock` daemon (ssh-agent-style, holds master key for a TTL)
|
||||
- [ ] Android/iOS clients (Rust core compiles to ARM)
|
||||
- [ ] Import from LastPass/Bitwarden/1Password
|
||||
- [ ] Firefox/Safari extensions
|
||||
- [ ] Safari extension
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -44,13 +44,17 @@
|
||||
│ │
|
||||
│ relicario-vault.git/ │
|
||||
│ ├── manifest.enc ← opaque ciphertext │
|
||||
│ ├── entries/ │
|
||||
│ │ ├── a1b2c3d4.enc ← opaque ciphertext │
|
||||
│ │ └── e5f6a7b8.enc ← opaque ciphertext │
|
||||
│ ├── settings.enc ← opaque ciphertext │
|
||||
│ ├── items/ │
|
||||
│ │ ├── a1b2c3d4e5f6a7b8.enc ← opaque ciphertext │
|
||||
│ │ └── … │
|
||||
│ ├── attachments/ │
|
||||
│ │ └── <item-id>/<aid>.enc ← opaque ciphertext │
|
||||
│ └── .relicario/ │
|
||||
│ ├── salt ← 32 bytes (not secret) │
|
||||
│ ├── params.json ← KDF params (not secret) │
|
||||
│ └── devices.json ← device public keys (not secret) │
|
||||
│ ├── devices.json ← device public keys (not secret) │
|
||||
│ └── revoked.json ← revoked device records (not secret) │
|
||||
│ │
|
||||
│ The server sees NOTHING useful. No keys, no plaintext, │
|
||||
│ no metadata about what's inside. │
|
||||
@@ -222,16 +226,18 @@ Input JPEG (possibly re-encoded or cropped)
|
||||
│ No filesystem, no network, no git │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌────────────┐ │
|
||||
│ │ crypto │ │ imgsecret│ │ entry │ │ vault │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ KDF │ │ DCT │ │ Entry │ │ encrypt_ │ │
|
||||
│ │ encrypt │ │ embed │ │ Manifest│ │ entry() │ │
|
||||
│ │ decrypt │ │ extract │ │ search │ │ decrypt_ │ │
|
||||
│ │ │ │ QIM │ │ │ │ manifest() │ │
|
||||
│ │ crypto │ │ imgsecret│ │ item + │ │ vault │ │
|
||||
│ │ │ │ │ │ types │ │ │ │
|
||||
│ │ KDF │ │ DCT │ │ Item │ │ encrypt_ │ │
|
||||
│ │ encrypt │ │ embed │ │ Manifest│ │ item() │ │
|
||||
│ │ decrypt │ │ extract │ │ Settings│ │ decrypt_ │ │
|
||||
│ │ │ │ QIM │ │ Backup │ │ manifest() │ │
|
||||
│ │ │ │ │ │ Device │ │ ... │ │
|
||||
│ └──────────┘ └──────────┘ └─────────┘ └────────────┘ │
|
||||
│ │
|
||||
│ Future: relicario-wasm wraps this for browser extension │
|
||||
│ Future: JNI/Swift wrappers for Android/iOS │
|
||||
│ Consumed by: relicario-cli, relicario-wasm (extension), │
|
||||
│ relicario-server (pre-receive hook). │
|
||||
│ Future: JNI/Swift wrappers for Android/iOS. │
|
||||
└────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
|
||||
@@ -177,8 +177,8 @@ Core tests use **fast Argon2id params** (m=256, t=1, p=1) so they don't take for
|
||||
|---|---|---|
|
||||
| Master key only in `Zeroizing<[u8;32]>` | core types; CLI follows; extension WASM follows | Drop-on-scope-exit zeroization; never leaves stack |
|
||||
| AEAD ciphertext starts with version byte | `core/crypto.rs` | Format identification; reject v1 blobs cleanly |
|
||||
| Item IDs are random 8-char hex | `core/ids.rs` | Stable, short, no information leak |
|
||||
| Attachment IDs are content-addressed (SHA-256) | `core/ids.rs` | Dedup; integrity check |
|
||||
| Item IDs are random 16-char hex (64 bits) | `core/ids.rs` | Stable, short, no information leak |
|
||||
| Attachment IDs are content-addressed (first 32 hex chars / 128 bits of SHA-256) | `core/ids.rs` | Dedup; integrity check |
|
||||
| KDF input is length-prefixed | `core/crypto.rs` | Prevents `passphrase || image_secret` collisions |
|
||||
| Git history is preserved as audit log; never squash | CLI commits; SW commits | Per-action history is a feature |
|
||||
| Per-action git commits with structured messages | `cli` (via `commit_paths`); SW (via vault.ts helpers) | Greppable, useful as audit log |
|
||||
|
||||
Reference in New Issue
Block a user