· 9 dakikalık okuma

Güvenli bir DynamoDB MCP sunucusu kurmak ne gerektirdi

, bir veritabanınızı teslim etmeyi son derece kolaylaştırır. Sorun da bu. Çoğu DynamoDB MCP sunucusu, ham AWS kimlik bilgilerinizi tutan, yazma yolu olan ve inceleme adımı bulunmayan ince bir süreçtir — kullanıcı tarafından bu modelin neden riskli olduğu ve nasıl güvenli seçim yapılacağı hakkında yazmıştık.

Bu yazı ise diğer taraf: güvenli sürümü kurmanın gerçekte ne gerektirdiği. DynoTable, MCP sunucusu aracılığıyla, kısıtlı AI araç takımını harici ajanlara — Claude Code, Cursor, Codex — ajan hiçbir zaman AWS kimlik bilgilerine dokunmadan sunan bir masaüstü DynamoDB istemcisidir. Oraya ulaşmak, bir Electron uygulamasının içinde bir yetkilendirme sunucusu yayınlamayı, kimlik bilgisi karışıklıklarını temsil edilemez kılan bir kimlik türü tasarlamayı ve birden fazla kez, kullanışlı olan varsayılanın yanlış olduğuna karar vermeyi gerektirdi.

Hassas herhangi bir şeyin etrafında bir MCP sunucusu kuruyorsanız, bu kararlarla siz de karşılaşacaksınız.

Loopback HTTP otomatik olarak güvenli değildir

Sunucu 127.0.0.1'e bağlanır, ki bu güvenli gibi görünür ama yeterli değildir. Ziyaret ettiğiniz herhangi bir web sayfası localhost'a doğru istekler yapmayı deneyebilir ve DNS rebinding, düşman bir sayfanın bunları makul bir Host ile süslemesine olanak tanır. Dolayısıyla ilk katman bir origin koruyucusudur: gerçek bir web sayfası Origin'i taşıyan her isteği reddet, loopback olmayan Host başlıklarını reddet — ama hiç Origin taşımayan istekleri kabul et, çünkü Claude Code gibi meşru CLI istemcileri hiç göndermez.

O son cümle işin dürüst kısmı: bir origin koruyucusu yalnızca tarayıcı saldırı sınıfını engeller. Kimseyi kimliklendiremez. Gerçek kapı bearer token'dır ve bu da token'ların nereden geldiği sorusunu gündeme getirir.

Uygulamanın içinde bir OAuth 2.1 yetkilendirme sunucusu yayınladık

MCP'nin uzak sunucu kimlik doğrulama hikayesi OAuth 2.1'dir ve yerel bir masaüstü sunucusu için üzerine yaslanacak bir üst kimlik sağlayıcı yoktur. Dolayısıyla uygulamanın kendisi yetkilendirme sunucusudur: dinamik istemci kaydı, (S256), yetkilendirme kodları, refresh token'ları, iptal ve tüm bunları istemcilerin keşfetmesini sağlayan RFC 8414 / RFC 9728 meta veri belgeleri.

Erken belirlediğimiz ve koruduğumuz kurallar:

  • Protokolü elle yazmayın. MCP SDK, tam AS yüzeyini bir router olarak sunar; biz yalnızca onun altındaki depolama/politika sağlayıcısını uygularız. Kabul ettiğimiz bir sonuç: MCP çerçevemiz dahili olarak bir HTTP yığını konuşurken SDK router'ı başka birini konuşuyor, bu yüzden AS ikinci bir loopback dinleyicisi olarak çalışıyor ve kaynak sunucu istemcileri korumalı kaynak meta verisi üzerinden ona yönlendiriyor. İki dinleyici, kapsamı belirli ve açık bir maliyettir; PKCE ile token gramerini elle yeniden türetmek ise sınırsız bir maliyettir.
  • Yönlendirmeler yalnızca loopback'tir (yerel uygulamalar için RFC 8252 uyarınca) ve geçersiz bir yönlendirme asla bir hata yönlendirmesi almaz — doğrudan bir 400 alır, böylece bir saldırganın URI'si asla bir hedef olmaz.
  • Yetkilendirme kodları tek kullanımlıktır — yeniden oynatılan bir kod geçersiz bir grant'tır, nokta.
  • Refresh, kapsamı daraltabilir ama asla genişletemez ve aynı kimlik yükünü kelimesi kelimesine yeniden verir — yenilenmiş bir token sessizce farklı bir bölge edinemez.
  • İptal her istekte yeniden kontrol edilir, bağlantı anında önbelleğe alınmaz — Ayarlar'da "İptal Et"e tıklamak, istemcinin bir sonraki çağrısını öldürür.

