Each of the eight tour docs (README, DESIGN, docs/CRYPTO, docs/FORMATS, docs/SECURITY, crates/relicario-core/ARCHITECTURE, crates/relicario-cli/ARCHITECTURE, extension/ARCHITECTURE) now declares its scope in a blockquote under its H1 and ends with a single-line "Next:" pointer to the next doc in the canonical reading order: README → DESIGN → CRYPTO → FORMATS → SECURITY → core → cli → extension. Also trimmed README's mid-section "Architecture" stub to a one- paragraph pointer at DESIGN.md (was duplicating cross-codebase content and referencing a non-existent docs/architecture/ tree). Renamed docs/CRYPTO.md's H1 from "Relicario — Architecture" to "Relicario — Crypto Pipeline" to match the file's renamed scope. Spec: docs/superpowers/specs/2026-05-30-doc-structure-redesign-design.md
5.1 KiB
Relicario Security Model
Audience: auditors and curious users. This doc owns the threat model, attacker-scenarios table, device-authentication model, env-var trust surface, and known limitations. Does NOT own: crypto primitive details (see CRYPTO.md), wire formats (see FORMATS.md), or implementation (see ../crates/relicario-core/ARCHITECTURE.md and ../crates/relicario-cli/ARCHITECTURE.md).
Cryptographic Protection
Relicario uses two-factor vault decryption:
- Passphrase — user-memorized, zxcvbn score ≥3 required
- Reference image — JPEG carrying 256-bit secret via DCT steganography
Key derivation: Argon2id (64 MiB memory, 3 iterations, 4 parallelism) Encryption: XChaCha20-Poly1305 (192-bit nonce, 256-bit key)
Manifest Integrity
The manifest (manifest.enc) is encrypted with AEAD, which provides:
- Confidentiality: Contents unreadable without master key
- Integrity: Any modification detected and rejected on decrypt
- Authenticity: Only master key holders can create valid ciphertexts
What AEAD Does NOT Protect
-
Item deletion: An attacker with write access can delete
.encfiles or git-revert commits. The manifest decrypts successfully but won't contain the deleted items. -
Rollback attacks: An attacker can replace
manifest.encwith an older valid version. AEAD accepts any ciphertext created with the key.
Mitigation
Item deletion and rollback are detectable via git history:
git log --oneline items/
For environments where git history could be rewritten (force-push):
- Enable device authentication (commit signing + pre-receive hook)
- Use a git server that rejects non-fast-forward pushes
- Regular backups with
relicario backup export
Device Authentication
When enabled, device authentication provides:
- Commit authorship: All commits signed by registered device keys
- Push access control: Deploy keys managed via Gitea API
- Instant revocation: One command cuts off both signing and push
Enforcement requires deploying the relicario-server pre-receive hook
on the vault remote. The crate provides two subcommands:
relicario-server generate-hook— emits the hook script to install at<repo>/hooks/pre-receiverelicario-server verify-commit <sha>— checks one commit's signature against.relicario/devices.jsonand.relicario/revoked.jsonas of that commit; the hook calls this for every pushed ref
Without the server hook, signed commits provide authorship metadata only — any process with push access can land an unsigned commit, since verification is otherwise advisory.
See docs/superpowers/specs/2026-05-02-device-authentication-design.md.
Access Control
Without device authentication, access control is transport-layer only:
- CLI: SSH key authentication to git remote
- Extension: Git credentials in browser storage
Device registration is optional but recommended for shared vaults.
Configuration env vars
Relicario reads the following environment variables. Each is a trust boundary: an attacker who can set them in the user's environment can influence Relicario's behavior. They are listed here for security reviewers to audit the surface in one place.
User-facing (active in all builds)
| Variable | Purpose | Trust |
|---|---|---|
RELICARIO_IMAGE |
Override the reference-image JPEG path used during vault unlock. | Trusted: filesystem path under the user's control. Read-only; its bytes feed imgsecret::extract_secret. |
RELICARIO_GITEA_URL |
Gitea API base URL for relicario device add. Equivalent to --gitea-url. |
Trusted: HTTPS URL. Used only in the device-add code path. |
RELICARIO_GITEA_TOKEN |
Gitea personal-access token. Equivalent to --gitea-token. |
Secret: anyone who can read this env var can manage the user's deploy keys via the Gitea API. The CLI never logs it. |
RELICARIO_GITEA_OWNER |
Gitea repository owner (e.g. alee). Equivalent to --owner. |
Trusted: opaque string. |
RELICARIO_GITEA_REPO |
Gitea repository name (e.g. vault). Equivalent to --repo. |
Trusted: opaque string. |
Debug-only (compiled out of cargo build --release)
The following variables are gated behind cfg(debug_assertions) and
are no-ops in release builds. The env-var lookup is removed by the
optimiser from any binary built without debug assertions (i.e. the
standard --release profile).
| Variable | Purpose |
|---|---|
RELICARIO_NO_GROUPS_CACHE |
Suppress the plaintext groups.cache write. Developer debugging tool for the cache logic. |
RELICARIO_TEST_PASSPHRASE |
Bypass the rpassword prompt during integration tests. |
RELICARIO_TEST_ITEM_SECRET |
Bypass the rpassword prompt for item-secret fields during integration tests. |
RELICARIO_TEST_BACKUP_PASSPHRASE |
Bypass the rpassword prompt for backup export/restore passphrases during integration tests. |
Next: ../crates/relicario-core/ARCHITECTURE.md — implementation, starting with the platform-agnostic core.