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:
|
A git repository containing:
|
||||||
- `manifest.enc` — opaque binary blob
|
- `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/salt` — a random 32-byte value (not secret)
|
||||||
- `.relicario/params.json` — Argon2id parameters (not secret)
|
- `.relicario/params.json` — Argon2id parameters (not secret)
|
||||||
- `.relicario/devices.json` — authorized device public keys
|
- `.relicario/devices.json` — authorized device public keys
|
||||||
@@ -114,12 +116,23 @@ relicario/
|
|||||||
│ ├── relicario-core/ # Platform-agnostic library (no filesystem, no network)
|
│ ├── relicario-core/ # Platform-agnostic library (no filesystem, no network)
|
||||||
│ │ ├── crypto.rs # Argon2id KDF + XChaCha20-Poly1305 AEAD
|
│ │ ├── crypto.rs # Argon2id KDF + XChaCha20-Poly1305 AEAD
|
||||||
│ │ ├── imgsecret.rs # DCT steganography: embed/extract 256-bit secrets in JPEGs
|
│ │ ├── imgsecret.rs # DCT steganography: embed/extract 256-bit secrets in JPEGs
|
||||||
│ │ ├── entry.rs # Entry, Manifest data model (serde)
|
│ │ ├── item.rs # Item, Field, Manifest data model (serde)
|
||||||
│ │ └── vault.rs # Encrypt/decrypt entries and manifests
|
│ │ ├── item_types/ # Per-type cores (Login, SecureNote, Card, Identity, Key, Document, Totp)
|
||||||
│ └── relicario-cli/ # CLI binary: filesystem, git, terminal I/O
|
│ │ ├── 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/
|
└── docs/
|
||||||
|
├── ARCHITECTURE.md # System overview + flow diagrams
|
||||||
|
├── SECURITY.md # Manifest integrity model + threat notes
|
||||||
|
├── architecture/ # Cross-codebase + per-codebase architecture docs
|
||||||
└── superpowers/
|
└── 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).
|
`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/
|
my-vault.git/
|
||||||
├── manifest.enc # Encrypted entry index (names, URLs, timestamps)
|
├── manifest.enc # Encrypted item index (names, URLs, timestamps)
|
||||||
├── entries/
|
├── settings.enc # Encrypted vault settings (retention, caps, generator defaults)
|
||||||
│ ├── a1b2c3d4.enc # One encrypted entry per file
|
├── items/
|
||||||
│ └── e5f6a7b8.enc
|
│ ├── a1b2c3d4e5f6a7b8.enc # One encrypted item per file
|
||||||
|
│ └── …
|
||||||
|
├── attachments/
|
||||||
|
│ └── <item-id>/
|
||||||
|
│ └── <aid>.enc # Content-addressed encrypted attachment blob
|
||||||
└── .relicario/
|
└── .relicario/
|
||||||
├── salt # 32-byte random salt (not secret)
|
├── salt # 32-byte random salt (not secret)
|
||||||
├── params.json # KDF parameters
|
├── 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
|
## Device management
|
||||||
|
|
||||||
@@ -183,13 +201,17 @@ The binary is at `target/release/relicario`.
|
|||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
- [ ] WASM build + Chrome browser extension (inline crypto, no native messaging)
|
- [x] WASM build + Chrome MV3 browser extension (inline crypto, no native messaging)
|
||||||
- [ ] Secure notes (free-form encrypted text entries)
|
- [x] Firefox WebExtension build
|
||||||
- [ ] Secure document storage (encrypted file attachments up to 5-10 MB)
|
- [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)
|
- [ ] `relicario unlock` daemon (ssh-agent-style, holds master key for a TTL)
|
||||||
- [ ] Android/iOS clients (Rust core compiles to ARM)
|
- [ ] Android/iOS clients (Rust core compiles to ARM)
|
||||||
- [ ] Import from LastPass/Bitwarden/1Password
|
- [ ] Safari extension
|
||||||
- [ ] Firefox/Safari extensions
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -42,15 +42,19 @@
|
|||||||
┌──────────────────────────────────────────────────────────────────┐
|
┌──────────────────────────────────────────────────────────────────┐
|
||||||
│ GIT SERVER (untrusted) │
|
│ GIT SERVER (untrusted) │
|
||||||
│ │
|
│ │
|
||||||
│ relicario-vault.git/ │
|
│ relicario-vault.git/ │
|
||||||
│ ├── manifest.enc ← opaque ciphertext │
|
│ ├── manifest.enc ← opaque ciphertext │
|
||||||
│ ├── entries/ │
|
│ ├── settings.enc ← opaque ciphertext │
|
||||||
│ │ ├── a1b2c3d4.enc ← opaque ciphertext │
|
│ ├── items/ │
|
||||||
│ │ └── e5f6a7b8.enc ← opaque ciphertext │
|
│ │ ├── a1b2c3d4e5f6a7b8.enc ← opaque ciphertext │
|
||||||
│ └── .relicario/ │
|
│ │ └── … │
|
||||||
|
│ ├── attachments/ │
|
||||||
|
│ │ └── <item-id>/<aid>.enc ← opaque ciphertext │
|
||||||
|
│ └── .relicario/ │
|
||||||
│ ├── salt ← 32 bytes (not secret) │
|
│ ├── salt ← 32 bytes (not secret) │
|
||||||
│ ├── params.json ← KDF params (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, │
|
│ The server sees NOTHING useful. No keys, no plaintext, │
|
||||||
│ no metadata about what's inside. │
|
│ no metadata about what's inside. │
|
||||||
@@ -217,21 +221,23 @@ Input JPEG (possibly re-encoded or cropped)
|
|||||||
│ uses
|
│ uses
|
||||||
▼
|
▼
|
||||||
┌────────────────────────────────────────────────────────────┐
|
┌────────────────────────────────────────────────────────────┐
|
||||||
│ relicario-core │
|
│ relicario-core │
|
||||||
│ Platform-agnostic: bytes in, bytes out │
|
│ Platform-agnostic: bytes in, bytes out │
|
||||||
│ No filesystem, no network, no git │
|
│ No filesystem, no network, no git │
|
||||||
│ │
|
│ │
|
||||||
│ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌────────────┐ │
|
│ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌────────────┐ │
|
||||||
│ │ crypto │ │ imgsecret│ │ entry │ │ vault │ │
|
│ │ crypto │ │ imgsecret│ │ item + │ │ vault │ │
|
||||||
│ │ │ │ │ │ │ │ │ │
|
│ │ │ │ │ │ types │ │ │ │
|
||||||
│ │ KDF │ │ DCT │ │ Entry │ │ encrypt_ │ │
|
│ │ KDF │ │ DCT │ │ Item │ │ encrypt_ │ │
|
||||||
│ │ encrypt │ │ embed │ │ Manifest│ │ entry() │ │
|
│ │ encrypt │ │ embed │ │ Manifest│ │ item() │ │
|
||||||
│ │ decrypt │ │ extract │ │ search │ │ decrypt_ │ │
|
│ │ decrypt │ │ extract │ │ Settings│ │ decrypt_ │ │
|
||||||
│ │ │ │ QIM │ │ │ │ manifest() │ │
|
│ │ │ │ QIM │ │ Backup │ │ manifest() │ │
|
||||||
│ └──────────┘ └──────────┘ └─────────┘ └────────────┘ │
|
│ │ │ │ │ │ Device │ │ ... │ │
|
||||||
|
│ └──────────┘ └──────────┘ └─────────┘ └────────────┘ │
|
||||||
│ │
|
│ │
|
||||||
│ Future: relicario-wasm wraps this for browser extension │
|
│ Consumed by: relicario-cli, relicario-wasm (extension), │
|
||||||
│ Future: JNI/Swift wrappers for Android/iOS │
|
│ 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 |
|
| 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 |
|
| 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 |
|
| Item IDs are random 16-char hex (64 bits) | `core/ids.rs` | Stable, short, no information leak |
|
||||||
| Attachment IDs are content-addressed (SHA-256) | `core/ids.rs` | Dedup; integrity check |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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