فاز 13 · درس 30

امنیت زنجیره تأمین در رجیستری MCP: پذیرش، انحراف و بازگردانی

نوع
ساختنی
زمان
حدود 90 دقیقه
زبان‌ها
Python
پیش‌نیاز
فاز 13 · 17 (گیت‌وی‌ها و رجیستری‌ها)، فاز 13 · 18 (احراز هویت در محیط پروداکشن)
یک گیت بازرسی دیجیتال با سنسورهای اسکن بارکد و محفظه ایزوله شفاف برای بررسی بسته‌های داده قبل از ورود به خط تولید
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. رجیستری یک نمایه است، نه سیستم تأیید شما
  4. هفت کنترل در یک تصمیم پذیرش
  5. 1. اعتبارسنجی فضای نام
  6. 2. الحاق منشأ و سندیت
  7. 3. پین کردن تصمیم، نه فقط نسخه
  8. 4. شناسایی انحراف در محیط زنده
  9. 5. وضعیت رجیستری، یک حالت زنده است
  10. 6. بازگردانی یعنی بازیابی مسیر
  11. 7. ثبت در دفترکل پذیرش
  12. ساخت کنترلر
  13. استفاده از کنترلر
  14. کارگاه تعاملی
  15. کارگاه الف: تداخل فضای نام
  16. کارگاه ب: انحراف توصیف‌گر
  17. کارگاه ج: وضعیت و بازگردانی
  18. تمرین عملی
  19. خروجی این درس
  20. بررسی صحت کار
  21. حالت‌های شکست در پروداکشن
  22. اصل عملیاتی
  23. برای مطالعه‌ی بیشتر

در معماری سیستم‌های مبتنی بر پروتکل بافتار مدل (MCP)، دسترسی به ابزارها معمولاً از طریق رجیستری‌های عمومی یا سازمانی آغاز می‌شود. اعتماد کورکورانه به این که یک سرور در رجیستری نمایه شده یا اسمی شبیه به بسته‌های معتبر دارد، خطر حملات زنجیره‌ی تأمین (Supply Chain Attacks) و تغییر ناگهانی ابزارهای اجرایی را به شدت افزایش می‌دهد. در محیط پروداکشن، یک ورودیِ نمایه صرفاً ادعای ناشر است و تضمینی برای رفتار واقعی یا ایمنی آن در زیرساخت شما نیست.

این درس به توسعه‌دهندگان نشان می‌دهد چگونه با ایجاد یک کنترلر پذیرش (Admission Controller)، مرزهای اعتبارسنجی را از انتشار در رجیستری تا اجرای زنده جدا کنند. با استفاده از پین کردن هش‌ها، ارزیابی دقیق فضای نام و بررسی پویای انحراف در محیط اجرا (Runtime Drift)، مطمئن می‌شوید که هیچ ابزاری بدون ارزیابی خط‌مشی‌های امنیتی وارد جریان داده مدل‌ها نمی‌شود و در صورت بروز مشکل نیز یک مسیر بازگردانی کاملاً قابل اتکا و حسابرسی‌شده وجود دارد.

مدخل رجیستری فقط می‌گوید ناشر چه ادعایی کرده است. پذیرش پروداکشن ثابت می‌کند چه چیزی دریافت کرده‌اید، چه چیزی مشاهده کرده‌اید، چه چیزی را تأیید کرده‌اید و چه چیزی را می‌توانید با خیال راحت بازگردانید.

اهداف یادگیری

  • تفکیک انتشار در رجیستری (Registry)، منشأ و سندیت پکیج (Package Provenance)، کشف در محیط اجرا (Runtime Discovery) و تأیید محلی.
  • اعتبارسنجی فضای نام (Namespace) سرور MCP بدون اعتماد به نامِ ثبت‌شده در خودِ رکورد.
  • پین کردن شواهد تغییرناپذیر انتشار، منبع اجرا، منشأ و سندیت، و توصیف‌گر زنده.
  • شناسایی تغییرات وضعیت در رجیستری و انحراف محیط اجرا (Runtime Drift) پس از پذیرش.
  • بازگردانی (Rollback) مسیریابی به نسخه‌ای که قبلاً پذیرفته شده، بدون بازنویسی تاریخچه.
  • نگهداری یک دفترکل پذیرش ضد‌دستکاری (Tamper-Evident) که تک‌تک تصمیم‌ها را مستند و توجیه کند.

صورت مسئله