Geliştirme derlemeleri bunun yerine, bir sürüm ikilisinde var olamayacak şekilde inşa edilmiş daha basit bir kimlik doğrulama yolu kullanır — yayınlanmış bir yazılımda kimliği doğrulanmamış, tam kapsamlı bir token, kasıtlı olarak Origin'siz istekleri kabul eden bir origin koruyucusunun arkasında yerel bir arka kapı olurdu.

Tek bağlantı, tek AWS kimliği — bütün olarak taşınır, asla tahmin edilmez

Temel güvenlik özelliği: harici bir ajan "DynoTable"a değil, bir profile bağlanır. Her bağlantı tek bir AWS profiline ve tek bir bölgeye bağlıdır ve kendi paylaşılmayan DynamoDB istemcisi ile desteklenir, böylece farklı profillerdeki iki ajan birbirine sızamaz.

Binding, gevşek alanlar olarak başladı — awsProfile, region, profileId, isteğe bağlı bir yerel port — yol boyunca her kayıtta yeniden bildirilerek. Artık iki kollu tek bir ayrık birleşim (discriminated-union) kimlik türü: online (profil + bölge

  • id) ve offline (yerel port + id, DynamoDB Local profilleri için). Çevrimdışı olma durumu, ayırt edicinin kendisidir, bu yüzden kimlik bilgisi olmayan bir çevrimiçi kimlik veya bir bölge taşıyan bir çevrimdışı kimlik, çalışma zamanı sürprizi değil, bir tür hatasıdır. O tek tür, onay → token → grant → her istek boyunca bütün olarak yol alır.
MCP server (tools)User (consent modal)In-app OAuth ASClaude Code / CursorMCP server (tools)User (consent modal)In-app OAuth ASClaude Code / Cursorregister + authorize (PKCE)which profile? which scope?profile P, read-onlycode → token (identity {P, region}pinned)tool call + bearer tokenverify, re-check revocation,clamp scope to license, resolve P's credsresult (agent never sees AWS keys)

Yük taşıyıcı olarak değerlendirdiğimiz iki sonuç:

  • Bölge onay anında dondurulur. Kullanıcı "Y bölgesindeki X profili"ni onaylar ve o demet token'a sabitlenir — refresh'ten sağ çıkar, sıcak yolda asla değişebilir durumdan yeniden çözülmez. Profilin bölgesini düzenlemek yeniden onay gerektirir. Alternatif — bölgeyi istek başına çözmek veya bir varsayılana geri düşmek — bir ajanın sessizce us-east-1'i sorgular hale gelmesinin yoludur.
  • Bozuk token'lar bir 401'dir, asla bir zorlama değil. Bir token'ın kimlik iddiaları geçerli bir kola ayrıştırılamıyorsa, istek yetkisizdir. 'default' profil yok, varsayılan bölge yok, boş dize yok. Eski kodun tahmin edeceği her yer artık kesin bir başarısızlıktır.

Onay bir diyalog kutusu değil, bir ürün yüzeyidir

İlk onay istemi, platformun yerel mesaj kutusuydu. Açıkken Electron ana sürecini donduruyordu, uygulamanın tasarım sistemiyle eşleşemiyordu ve dokümanlar için ekran görüntüsü bile alınamıyordu. Artık uygulama içi bir modal: bağlanan istemcinin adı, kullanıcının açığa çıkarmayı seçtiği tam olarak o profiller üzerinde bir profil seçici ve en dardan başlayarak sunulan üç kapsam — read-only, read + stage, full. Süresi dolmuş veya yinelenen onay istekleri OAuth akışını askıda bırakmak yerine reddedilmiş olarak sonuçlanır.

Uygulama içi MCP onay modalı: bağlanan istemci, profil seçici ve en dardan başlayan üç kapsam — read-only, read + stage ve full erişim.
Uygulama içi MCP onay modalı: bağlanan istemci, profil seçici ve en dardan başlayan üç kapsam — read-only, read + stage ve full erişim.

Seçicinin kendine ait küçük bir güven sınırı vardır: bir istemci, yetkilendirme URL'sinde bir profil önerebilir, ama grant kullanıcının gerçekten seçtiği şeyden üretilir ve kendisine gösterilen anlık görüntüye karşı doğrulanır — sahte bir öneri, ekranda hiç olmayan bir profili bağlayamaz.

Onayın size ne vermediği konusunda da aynı derecede açığız: yetkilendirme yalnızca kapsamdır, bağlantı başına bir kez onaylanır. Uygulama içi asistanın çağrı başına izin istemleri MCP trafiğine uygulanmaz — sızdırılmış tam kapsamlı bir token, her çağrıyı bir insan görmeden (hazırlama alanına) yazabilir. Kısa token ömürleri, istemci başına iptal, her MCP kaynaklı eylemi işaretleyen her zaman açık bir denetim izi ve varsayılan teklif olarak read-only bunun azaltıcılarıdır. Bunu bir kalıntı risk olarak yazmak, onay modalının riski kapattığını iddia etmekten daha yararlıydı.

Başsız çalışma için koruyucu bariyerler

