تصور کنید یک برنامهنویس در تیمی کوچک، صبح خود را با ایمیلی از Vercel آغاز کند و بفهمد کدی که هرگز بررسی نشده، همین حالا برای هزاران کاربر فعال است. این کابوس در ۱۲ اکتبر ۲۰۲۶ برای یکی از توسعهدهندگان پلتفرم dev.to رخ داد؛ جایی که یک عامل (Agent) — شبیه دستیاری که دستورات را بدون پرسیدنِ «چرا» اجرا میکند — تمام لایههای امنیتی را دور زد. توسعهدهنده در گزارش خود نوشت: «کدی تستنشده مستقیماً به محیط عملیاتی فرستاده شد». این خطا تنها زمانی کشف شد که توسعهدهنده بهطور اتفاقی ایمیل خودکار استقرار (Deployment) را از Vercel دریافت کرد.
این حادثه هشداری جدی برای تیمهایی است که عاملهای هوش مصنوعی را در خط لولههای CI/CD خود جای میدهند. بسیاری از توسعهدهندگان تصور میکنند داشتن یک «سیاست کلی برای هوش مصنوعی» (AI Policy) کافی است، اما این مورد ثابت میکند که عاملها از هنجارهای اجتماعی ضمنی یا میانبرهای «موقت» پیروی نمیکنند. آنها دقیقاً بر اساس دسترسیهای فنی اعطا شده عمل میکنند، فارغ از اینکه ریسک آن چه باشد.
همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای بازمتن اشاره کردیم، اعتماد بیش از حد به لایههای حفاظتی انسانی، بزرگترین نقطه ضعف سیستمهای خودکار است. در یک مورد پیشین، همین عامل کدی معیوب را به یک شاخه ویژگی (Feature Branch) فرستاده بود و سیستم یکپارچهسازی مداوم (CI) — مثل یک بازرس سختگیر که اجازه ورود به ساختمان را بدون کارت شناسایی نمیدهد — خطا را شناسایی کرد. این موفقیت اولیه، حس امنیت کاذبی ایجاد کرد و این تصور را به وجود آورد که حفاظهای انسانی برای متوقف کردن ماشین کافی هستند. اما فاجعهی ۱۲ اکتبر به این دلیل رخ داد که عامل با مخزنی (Repository) مواجه شد که پیکربندی متفاوتی داشت. این تجربه یادآور این نکته است که طراحی گردشکار ایمن بسیار حیاتیتر از تکیه بر مدل است، چرا که حتی پیشرفتهترین مدلها نیز در برابر حفرههای زیرساختی ناتواناند.
توهم امنیت
در حادثه اول، چون کد به شاخه اصلی (Main) نرفت و تنها در یک شاخه ویژگی باقی ماند، خطا صرفاً یک اتفاق گذرا بود و نه یک بحران؛ یا به قول توسعهدهنده، «یک تکان شانه بود، نه یک بعدازظهر بد». توسعهدهنده به این نتیجه رسید که نیازی به سیاستهای خاص برای هوش مصنوعی نیست، چون همان حفاظهایی که برای مشارکتکنندگان انسانی تعریف شده، ماشین را هم متوقف میکند.
این یک فرض خطرناک بود. توسعهدهنده باور داشت که سیستم امن است، اما در واقعیت، این امنیت به پیکربندی خاص آن یک مخزن وابسته بود، نه به ماهیت کلی سیستم. وقتی عامل به مخزن دیگری منتقل شد، نبودِ همان حفاظها، یک خطای کوچک را به یک حادثه در محیط عملیاتی تبدیل کرد.
کالبدشکافی شکست
وظیفه عامل ساده بود: بهروزرسانی رابط کاربری (UI) برای رندرینگ صفحه و وضعیت DOM پس از بهروزرسانی دادهها. تغییرات در محیط محلی درست به نظر میرسید، اما عامل دستور git push را مستقیماً روی شاخه اصلی اجرا کرد. هیچ وقفهای بین لحظهای که «عامل دستور git push را تایپ کرد» و آنلاین شدن کد وجود نداشت. طبق بررسی مستندات این حادثه، سه شکاف حیاتی باعث این اتفاق شد:
- نبود حفاظت از شاخه: مخزن فاقد Branch Protection بود و اجازه میداد بدون Pull Request (PR) یا هرگونه مرحلهی بررسی، کد مستقیماً روی Main قرار بگیرد.
- نبود گیت CI: هیچ الزامی وجود نداشت که یک خط لوله (Pipeline) پیش از ادغام کد در شاخه اصلی، پاس شود.
- محرک استقرار خودکار: مخزن به سیستم استقرار خودکار Vercel متصل بود؛ یعنی هر Push به شاخه اصلی، فوری به معنای انتشار برای تمام بازدیدکنندگان سایت بود. هر آنچه در آن کامیت (Commit) بود، فوراً برای همه کاربران اجرا میشد.
شانس در لباس فرآیند
توسعهدهنده صادقانه اعتراف میکند که این خطا توسط هیچ حفاظ سیستمی گرفته نشد. تنها دلیل کشف آن، این بود که Vercel هر بار پس از استقرار یک ایمیل میفرستد و توسعهدهنده بهطور اتفاقی آن را دید. او این وضعیت را «شانس در لباس فرآیند» مینامد.
اگر او یک ساعت دیرتر ایمیل را میدید، یا اگر ایمیل در میان انبوه پیامها نادیده گرفته میشد، کد معیوب تا زمانی که یک کاربر متوجه مشکل در سایت میشد، در محیط عملیاتی باقی میماند. هرچند استقرار سریعاً بازگردانی (Rollback) شد و خسارتی به کاربر نرسید، اما توسعهدهنده خاطرنشان میکند که عبارت «اتفاقی ایمیل را به موقع دیدم» جملهای است که هرگز نباید در نزدیکی گیتهای استقرار محیط عملیاتی شنیده شود.
چرا این مخزن متفاوت بود؟
مخزن قبلی دارای حفاظت از شاخه و CI بود که باید پیش از ادغام پاس میشد. اما این مخزن جدید، یک پروژه جانبی کوچک و جدیدتر بود؛ از آن دست پروژههایی که برنامهنویس با خود میگوید «بعداً تنظیماتش را درست میکنم» و چون تا آن لحظه اتفاق بدی نیفتاده، هرگز این کار را نمیکند.
در اینجا هیچ حفاظی حذف نشده بود، بلکه اصلاً ساخته نشده بود. عامل راه پیچیدهای برای دور زدن گیت پیدا نکرد؛ او صرفاً از دری عبور کرد که هرگز نصب نشده بود. از دیدگاه داخلی سیستم، یک دربِ نصبنشده دقیقاً شبیه به یک کفپوش باز است.
بستن شکافها
توسعهدهنده این آسیبپذیری را نه با سیاستهای پیچیده و خاصِ هوش مصنوعی، بلکه با دو تغییر مکانیکی و ساده حل کرد:
- فعالسازی Branch Protection: اکنون حفاظت روی شاخه اصلی فعال شده و ارسال Pull Request الزامی است. هیچ کدی نمیتواند بدون PR به Main ادغام شود.
- لغو دسترسی مستقیم: دسترسی عامل برای Push مستقیم در این مخزن لغو شد. عامل همچنان میتواند کار کند، شاخه بسازد و PR باز کند، اما دیگر نمیتواند مستقیماً کامیتی را در برابر محرک استقرار عملیاتی قرار دهد.
این اصلاحات برای هر پروژه چندنفره استاندارد است، اما در پروژههای کوچک نادیده گرفته میشود. عامل هیچ اکسپلویت هوشمندانهای پیدا نکرد؛ او فقط طبق دسترسیهایی که داشت عمل کرد.
درس واقعی
در عصر عاملمحور (Agentic)، این تغییر دیدگاه حیاتی است. عاملی که سریع، مطمئن و بدون تردید عمل میکند، در واقع یک تست استرس با سرعت بالا برای «بدهی فنی» (Technical Debt) شماست. او سریعتر از هر حسابرس انسانی، تکتک خط لولههای تقویتنشده یا مخازن فراموششده را پیدا میکند. این موضوع دقیقاً همان جایی است که بحران هویتهای دارای دسترسی ویژه در عصر عاملها شکل میگیرد و نظارتهای سنتی را ناکارآمد میکند.
یک عامل غریزی ندارد که بگوید «این بخش هنوز آماده نیست» یا «این فقط موقتی است». او تسک را روی هر ریلی که زیر پایش باشد اجرا میکند. او مخزنی را که شما هرگز در آن Branch Protection را فعال نکردهاید، سریعتر از یک برنامهنویس در «یک بعدازظهر آرام سهشنبه» پیدا میکند.
برای شما این یعنی ایمنی هوش مصنوعی شما، به اندازه ضعیفترین و رهاشدهترین مخزن شماست. اگر تنها چیزی که بین یک عامل خودکار و سایت عملیاتی شما، «دیده شدن به موقع یک ایمیل توسط انسان» است، شما یک شکاف سیستمی دارید. درس اصلی این است که این شکافها را در هر مخزنی ببندید، نه فقط در مخازنی که قبلاً دلیلی برای بررسیشان به شما دادهاند.
در آینده، باید منتظر ظهور نقشهای «IAM مخصوص عاملها» (مدیریت هویت و دسترسی) باشیم که شعاع تخریب ابزارهای خودکار را در کل سازمانها بهطور سختگیرانهای محدود میکنند. همچنین برای جلوگیری از خطاهای گزارششده، ابزارهایی مانند Claude Code با ایجاد گاردریلهای سختگیرانه تلاش میکنند تا از ادعاهای دروغین عاملها درباره رفع باگها جلوگیری کنند.
گام بعدی شما
- تمام مخازن (حتی پروژههای جانبی) را برای فعال بودن Branch Protection بررسی کنید.
- دسترسیهای API عاملها را از Push مستقیم به Main سلب کرده و آنها را مجبور به باز کردن Pull Request کنید.
- یک خط لوله CI ساده حتی برای کوچکترین پروژهها تعریف کنید تا از ورود کد معیوب جلوگیری شود.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو