| Version | Supported |
|---|---|
| 2.0.x (latest) | ✅ Active |
| 1.x | ✅ Security fixes only |
| 0.x | ❌ Unsupported |
Do not open a public issue. Email security disclosures to:
You will receive a response within 48 hours. Perseus Computing LLC is a US-owned small business and treats security reports as confidential until a fix is published.
- Affected version(s) and build target (Linux, macOS, Windows)
- Steps to reproduce
- Impact assessment (what an attacker could do)
- Any suggested mitigations
- Acknowledgment — within 48 hours
- Triage — severity assessment within 5 business days
- Fix development — timeline depends on severity
- Coordinated disclosure — CVE assigned, fix released, advisory published
We support responsible disclosure and will credit reporters who follow this policy.
Maintainers: the internal process behind these commitments (handler roles, severity rubric, embargo and CVE handling) is documented in
docs/vuln-response.md. For the full map of security documents, the access-privileges register, and the milestones that gate when we escalate security effort, seedocs/SECURITY-INDEX.mdanddocs/SECURITY-MILESTONES.md.
Perseus Vault is a local-first MCP server that stores AI agent memory. It processes:
- Entity CRUD (remember, recall, search, forget)
- Journaling (append-only decision logs)
- State management (key-value with TTL)
- Optional embeddings (Ollama / ONNX Runtime)
- Optional connectors (GitHub issues, file watcher)
Perseus Vault supports AES-256-GCM encryption at rest for entity bodies. It
is enabled by default for fresh installations: the first write to a new
database generates an owner-only standard key (~/.perseus-vault/secret.key)
and establishes the encrypted canary. Existing plaintext databases fail closed
with an actionable init --rekey migration path (or an explicit
PERSEUS_VAULT_ALLOW_PLAINTEXT=1 opt-out). See the full
Encryption Specification
and Threat Model for precise guarantees and limits.
| Property | Detail |
|---|---|
| Algorithm | AES-256-GCM (96-bit random nonce per message; 128-bit tag) |
| Key | Raw 256-bit key from a base64 key file — no passphrase / KDF |
| AAD | category:key binds ciphertext to entity identity (anti-swap) |
| Encryption scope | The entities.body_json field only |
| Encrypted at rest | |
| Encrypted in transit | |
| Key management | Operator responsibility — keys never leave the machine; no escrow, no recovery |
Encryption is on by default for fresh installs — the standard key is
auto-generated at ~/.perseus-vault/secret.key (0o600 on Unix) on first write.
Explicit key management:
perseus-vault keygen # optional; fresh installs auto-create the standard key
perseus-vault --encryption-key ~/.perseus-vault/secret.key # explicit key pathExisting plaintext databases fail closed with an init --rekey migration path
(or explicit PERSEUS_VAULT_ALLOW_PLAINTEXT=1); doctor reports the actual
on-disk state.
⚠️ Body encryption does not make the database file opaque. For keyword search to work, the FTS5 index (entities_fts) stores the body in plaintext, and metadata columns (category, key, tags, workspace, timestamps) are plaintext by design. To keep content unreadable from the file itself, also enable OS-level disk encryption (LUKS / FileVault / BitLocker). On Windows, Perseus Vault does not restrict the key file's ACL — do it yourself. Details in docs/ENCRYPTION.md.
| Vector | Risk | Mitigation |
|---|---|---|
| SQL injection | None | Parameterized queries via rusqlite — no string concatenation |
| Malicious MCP requests | Low | JSON-RPC 2.0 validation; MCP stdio is local-only by default |
| Entity injection (FTS5) | Low | FTS5 uses parameterized queries; inputs are escaped |
| File watcher path traversal | Medium | Paths are canonicalized before watching; only configured directories |
| GitHub connector token exposure | Medium | Token is never logged or stored in the database; memory-only during connector run |
| Embedding model download | Low | Optional; models are downloaded from Ollama or ONNX Runtime's official CDN |
| HTTP transport (axum) | Medium | CORS configured; no authentication by default (local-only intended use) |
- Perseus Vault runs on your machine. It does not phone home. No telemetry.
- MCP transport is local stdio by default. No network exposure unless you enable HTTP transport.
- Connectors are opt-in. GitHub and file watcher connectors are disabled by default.
- Encryption keys are your responsibility. Perseus Vault does not store, transmit, or escrow keys.
| Standard | Status |
|---|---|
| NIST SP 800-53 | Mapping in progress |
| NIST AI RMF | Alignment documented |
| EO 14028 (SBOM) | SBOM published |
| CMMC Level 2 | In progress — encryption, access control, audit trail |
| ITAR | US-owned LLC; all development in US; no foreign nationals on codebase |
- 17 runtime dependencies — all MIT or Apache-2.0 licensed
- Zero copyleft (GPL/AGPL) — safe for government deployment
- SQLite bundled via rusqlite — no system library dependency
- SBOM published at docs/SBOM.md
- We monitor RustSec Advisory Database for crate CVEs
cargo auditrun in CI on every push
cargo audit --deny warnings runs on every push, every PR, and weekly against
the live advisory database (.github/workflows/audit.yml). As of 2026-08-16 the
scan reports 0 vulnerabilities across 438 locked dependencies. Two
unmaintained advisories (informational severity — not exploitable
vulnerabilities) are explicitly accepted, with justification, in that workflow:
| Advisory | Crate | Why it is accepted |
|---|---|---|
| RUSTSEC-2024-0436 | paste 1.0.15 |
Unmaintained, but a proc-macro: it executes only at compile time and adds no runtime attack surface. Reachable only through tokenizers, whose newest release still pins it — no patched version exists. |
| RUSTSEC-2026-0192 | ttf-parser 0.25.1 |
Unmaintained. Compiled only in the opt-in multimodal build (local PDF text extraction via pdf-extract/lopdf); the default binary does not contain it. The newest lopdf release still pins it — no patched version exists. |
Both chains were re-verified against crates.io on 2026-08-16: every crate in
each chain is at its newest release and the newest releases still carry these
crates, so there is currently no upgrade path that removes them. Any new
advisory fails the CI gate immediately; if an upstream chain ever drops one of
these crates, the corresponding ignore in .github/workflows/audit.yml is
removed.
Release binaries carry signed SLSA build provenance (Sigstore-signed, via GitHub Artifact Attestations). After downloading a release archive you can verify it was built by our release workflow from this repository:
gh attestation verify perseus-vault-lite-x86_64-unknown-linux-musl.tar.gz \
--repo Perseus-Computing-LLC/perseus-vaultA successful verification confirms the artifact's provenance (repo, workflow, commit) and that it has not been tampered with since it was built.
Security: perseus@perseus.observer
PGP — encrypt sensitive reports to our security key:
Fingerprint: 92C8 E815 1A60 DB38 46DB 420B 029A 35A6 A22B 287E
Fetch it from keys.openpgp.org
(gpg --keyserver hkps://keys.openpgp.org --recv-keys 92C8E8151A60DB3846DB420B029A35A6A22B287E)
and verify the fingerprint above before use.