شما com.example/inventory را در یک رجیستری پیدا می‌کنید. توضیحاتش درست به نظر می‌رسد. پکیج آن موجود است. سرور به server/discover پاسخ می‌دهد.

این یک واقعیت واحد نیست؛ زنجیره‌ای از واقعیت‌ها از مراجع مختلف است:

  1. ناشری که هویتش برای یک فضای نام احراز شده، رکوردی ثبت کرده است.
  2. رجیستری پکیج، آرتیفکتی با شناسه و دایجست (Digest) مشخص ارائه داده است.
  3. یک اندپوینت در حال اجرا، نسخه‌ی پروتکل، قابلیت‌ها، ابزارها و اطلاعات تشخیصی سرور را گزارش داده است.
  4. سازمان شما تصمیم گرفته که این ترکیب دقیق مجاز است.

خلاصه کردن این واقعیت‌ها در «چون در رجیستری است، پس قابل اعتماد است»، نقطه‌ی کوری در زنجیره‌ی تأمین شما می‌سازد. یک انتشار معتبر همچنان ممکن است منسوخ (Deprecated) شده باشد. اگر دایجست یک پکیج را پین نکنید، تگ آن ممکن است به آرتیفکت غیرمنتظره‌ای اشاره کند. یک سرور ممکن است پس از بازبینی، ابزاری مخرب اضافه کند. یک فرایند بازگردانی ممکن است بی‌سر‌و‌صدا نسخه‌ای را انتخاب کند که هرگز پذیرش نشده است.

راه‌حل، استفاده از یک کنترلر پذیرش (Admission Controller) همراه با ارائه‌ی شواهد در تک‌تک این مرزها است.

رجیستری یک نمایه است، نه سیستم تأیید شما

رجیستری رسمی MCP متادیتای سرور را ذخیره می‌کند. رکورد server.json نام نسخه‌ی سرور را مشخص کرده و یک یا چند پکیج یا اندپوینت راه‌دور را اعلام می‌کند. قواعد انتشار شامل احراز هویت فضای نام، بررسی مالکیت پکیج، قوانین محدودکننده‌ی رجیستری و جایگاهی مشخص و محدود برای متادیتای ناشر است.

این کنترل‌ها به سؤالات حوزه‌ی انتشار پاسخ می‌دهند؛ اما این خط‌مشی پروداکشن شماست که به سؤالات مربوط به استقرار پاسخ می‌دهد:

مرز سؤال مالک شواهد
فضای نام آیا ناشر مجاز به استفاده از این نام بود؟ احراز هویت رجیستری به همراه ورودی فضای نام تأییدشده‌ی شما
رکورد ناشر برای این نسخه چه چیزی اعلام کرده بود؟ دایجست تغییرناپذیر server.json
منبع اجرا کدام پکیج یا اندپوینت راه‌دور اجرا خواهد شد؟ فیلدهای منبع اعلام‌شده، نتیجه‌ی مالکیت تأییدشده، بستر انتقال و دایجست معتبر
محیط اجرا اندپوینت در حال حاضر چه مواردی را ارائه می‌دهد؟ server/discover و توصیف‌گرهای ابزار
پذیرش آیا خط‌مشی شما دقیقاً این مجموعه را تأیید کرده است؟ پین محلی و مدخل دفترکل
عملیات آیا هنوز ایمن است و چه چیزی می‌تواند جایگزین آن شود؟ بررسی‌های انحراف، همگام‌سازی وضعیت، بررسی سلامت و مسیر بازگردانی

نسخه‌ی اسکیمای رجیستری و نسخه‌ی پروتکل MCP مستقل از یکدیگرند. ممکن است یک رکورد از اسکیمای سرورِ منتشرشده‌ی 2025-12-11 استفاده کند، در حالی که سرور زنده از نسخه‌ی 2026-07-28 پروتکل MCP پشتیبانی می‌کند. هرگز یکی را از روی دیگری استنتاج نکنید.

هفت کنترل در یک تصمیم پذیرش

1. اعتبارسنجی فضای نام

