v0.5.4.6
v0.5.4.6 — Patch 6: Security Hardening & Governance
12 security vulnerabilities fixed. Zero unsafe impl. Repository governance locked down.
For Everyone
This is a security-focused release. If you're running v0.5.4.5 or earlier, upgrade now.
What changed:
- The HTTP API no longer allows any website to read your memories (CORS fix)
- Bulk delete (
memory_forget) now archives memories before deleting and supportsdry_runto preview what would be deleted - Control characters (ANSI escape codes, backspace, etc.) are now rejected in memory titles and content
- All
unsafecode removed from the memory and search engine
New feature: Memories now support an optional metadata JSON field for storing structured key-value data alongside your memories.
Upgrade:
# Any of these:
brew upgrade ai-memory
cargo install ai-memory
curl -fsSL https://raw.githubusercontent.com/alphaonedev/ai-memory-mcp/main/install.sh | shFor Leadership
Governance hardening:
- Branch protection enabled on all branches (main, develop, release/*)
- CODEOWNERS established — all changes require @alphaonedev approval
- Signed commits required
- CI status checks required (fmt, clippy pedantic, tests, audit on Linux + macOS)
- Self-merge permanently blocked
Security fixes (12):
| # | Severity | What was wrong | What we fixed |
|---|---|---|---|
| CVE x2 | Critical | TLS certificate validation bypass (rustls-webpki) | Patched to 0.103.12 |
| 1 | Critical | HTTP API accepted cross-origin requests from any website | Deny all cross-origin by default |
| 2a | Critical | Unverified unsafe thread-safety on embedding model | Replaced with Mutex |
| 2b | Critical | Same issue on search reranker model | Replaced with Mutex |
| 3 | High | Search queries could exclude results via FTS injection | Stripped +/- operators |
| 4 | High | Bulk delete had no undo, no preview, no archive | Added archive + dry_run |
| 5 | Medium | Memory consolidation silently lost provenance data | Stored in metadata |
| 6 | Medium | Vector search index grew without bound | Capped at 100K entries |
| 7 | Medium | Promote operation bypassed safety checks | Uses proper update path |
| 8 | Medium | Filesystem directory names leaked into database | Disabled |
| 9 | Low | ANSI escape codes accepted in memory content | Rejected |
By the numbers:
- 230 automated tests (173 unit + 57 integration), all pass
- 59 live functional tests, all pass
- 0 vulnerabilities, 0 audit warnings
- 0 unsafe impl in codebase
For Engineers
Security Fixes
CVE: rustls-webpki 0.103.10 (RUSTSEC-2026-0098, RUSTSEC-2026-0099)
Wildcard name constraint bypass and URI name constraint acceptance. Patched via lockfile update to 0.103.12. Additionally, reqwest bumped from 0.11 to 0.12 to eliminate a second copy (0.101.7) that had no patch available.
CORS (Critical): CorsLayer::permissive() → CorsLayer::new(). The previous configuration allowed any website to make authenticated cross-origin requests to the localhost API, enabling CSRF-style attacks to exfiltrate or destroy memories.
unsafe impl Send/Sync (Critical): Both Embedder and CrossEncoder had unsafe impl Send for T {} / unsafe impl Sync for T {} on types containing BertModel. Replaced with Mutex<BertModel> wrapping. The mutex is never contended in practice (MCP server is single-threaded stdio).
FTS Injection (High): sanitize_fts_query now strips + and - prefix operators in addition to the existing "*^{}():| filter. Previously, -secret in a recall query would exclude matching memories from results.
memory_forget (High): Now archives matching memories before deletion (like GC already did). New dry_run parameter returns {"would_delete": N} without executing.
Consolidation provenance (Medium): derived_from links were created then immediately CASCADE-deleted when source memories were removed in the same transaction. Source IDs are now recorded in the consolidated memory's metadata.derived_from array.
HNSW cap (Medium): all_entries vector capped at 100,000. Oldest entries evicted and index rebuilt on overflow. Prevents unbounded memory growth (~150MB at 100K with 384-dim embeddings).
handle_promote (Medium): Raw SQL UPDATE memories SET tier='long', expires_at=NULL replaced with db::update() call that respects tier downgrade protection and title collision checks.
auto_register_path_hierarchy (Medium): Disabled. This function walked the filesystem from cwd upward and wrote directory names into the database as namespace parent relationships, leaking filesystem structure.
Control char validation (Low): is_clean_string expanded from !s.contains('\0') to !s.chars().any(|c| c.is_control() && c != '\n' && c != '\t'). Rejects ANSI escape sequences, backspace, bell, bidirectional overrides.
New Feature: Metadata Column
Memories now have an optional metadata JSON field (Phase 1, Task 1.1):
{"name": "memory_store", "arguments": {
"title": "API endpoint",
"content": "POST /api/v1/users",
"metadata": {"version": 2, "author": "team-a"}
}}Schema migration adds the column automatically. MCP tools support store, update, and recall with metadata. Metadata is validated (must be object, max 64KB, max depth 10).
Governance
Branch protection, CODEOWNERS, signed commits, and CI status checks are now enforced on all protected branches. See issue #170 for full details and SOP.
Full Changelog
fix: update rustls-webpki 0.103.10 -> 0.103.12 (RUSTSEC-2026-0098, RUSTSEC-2026-0099)
fix: bump reqwest 0.11 -> 0.12 (eliminates rustls-webpki 0.101.7)
fix: replace permissive CORS with deny-by-default
fix: remove unsafe impl Send/Sync on Embedder
fix: remove unsafe impl Send/Sync on CrossEncoder
fix: strip +/- prefix operators in FTS query sanitizer
fix: memory_forget archive + dry_run
fix: consolidation provenance via metadata
fix: cap HNSW index at 100K entries
fix: handle_promote uses db::update
fix: disable auto_register_path_hierarchy
fix: reject control characters in stored content
fix: restore rust-version = 1.87
feat: metadata JSON column (Phase 1, Task 1.1)
chore: CODEOWNERS, branch protection, governance
chore: reconcile main/develop divergence
chore: bump version to 0.5.4-patch.6
Package Distribution
| Channel | Install / Upgrade | Status |
|---|---|---|
| Pre-built binary (Linux/macOS) | curl -fsSL https://raw.githubusercontent.com/alphaonedev/ai-memory-mcp/main/install.sh | sh |
✅ Live |
| Pre-built binary (Windows) | irm https://raw.githubusercontent.com/alphaonedev/ai-memory-mcp/main/install.ps1 | iex |
✅ Live |
| Homebrew (macOS + Linux) | brew install alphaonedev/tap/ai-memory |
✅ Live |
| Ubuntu PPA (apt) | sudo add-apt-repository ppa:jbridger2021/ppa && sudo apt install ai-memory |
✅ Live |
| Fedora COPR (dnf) | sudo dnf copr enable alpha-one-ai/ai-memory && sudo dnf install ai-memory |
✅ Live |
| crates.io (cargo) | cargo install ai-memory |
✅ Live |
| cargo-binstall | cargo binstall ai-memory |
✅ Live |
| Docker (GHCR) | docker pull ghcr.io/alphaonedev/ai-memory-mcp:v0.5.4.6 |
✅ Live |
| GitHub Release (binaries + .deb + .rpm) | Download | ✅ Live |
