
Memo, yerel-öncelikli ve gizliliğe saygılı bir güvenlik mimarisi ile tasarlanmıştır.
Tüm sağlayıcı API anahtarları (OpenAI, Anthropic, Google vb.) bekleme durumunda AES-256-GCM ile şifrelenir. Anahtarlar, mümkün olduğunda işletim sistemi anahtar kasasında saklanan makineye özel bir sırdan türetilir; bunun mümkün olmadığı durumlarda kısıtlı izinlere sahip dosya tabanlı bir sırra başvurulur. Anahtarlar hiçbir zaman günlüğe kaydedilmez, dışa aktarılmaz veya düz metin olarak iletilmez.
API sunucusunda IP başına hız sınırlaması için token bucket algoritması uygulanır:
| Uç Nokta | Hız |
|---|---|
/api/chat |
30 istek / dakika |
/api/embeddings |
60 istek / dakika |
| Diğer tüm uç noktalar | 120 istek / dakika |
Patlama kapasitesi sürekli hızın 2 katıdır. API yanıtlarında hız sınırı başlıkları (X-RateLimit-*) bulunur.
filepath.Clean ile temizlenir.413 Request Entity Too Large yanıtı alır.config.yaml, memo.db) 0600 izinleriyle (yalnızca sahibin okuma/yazma) oluşturulur.~/.memo/) 0700 izinleriyle oluşturulur.os.CreateTemp kullanır ve süreç sonlandığında temizlenir.Senkron verileri uçtan uca şifrelidir:
Bir ajan araçları çalıştırdığında:
v3.3.3'ten itibaren, uzaktan erişim (LAN veya ngrok) bağlantısına karşı her istek Ayarlar'da gösterilen erişim token'ını sunmak zorundaydı — öncesinde, o adrese ulaşabilen herkes hiçbir kimlik doğrulaması olmadan sağlayıcı API anahtarlarını okuyabiliyor, veri silebiliyor veya ajan komutları çalıştırabiliyordu. v3.5.5 itibarıyla, o tek-paylaşılan-token şeması, bir Pi/ev sunucusu/VPS/Docker üzerinde self-hosting için inşa edilmiş ama masaüstünde LAN/ngrok/Tailscale Uzaktan Erişim için de aynı şekilde geçerli olan tam bir kimlik doğrulama sistemiyle değiştirildi.
Ayarlar'dan veya memo remote set-mode ile seçilebilir:
| Mod | Gereken kimlik |
|---|---|
none |
Yok — sadece tamamen güvenilir bir özel ağda uygun |
token (loopback dışına bağlandığında varsayılan) |
Cihaz-bazlı bir token, X-Memo-Token header'ı veya Authorization: Bearer |
password |
Kullanıcı adı + argon2id-hash'li şifre, imzalı bir oturum verir |
token_password |
Geçerli bir token ya da geçerli bir şifre, ikisi de çalışır |
Gerçek kaynak IP'si loopback olan bir istek (127.0.0.0/8, ::1) her modda, kimliksiz güveniliyor — bu, isteğin gerçek kaynağına dayanıyor, istemcinin hangi URL'yle konuştuğunu sandığına değil, yani sadece aynı makinede çalışan yazılımı kapsıyor (kurulu masaüstü uygulamasının 127.0.0.1'le konuşması gibi). Aynı fiziksel kutudan bile olsa, LAN IP'sinden gelen bir istek yine normal şekilde kapıdan geçer.
memo remote revoke-device <id>). memo remote rotate-token <id>, hemen çalışmaz hale gelmesi gereken sızmış bir token için, bir token'ı iptal edip aynı cihaz adıyla tek adımda yeniden verir.--password/--key asla düz CLI argümanı olarak gerekmez (ps ile görünür, shell history'de kalır) — boş bırak, ihtiyacı olan her CLI komutu terminalden gizli olarak interaktif sorar.Self-hosted Memo, Ayarlar → Hesaplar'dan yönetilen admin/kullanıcı rolleriyle çoklu hesabı destekler. Uygulamadaki her ekran — sohbet, Ayarlar, Geliştirici Seçenekleri — her ekranın auth durumunu bağımsız takip etmesi yerine aynı ilk-kurulum kapısından ve giriş kapısından geçer.
Uzaktan erişim kapısındaki bir CORS origin-doğrulama açığı (CWE-346), tüm auth yüzeyi üzerinde yapılan düşmanca bir taramada bulunup v3.5.5'te kapatıldı.
Geliştirici API Ağ Geçidi, kendi "API Anahtarı Gerektir" anahtarı etkinken bu aynı auth sistemini paylaşır. Henüz açıkça kapsanmayanlar için (gömülü TLS, bağımsız bir düşmanca sızma testi) bkz. Self-Hosting → Bilinen Sınırlamalar.
govulncheck'in işaretlediği golang.org/x/text (WhatsApp entegrasyonunun profil fotoğrafı sorgusu üzerinden erişilebilen bir sonsuz döngü açığı) ve ilişkili golang.org/x/net bulguları, her iki bağımlılık güncellenerek yamalandı.WhatsApp köprüsü, aynı konuşmadan eş zamanlı mesaj işlemeyi önlemek için bir mutex kullanır; böylece oturum durumunda yarış koşulları engellenir. Mesajlar kuyruğa alınır ve sohbet başına sıralı olarak işlenir.