Harici bir ajanın renderer'ı, onay açılır pencereleri veya izleyen bir kullanıcısı yoktur. Etkileşimli olan her şey için başsız bir eşdeğer gerekiyordu:

  • Canlı lisans kısıtlaması, çağrı başına. Grant, kullanıcının onayladığı kapsamı saklar; etkin kapsam, uygulamanın mevcut lisans durumundan her tool çağrısında türetilir — read-only bir lisans, tam bir grant'ı aşağı kısıtlar, oturumu kapatılmış bir durum herhangi bir token koluna girmeden önce 401 ile reddeder (böylece geliştirme token'ı bunu atlayamaz) ve oturum ortasında bir yeniden etkinleştirme, yeniden onay olmadan tekrar genişletir. Kasıtlı bir asimetri: uygulama içi dışa aktarım read-only bir lisans altında kullanılabilir kalır (verileriniz sizin verilerinizdir), ama MCP üzerinden başsız toplu dışa aktarım kısıtlanarak kapatılır — etkileşimli bir taşınabilirlik hakkı ile ajan güdümlü bir dışa akış kanalı farklı güven yüzeyleridir.
  • Onay açılır pencereleri yerine tarama bütçeleri. Uygulamada, tüm tabloyu okuma önce sorar. Başsız olarak, bir öğe/bayt/süre bütçesi her Scan'i sınırlar ve tablolar üzerindeki SQL, bellek içi bir üst sınır yerine diske dayalı bir motor üzerinden akar.
  • Bağlantı kesilmesi dürüstçe iptal eder. İstemci Scan ortasında düşerse, sunucu bir sonraki sayfa sınırında iptal eder — asla ifade ortasında değil — ve geçici durumu temizler.
  • telden tamamlanır. AWS kimlik bilgileri bir MFA koduna ihtiyaç duyduğunda ve istemci MCP elicitation'ı desteklediğinde, sunucu 6 haneli kodu ajanın kendi arayüzü üzerinden elicit eder — Claude Code insana sorar — ve yeniden dener. SSO bu yoldan kasıtlı olarak dışlanmıştır: bir tarayıcı device flow'una ihtiyaç duyar ve aksini iddia etmek yalnızca daha kötü bir hata mesajı olurdu. Aynı kimlik bilgilerine ihtiyaç duyan eşzamanlı çağrılar tek bir istemde birleşir.

Bir veritabanını MCP üzerinden açığa çıkarmak hiç güvenli midir?

Dürüst yanıtımız: yalnızca sunucu, ajanın en iyi ihtimalle kafası karışık, en kötü ihtimalle düşman olduğu varsayımı etrafında tasarlanmışsa. , bir ajanın niyetini güvenilmez kılar, bu yüzden mimari asla ajanın uslu davranmasına güvenmez: kimlik bilgileri uygulamada kalır, yazmalar yalnızca incelenebilir bir hazırlama alanına iner, kapsamlar modelin ne istediğine bakılmaksızın bir çağrının ne yapabileceğini kısıtlar ve her eylem denetlenir. Bağlantı tarafı kılavuzu, bunun her istemci için pratikte ne anlama geldiğini kapsar.

Veritabanınıza dokunan herhangi bir MCP sunucusundan ne talep etmeli

  • Kimlik bilgileri nerede yaşıyor — ajanın sürecinde mi, yoksa sunucunun arkasında mı?
  • Gerçek kapsamlarla bağlantı başına onay var mı, yoksa tek bir yapılandırma dosyası her şeyi mi veriyor?
  • Bir yazma, bir insan inceleme adımı olmadan yürütülebilir mi?
  • Kimlik (profil, bölge) onay anında mı sabitleniyor, yoksa çağrı anında varsayılanlardan mı çözülüyor?
  • Bozuk veya iptal edilmiş bir token'da ne olur — kesin bir başarısızlık mı, yoksa bir geri düşüş mü?
  • Ajan kaynaklı eylemleri ayırt eden bir denetim izi var mı?
  • Kontrolden çıkmış bir Scan'i ne sınırlar ve istemci işlem ortasında bağlantıyı kestiğinde ne olur?

Bir sunucu bunları yanıtlayamıyorsa, kullanışlı entegrasyon riskli olanıdır. Sınırsız bir Scan'in size gerçekte neye mal olacağını boyutlandırmak için fiyatlandırma hesaplayıcısı ayıltıcıdır — ve güvenli sürümü okumaktansa çalışırken görmeyi tercih ederseniz, DynoTable'ı indirin, MCP sunucusunu açın ve bir dakikadan kısa sürede bir istemciyi read-only kapsamda bağlayın.

Console olmadan DynamoDB ile çalışın

DynoTable, DynamoDB için hızlı bir masaüstü istemcisidir — tablolara göz atın, SQL tarzı sorgular çalıştırın ve item'ları yerel olarak düzenleyin.