نام‌ها در رجیستری رسمی از فضاهای نام احراز هویت‌شده استفاده می‌کنند. یک دامنه‌ی تأییدشده می‌تواند به یک پیشوند دامنه‌ی معکوس نگاشت شود. برای مثال، کنترل دامنه‌ی example.com می‌تواند فضای نام com.example/* را تثبیت کند.

بررسی پیشوند رشته‌ای را قبول نکنید:

server_name.startswith("com.example")

این مقایسه com.exampleevil/tool را هم می‌پذیرد. نام را بر اساس کاراکتر / بشکنید، وجود یک اسلاگ (Slug) غیرخالی را الزامی کنید و بخش فضای نام را دقیقاً بسنجید. مهم‌تر از همه، فضای نام تأییدشده را از نتیجه‌ی احراز هویت به فرایند پذیرش منتقل کنید؛ به داده‌های رکوردی که هنوز قابل اعتماد نیست تکیه نکنید.

فضاهای نام مبتنی بر GitHub و مبتنی بر دامنه، مسیرهای احراز هویت متفاوتی دارند. هر دو مسیر را در قالب یک ورودی واحد برای پذیرش یکپارچه کنید: رشته‌ی دقیق فضای نامِ تأییدشده.

2. الحاق منشأ و سندیت

در مورد رکورد یک پکیج، اطلاعات اعلام‌شده و آرتیفکت دریافت‌شده باید بر اساس فیلدهای صریح به یکدیگر ملحق شوند:

  • نوع رجیستری پکیج
  • شناسه‌ی پکیج
  • نسخه‌ی پکیج
  • نتیجه‌ی مالکیت تأییدشده
  • دایجست آرتیفکت دانلودشده

همچنین بستر انتقالِ اعلام‌شده برای پکیج را اعتبارسنجی کنید. رکوردی که فقط یک اندپوینت راه‌دور دارد کاملاً معتبر است و نباید به خاطر نداشتن پکیج رد شود. برای یک منبع راه‌دور، URL و نوع بستر انتقالِ اعلام‌شده را به مالکیتِ مستقل و تأییدشده‌ی اندپوینت و دایجستِ شواهد اتصال یا استقرار مطمئن ملحق کنید.

کد این درس از هر دو نوع منبع پشتیبانی می‌کند و منبع انتخاب‌شده را همراه با منبع رجیستری، نام سرور، نسخه‌ی رجیستری، دایجست رکورد و دایجست شواهد هش می‌کند. دایجستِ منشأ و سندیتِ حاصل، ارجاعی فشرده به کل مجموعه‌ی شواهد است، اما جایگزین نگهداری خودِ شواهد نیست.

هرگز دایجستی را که صرفاً خودِ آرتیفکتِ در حال بررسی ارائه کرده نپذیرید. آن را در مرزِ یک دریافتِ مطمئن محاسبه کنید یا از سرویس پکیجی تحویل بگیرید که نتیجه‌ی اعتبارسنجی‌اش را تأیید کرده‌اید.

3. پین کردن تصمیم، نه فقط نسخه

نسخه‌های رجیستری، شناسه‌های انتشار یکتا هستند. متادیتای منتشرشده تغییرناپذیر است و تغییر رکورد به نسخه‌ی جدیدی نیاز دارد. نسخه‌گذاری معنایی (Semantic Versioning) توصیه می‌شود، اما رجیستری آن را الزامی نکرده و بازه‌های نسخه‌ای (Version Ranges) را نمی‌پذیرد.

این یعنی ^1.4 یک پین پذیرش به شمار نمی‌رود؛ مقدار «latest» هم همین‌طور. یک پین کاربردی شامل این موارد است:

{
  "server": "com.example/inventory",
  "version": "1.0.0",
  "recordDigest": "...",
  "source": {"kind": "package", "registryType": "pypi"},
  "sourceDigest": "...",
  "toolsetDigest": "...",
  "provenanceDigest": "...",
  "registryStatus": "active"
}

پین کردن چند لایه به شما امکان می‌دهد بفهمید دقیقاً کدام مرز دستخوش تغییر شده است. تغییر دایجست رکورد تحت همان نسخه‌ی رجیستری، نقض یکپارچگی رجیستری است. تغییر دایجست منبع تحت همان مختصات پکیج یا استقرار راه‌دور، نقض یکپارچگی منبع اجرا است. تغییر دایجست مجموعه‌ابزارها نیز انحراف محیط اجرا است.

4. شناسایی انحراف در محیط زنده

فرایند پذیرش باید سروری را ارزیابی کند که در عمل ترافیک دریافت خواهد کرد. متد server/discover را فراخوانی کنید، توصیف‌گرهای ابزارهای ارائه‌شده را از مسیر معتبر خود به دست آورید و موارد زیر را بررسی کنید:

  • نسخه‌ی 2026-07-28 در supportedVersions باشد
  • تمام قابلیت‌های موردنیاز محلی وجود داشته باشند
  • تک‌تک توصیف‌گرهای ابزار، هویت و سطح اسکیمای لازم را داشته باشند
  • دایجست توصیف‌گرِ نرمال‌شده، در بررسی‌های بعدی دقیقاً با پین پذیرفته‌شده بخواند

مقدار اختیاری در نتیجه‌ی _meta["io.modelcontextprotocol/serverInfo"] متنی خوداظهاری برای نمایش، ثبت لاگ و خطایابی است. آن را به عنوان شواهد تشخیصی ثبت کنید، اما هرگز برای تعیین فضای نام، مالکیت پکیج، مالکیت اندپوینت، پذیرش یا هر تصمیم امنیتی دیگری به آن تکیه نکنید. نام مستعار مستقیم serverInfo خارج از بخش _meta جزو فیلدهای قرارداد رسمی نیست و نباید وارد شواهد تشخیصی شود.

فقط فیلدهایی را نرمال‌سازی کنید که ترتیب آن‌ها بی‌اهمیت است. کد نمونه، لیست ابزارها را پیش از هش کردن بر اساس نام پایدار مرتب می‌کند تا تغییر بی‌ضرر در ترتیب لیست، باعث گزارش انحراف نشود؛ اما فیلدهای توصیف‌گر را دور نمی‌اندازد. ابزار جدید، اسکیمای تغییریافته، توضیحات عوض‌شده یا حاشیه‌نویسی‌های جدید، همگی پین را تغییر می‌دهند.

کد نمونه با توصیف‌گرهای خراب و هرگونه تغییر در دایجست توصیف‌گر، مانند انحراف برخورد می‌کند: پین را قرنطینه کرده، مسیر فعال آن را حذف می‌کند و امکان بازگردانی به آن نسخه را مسدود می‌سازد. خط‌مشی پروداکشن ممکن است حتی یک تغییر متنی در توضیحات را فقط از طریق بازبینی مجدد مجاز بداند، چرا که توضیحات روی انتخاب ابزار توسط مدل تأثیر می‌گذارند. متادیتای «ظاهری» می‌تواند رفتار ایجنت را تغییر دهد.

5. وضعیت رجیستری، یک حالت زنده است

API رجیستری در کنار هر رکورد سرور، یک شیء _meta در سطح پاسخ قرار می‌دهد. فیلدهای تحت مدیریت رجیستری ذیل _meta["io.modelcontextprotocol.registry/official"] هستند. شیء _meta پاسخ را به فرایند پذیرش بفرستید و _meta["io.modelcontextprotocol.registry/official"].status را بخوانید. مقدار مستقیم _meta.status ساختار رسمی ارسال‌شده روی شبکه نیست. متادیتای پاسخ را با _meta داخلیِ خودِ رکورد انتشار اشتباه نگیرید. وضعیت می‌تواند این مقادیر باشد:

  • active: به صورت پیش‌فرض بازگردانده می‌شود و شرایط پذیرش محلی را دارد
  • deprecated: همچنان با یک هشدار قابل کشف است، اما دیگر انتخاب خودکارِ امنی نیست
  • deleted: به طور پیش‌فرض پنهان است، اما رکورد تاریخی آن از طریق نماهای حذفی یا افزایشی در دسترس باقی می‌ماند

وضعیت را پس از پذیرش همگام‌سازی کنید. اگر نسخه‌ای فعال به وضعیت منسوخ یا حذف‌شده تغییر کرد، پین آن را قرنطینه کنید و ارجاع کارهای جدید به آن را متوقف سازید. شواهد را نگه دارید؛ حذف از لیست پیش‌فرض به معنای مجوزی برای پاک کردن ردپای حسابرسی شما نیست.

متادیتای سفارشیِ ناشر فقط باید ذیل _meta.io.modelcontextprotocol.registry/publisher-provided در رکورد انتشار قرار گیرد. متادیتای پاسخ که توسط رجیستری مدیریت می‌شود جداست. اجازه ندهید ناشر وضعیت رسمی خودش را تعیین کند.

6. بازگردانی یعنی بازیابی مسیر

یک انتشار تغییرناپذیر هنگام بازگردانی ویرایش نمی‌شود. بازگردانی، پینی را انتخاب می‌کند که قبلاً پذیرفته شده و در حال حاضر واجد شرایط است و سپس مسیر فعال را تغییر می‌دهد.

یک مقصد امن باید:

  1. رکورد پذیرشِ تکمیل‌شده داشته باشد.
  2. بر اساس خط‌مشی شما، همچنان وضعیت رجیستری فعالی داشته باشد.
  3. با شواهد امنیتی یا محیط اجرا قرنطینه نشده باشد.
  4. همچنان به پکیج پین‌شده و مجموعه‌ی توصیف‌گرهای زنده منتهی شود.
  5. بررسی‌های سلامت (Health Checks) فعلی را با موفقیت پشت سر بگذارد.

کد نمونه روی سه شرط اول تمرکز دارد. یک تطبیق‌دهنده (Reconciler) واقعی در محیط عملیاتی باید قبل از فعال‌سازی، پکیج را دوباره دریافت کرده و اندپوینت زنده را دوباره بررسی کند.

7. ثبت در دفترکل پذیرش

پایگاه داده‌ی پذیرش می‌گوید چه چیزی فعال است؛ اما دفترکل توضیح می‌دهد چرا فعال است.

هر مدخل در کد نمونه شامل شماره ترتیب، زمان، رویداد، سرور، نسخه، نتیجه، دلایل، شواهد، هش مدخل قبلی و هش خودِ مدخل است. تغییر نتیجه‌ی یک مدخل قدیمی، اعتبارسنجی آن مدخل و تمام زنجیره‌های بعدی را با خطا مواجه می‌کند.

این ساختار «ضد‌دستکاری» است، نه اینکه معجزه‌آسا غیرقابل دستکاری باشد. سر (Head) دفترکل را به طور دوره‌ای در یک دامنه‌ی اعتماد مجزا مهار کنید؛ مثل متادیتای انتشار امضاشده یا حافظه‌های فقط‌خواندنی. افراد مجاز به ثبت مدخل را محدود کنید. توکن‌های احراز هویت، اعتبارهای دسترسی پکیج، آرگومان‌های ابزارها و داده‌های خصوصی اندپوینت را وارد شواهد نکنید.

ساخت کنترلر

کنترلر اجرایی در code/main.py قرار دارد و فقط از کتابخانه‌ی استاندارد Python استفاده می‌کند.

کار را با این سناریوی محدود آغاز کنید:

cd phases/13-tools-and-protocols/30-mcp-registry-supply-chain-and-drift
python3 code/main.py

این سناریو پنج عملیات را نمایش می‌دهد:

  1. پذیرش 1.0.0 با تطابق کامل در فضای نام، منشأ پکیج، پروتکل، قابلیت‌ها و ابزارها.
  2. پذیرش 1.1.0 و فعال کردن آن.
  3. مشاهده‌ی یک ابزار حذف غیرمنتظره در محیط اجرا.
  4. مشاهده‌ی تغییر وضعیت رجیستری برای نسخه‌ی 1.1.0 به deprecated.
  5. بازگردانی مسیر به پین نسخه‌ی 1.0.0 که هنوز در وضعیت پذیرفته‌شده قرار دارد.

خروجی مورد انتظار:

{
  "admitted": [true, true],
  "driftAllowed": false,
  "rollbackAllowed": true,
  "activeVersion": "1.0.0",
  "ledgerValid": true
}

کد را به این ترتیب مطالعه کنید:

  1. توابع namespace_for_domain() و namespace_matches() مرجعیت نام‌گذاری دقیق را برقرار می‌کنند.
  2. توابع digest() و normalized_tools() شواهدی قطعی و تکرارپذیر تولید می‌کنند.
  3. متد RegistryAdmissionController.admit() انتشار، منشأ و سندیت، محیط اجرا و خط‌مشی را پیوند می‌دهد.
  4. متد check_live() مشاهدات جدید را با پین مقایسه می‌کند.
  5. متد observe_registry_status() نسخه‌هایی را که وضعیت رجیستری آن‌ها تغییر کرده قرنطینه می‌کند.
  6. متد rollback() فقط مقصدی واجد شرایط را که قبلاً پذیرفته شده فعال می‌کند.
  7. متد AdmissionLedger.verify() تغییرات در تاریخچه‌ی ثبت‌شده را شناسایی می‌کند.

استفاده از کنترلر

کنترلر را بین بخش‌های کشف و مسیریابی قرار دهید:

Registry sync -> artifact verifier -> live discovery -> admission controller -> route table
                                               |                 |
                                               v                 v
                                          evidence store    admission ledger

برای این وظایف از هویت‌های مجزا استفاده کنید. یک پردازه‌ی همگام‌ساز رجیستری فقط نیاز به دسترسی خواندن متادیتا دارد. یک اعتبارسنج آرتیفکت به دسترسی دریافت پکیج نیاز دارد. یک تطبیق‌دهنده‌ی مسیر فقط به مجوزِ فعال‌سازی یک پینِ تأییدشده نیاز دارد. هیچ‌کدام از آن‌ها به تمامی دسترسی‌ها نیاز ندارند.

وضعیت استقرار را کاملاً شفاف کنید. «Approved» یعنی شواهد با خط‌مشی همخوانی دارند. «Active» یعنی مسیر در حال حاضر ترافیک را به آن می‌فرستد. «Quarantined» یعنی نباید کار جدیدی دریافت کند. «Superseded» یعنی نسخه‌ی پذیرفته‌شده‌ی دیگری فعال است. هرگز این چهار مفهوم را در یک متغیر بولی ساده خلاصه نکنید.

فرایند پذیرش را حتماً پیش از قرار دادن سرور در خروجی tools/list اجرا کنید؛ در غیر این صورت کلاینت می‌تواند ابزاری را در فاصله‌ی زمانی میان انتشار تا ارزیابی خط‌مشی (Policy Evaluation) شناسایی کند.

کارگاه تعاملی

در این بخش خرابی تک‌تک مرزها را به صورت عملی خواهید دید.

کارگاه الف: تداخل فضای نام

یک شل Python در پوشه‌ی کد باز کنید:

cd phases/13-tools-and-protocols/30-mcp-registry-supply-chain-and-drift/code
python3 -q

سپس این دستورات را اجرا کنید:

from main import namespace_matches
namespace_matches("com.example/inventory", "com.example")
namespace_matches("com.exampleevil/inventory", "com.example")

نتیجه‌ی اول True و نتیجه‌ی دوم False است. مقایسه‌ی دقیق را به صورت موقت با startswith جایگزین کنید و ببینید چطور نام دوم از مرز عبور می‌کند. پیش از ادامه‌ی کار، مقایسه‌ی دقیق را به حالت اول برگردانید.

کارگاه ب: انحراف توصیف‌گر

from main import *
times = iter(f"2026-08-21T12:00:{n:02d}+00:00" for n in range(10))
c = RegistryAdmissionController(clock=lambda: next(times))
meta = {OFFICIAL_META_KEY: {"status": "active"}}
c.admit(sample_record("1.0.0"), meta, "com.example", evidence_for("1.0.0"), sample_live("1.0.0"))
c.check_live("com.example/inventory", "1.0.0", sample_live("1.0.0", True))

دلایل و وضعیت مسیر را بررسی کنید. پکیج و رکورد رجیستری تغییری نکرده‌اند؛ اما مشخصات ابزار در محیط اجرا عوض شده است، بنابراین کنترلر پین را قرنطینه و غیرفعال کرده است. به همین دلیل کنترل زنجیره‌ی تأمین باید پس از نصب نیز ادامه داشته باشد.

کارگاه ج: وضعیت و بازگردانی

نسخه‌ی 1.1.0 را پذیرش کنید، آن را منسوخ علامت بزنید و هر دو مقصد بازگردانی را امتحان کنید:

c.admit(sample_record("1.1.0"), meta, "com.example", evidence_for("1.1.0"), sample_live("1.1.0"))
c.observe_registry_status("com.example/inventory", "1.1.0", "deprecated")
c.rollback("com.example/inventory", "1.1.0", "unsafe retry")
c.rollback("com.example/inventory", "1.0.0", "restore known release")
c.ledger.verify()

مقصد قرنطینه‌شده رد می‌شود. پین فعال قبلی پذیرفته می‌شود. دفترکل معتبر باقی می‌ماند.

تمرین عملی

کنترلر را با افزودن یک دروازه‌ی تأیید دو‌نفره توسعه دهید.

الزامات:

  • تأییدیه‌ها را به عنوان مراجع شواهد امضاشده ذخیره کنید، نه به صورت نام‌های تغییرپذیر درون پین.
  • برای مجموعه‌ابزارهایی که شامل ابزاری با ویژگی destructiveHint: true هستند، تأیید دو هویتِ بازبینِ متفاوت را الزامی کنید.
  • هویت‌های بازبینِ تکراری را رد کنید.
  • در صورتی که تأییدیه کامل نبود، تلاش اولیه‌ی پذیرش را درون دفترکل حفظ کنید.
  • تست‌هایی برای حالت‌های بدون تأیید، یک تأیید، تأیید تکراری و دو تأیید متمایز اضافه کنید.
  • امضاها، اطلاعات هویتی یا آرگومان‌های کامل و خصوصی ابزار را لاگ نکنید.

موفقیت یعنی ابزاری با رفتار مخرب تا زمانی که هر دو هویت، دایجست دقیق رکورد، پکیج و مجموعه‌ابزار را تأیید نکرده باشند، فعال نشود.

خروجی این درس

این درس فایل outputs/skill-mcp-registry-admission.md را تولید می‌کند. از آن به عنوان یک ران‌بوک (Runbook) مستقل و کاربردی هنگام بازبینی نسخه‌ی جدید رجیستری یا بررسی انحراف استفاده کنید. این فایل ورودی‌ها، قوانین رد درخواست، بسته‌ی شواهد، تطبیق وضعیت و اثبات بازگردانی را بدون وابستگی به نام کلاس‌های نمونه مشخص می‌کند.

بررسی صحت کار

کد نمایشی و مجموعه‌تست‌های قطعی را اجرا کنید:

cd phases/13-tools-and-protocols/30-mcp-registry-supply-chain-and-drift
python3 code/main.py
python3 -m unittest discover -s code/tests -v

ارزیابی باید موارد زیر را اثبات کند:

  • مرزهای دقیق فضای نام، پیشوندهای مشابه را رد می‌کنند
  • فقط وضعیت رسمیِ دارای فضای نام در رجیستری می‌تواند یک نسخه را واجد شرایط کند
  • شواهد پکیج و راه‌دورِ تأییدنشده یا ناسازگار رد می‌شوند
  • متادیتای ناشر نمی‌تواند خود را به جای متادیتای تحت مدیریت رجیستری جا بزند
  • ترتیب ابزارها نرمال‌سازی می‌شود، بدون اینکه تغییرات توصیف‌گر پنهان بماند
  • ساختارهای ناقص پکیج و ابزار با امنیت کامل رد می‌شوند
  • اطلاعات serverInfo تشخیصی باقی می‌ماند و مرجعیت پذیرش پیدا نمی‌کند
  • انحراف توصیف‌گر باعث قرنطینه، غیرفعال‌سازی و مسدود شدن بازگردانی به پین می‌شود
  • تغییرات وضعیت، پین‌های فعال را قرنطینه می‌کند
  • بازگردانی نمی‌تواند نسخه‌ای قرنطینه‌شده یا ناشناخته را انتخاب کند
  • دستکاری دفترکل فوراً شناسایی می‌شود

حالت‌های شکست در پروداکشن

حالت شکست علت رخ دادن اقدام لازم
نام معتبر به نظر می‌رسد اما فضای نام احراز هویت نشده خط‌مشی به متن خام رکورد اعتماد کرده است تا زمانی که یک اعتبارسنج مطمئن برای فضای نام، پیشوند دقیق را تأیید نکرده آن را رد کنید
مشخصات یکسان پکیج، بایت‌های متفاوتی برمی‌گرداند سرور بالادستی تغییرپذیر یا سیستم توزیعِ آلوده‌شده فعال‌سازی را متوقف کرده، هر دو دایجست را نگه دارید و مرز دریافت را بررسی کنید
گزینه‌ی «latest» بدون بازبینی تغییر می‌کند ارجاع شناور از قید پین خارج شده است فقط به نسخه‌ها و دایجست‌های پذیرفته‌شده‌ی دقیق متکی شوید
ابزار جدیدی پس از تأیید ظاهر می‌شود انحراف در محیط اجرا یا استقرار نسخه‌ای متفاوت مسیر را قرنطینه کرده و یک مشاهده‌ی جدید از توصیف‌گر ثبت کنید
نسخه‌ی منسوخ‌شده همچنان فعال می‌ماند همگام‌سازی وضعیت انجام نشده یا تأخیر دارد وضعیت را طبق زمان‌بندی و پیش از فعال‌سازی تطبیق دهید
رکورد حذف‌شده از همگام‌سازی پیش‌فرض ناپدید می‌شود کلاینت فقط رکوردهای فعال را درخواست کرده است از تطبیق افزایشی یا آگاه از موارد حذف‌شده استفاده کرده و تاریخچه‌ی محلی را حفظ کنید
مقصد بازگردانی هرگز پذیرفته نشده است کنترل مسیر و وضعیت تأیید از هم جدا هستند بازگردانی را رد کرده و فرایند پذیرش جدیدی برای مقصد اجرا کنید
دفترکل پس از بازنویسی همه‌ی مدخل‌ها توسط مهاجم همچنان تأیید می‌شود زنجیره‌ی هش لنگر خارجی ندارد سر دفترکلِ امضاشده را در یک دامنه‌ی اعتماد مجزا منتشر کنید
شواهد حاوی توکن‌های حامل (Bearer) یا آرگومان‌های ابزار هستند لاگ‌گیری کل درخواست‌ها را کپی کرده است اطلاعات حساس را در زمان دریافت سانسور کرده و فقط حداقل شواهد را ذخیره کنید

اصل عملیاتی

انتشار به این پرسش پاسخ می‌دهد که «آیا این هویت می‌تواند این نام را منتشر کند؟» پذیرش پاسخ می‌دهد که «آیا ما این آرتیفکت دقیق را اجرا کرده و این رفتار دقیق را ارائه خواهیم داد؟» این تصمیم‌ها را از هم تفکیک کنید، تمام نقاط الحاق را پین کنید و بازگردانی مسیر را بر اساس شواهد انجام دهید نه حدس و حافظه.

برای مطالعه‌ی بیشتر

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسانتشار موفقیت‌آمیز در یک رجیستری MCP چه چیزی را برای یک گیت‌وی پروداکشن اثبات می‌کند؟
  2. حین درسکدام روش مقایسه نیم‌اسپیس، com.exampleevil/tool را در صورتی که نیم‌اسپیس تاییدشده com.example باشد، رد می‌کند؟
  3. حین درسیک سرور زنده ابزار جدیدی اضافه می‌کند در حالی که رکورد رجیستری و مشخصات پکیج آن بدون تغییر مانده است. کدام شواهد این مورد را شناسایی می‌کند؟
  4. حین درسهنگامی که یک نسخه پذیرفته‌شده در رجیستری از active به deprecated تغییر می‌کند، چه اتفاقی باید بیفتد؟
  5. پس از درسکدام مقصد واجد شرایط بازگردانی خودکار (automatic rollback) است؟
  6. پس از درسچرا سر (head) دفتر کل پذیرش باید در یک دامنه اعتماد مجزا تثبیت (anchor) شود؟

سؤالات متداول

چرا وجود یک سرور در رجیستری رسمی MCP برای اعتماد و اجرای مستقیم آن کافی نیست؟

رجیستری فقط تأیید می‌کند که ناشر اجازه داشته متادیتا را ثبت کند؛ اما تضمین نمی‌کند محتوای دانلودشده تغییر نکرده باشد، نسخه منسوخ نشده باشد یا توصیف‌گر ابزار در محیط اجرا دچار انحراف و اضافه شدن توابع مخرب نشده باشد.

چرا پین کردن نسخه‌ای مثل 1.4^ یا latest برای پذیرش در پروداکشن ناامن است؟

ارجاع‌های شناور به بایت‌های تغییرپذیر اشاره می‌کنند. یک پین معتبر پذیرش باید علاوه بر نسخه دقیق، شامل دایجست تغییرناپذیر رکورد، دایجست منبع پکیج و دایجست توصیف‌گرهای زنده ابزار باشد تا هرگونه تغییر مرز شناسایی شود.

کنترلر پذیرش با انحراف توصیف‌گر ابزار در محیط اجرا (Runtime Drift) چه رفتاری می‌کند؟

اگر هش مشخصات ابزار با هش پین‌شده در زمان پذیرش تطابق نداشته باشد، پین مربوطه بلافاصله قرنطینه و مسیر آن غیرفعال می‌شود و از انتخاب این نسخه به عنوان مقصد بازگردانی (Rollback) جلوگیری خواهد شد.

نقش دفترکل پذیرش (Admission Ledger) در این معماری چیست؟

دفترکل با ثبت زنجیره‌ای از هش‌های هر تصمیم، مشخص می‌کند که چرا و بر اساس چه شواهدی یک سرور تأیید، فعال، قرنطینه یا بازگردانی شده است و ساختاری ضد دستکاری (Tamper-evident) برای بازرسی ثبت می‌کند.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.