اجرای عامل کدنویسی در VM موقت و امن
عامل کدنویسی را در VM دورریختنی اجرا کنید تا به کلیدهای SSH و فایلهای شخصی دسترسی نداشته باشد؛ هر وظیفه محیطی پاک دارد و VPS را میتوان در 10 دقیقه ساخت.
چرا یک VM موقت از لپتاپ شما بهتر است
یک VM موقت در اختیار عامل کدنویسی قرار دهید. در این حالت، بدترین کاری که میتواند انجام دهد، از بین بردن ماشینی است که میتوانید آن را در مدت ده دقیقه دوباره ایجاد کنید. عامل همچنان به root دسترسی دارد، همچنان packageها را نصب میکند و همچنان مجموعه آزمون را اجرا میکند؛ بدون اینکه برای هر مرحله از شما اجازه بگیرد. تفاوت در محل وقوع آسیب است. در لپتاپ، عامل به یک home directory مشترک با کلیدهای SSH، profile مرورگر، فایلهای .env و هر repository دیگری که تاکنون clone کردهاید دسترسی دارد. در یک server دورریختنی، فقط یک shell، یک checkout و هیچ چیز باارزش دیگری برای سرقت در اختیار دارد.
این تمام استدلال است؛ استدلالی درباره عدم تقارن، نه احتمال. یک عامل دقیق روی یک لپتاپ دقیق تقریباً همیشه مشکلی ایجاد نمیکند. اما اگر یکبار مشکلی ایجاد کند، هزینه آن یک commit نامناسب نیست. هزینه، restore کردن از backup است؛ البته اگر backup داشته باشید.
پیش از بحث درباره دامنه آسیب، آن را مشخص کنید
دامنه آسیب به مجموعه مواردی گفته میشود که یک فرایند میتواند به آنها دسترسی پیدا کند. برای عاملی که با حساب کاربری عادی شما روی دستگاه معمولی شما اجرا میشود، این مجموعه از چیزی که بیشتر افراد تصور میکنند بزرگتر است.
این مجموعه شامل ~/.ssh/id_ed25519 است که معمولاً رمزگذاری نشده است، چون از وارد کردن عبارت عبور خسته شدهاید. شامل ~/.aws/credentials و ~/.config/gh/hosts.yml نیز میشود که عمداً بهصورت متن ساده هستند. همچنین همه مخزنهای همسطح زیر ~/code را دربرمیگیرد، از جمله مخزنهایی که رشتههای اتصال محیط تولید را در یک فایل env محلی دارند. سابقه shell شما نیز در این مجموعه قرار میگیرد؛ این سابقه ممکن است حاوی tokenهایی باشد که یکبار در آن جایگذاری کردهاید. شبکهای که لپتاپ شما به آن متصل است نیز جزو این مجموعه است؛ این شبکه اغلب شبکه خانگی یا اداریای است که سرویسهای بدون احراز هویت روی آن فعال هستند.
هیچیک از این موارد به عامل مخرب نیاز ندارد. یک فرمان با اطمینان اما اشتباه کافی است. rm -rf با متغیری تعریفنشده که به / بسط پیدا میکند، یک git clean -xfd در پوشه اشتباه، یک docker system prune -af --volumes که پایگاه داده محلی شما را نیز حذف میکند، یا یک chmod -R 777 بهظاهر مفید روی پوشه خانگی. عاملها با همان اینترنتی آموزش دیدهاند که این فرمانها را به دیگران نیز آموخته است.
مکانیزمی که از شما محافظت میکند، قضاوت عامل نیست. این است که دستگاهی که آسیب را متحمل میشود، دستگاهی است که حاضر بودهاید آن را از دست بدهید.
محاسبه هزینه خستهکننده است؛ و نکته همین است
هزینه یک VPS کوچک ماهانه چند دلار است. بازیابی لپتاپ یک توسعهدهنده یک روز زمان میبرد؛ و این در بهترین حالت است، یعنی زمانی که بلافاصله متوجه مشکل میشوید و نسخه پشتیبان دارید.
با اعداد خودتان محاسبه کنید. نرخ ساعتی خود را در تعداد ساعتهای لازم برای نصب مجدد سیستمعامل، بازیابی شاخه خانه، چرخش یک کلید SSH، چرخش یک personal access token و clone مجدد بیست مخزن ضرب کنید. سپس این هزینه را با هزینه 12 ماه کوچکترین سروری که ارائهدهنده شما میفروشد مقایسه کنید. نقطه سربهسر کمتر از یک رخداد در هر چند سال است؛ و رخداد لازم نیست فاجعهبار باشد تا این هزینه را توجیه کند. حتی از دست دادن یک بعدازظهر بهدلیل خراب شدن محیط محلی، هزینه یک سال را پوشش میدهد.
نیمه دوم این محاسبه به snapshotها مربوط است. ایجاد یک snapshot پیش از اجرای پرریسک، یک نتیجه بد را از «زندگیام را بازیابی کن» به «بازگردان و prompt دیگری را امتحان کن» تبدیل میکند. این گزینه روی لپتاپی که اکنون با آن تایپ میکنید وجود ندارد، زیرا نمیتوانید هنگام استفاده از یک دستگاه بهعنوان میز کار، از آن snapshot بگیرید.
وضعیت تا ژوئیه 2026
برای پاسخ به این پرسش که «عامل باید کجا اجرا شود»، 3 پاسخ صادقانه وجود دارد. این گزینهها میان 2 عامل یکسان مصالحه ایجاد میکنند: قدرت مرز ایزولهسازی و میزان پیکربندیای که میپذیرید.
یک micro VM محلی. ابزارهای این دسته یک ماشین مجازی واقعی را روی سختافزار خودتان راهاندازی میکنند، مخزن شما را در آن mount میکنند و به عامل اجازه میدهند درون آن دسترسی root داشته باشد. clawk نمونه فعلی این دسته است و دقیقاً همین دیدگاه را دنبال میکند: بهجای لپتاپ، یک Linux VM موقت و قابل حذف در اختیار عاملهای کدنویسی بگذارید. تا ژوئیه 2026، این ابزار روی macOS 14 و نسخههای بعدی در Apple silicon هدفگذاری شده است و از Linux از طریق Firecracker بهصورت آزمایشی پشتیبانی میکند. نصب آن با brew install clawkwork/tap/clawk انجام میشود. برای راهاندازی sandbox و اتصال عامل، درون یک مخزن clawk را اجرا کنید؛ برای متوقفکردن آن از clawk down و برای حذف آن از clawk destroy استفاده کنید. این مرز را hypervisor ایجاد میکند و مرز قدرتمندی است. محدودیت این است که VM روی همان دستگاهی اجرا میشود که با خود حمل میکنید؛ بنابراین از حافظه شما استفاده میکند و با بستن درِ لپتاپ متوقف میشود.
یک container. Docker پاسخی است که بیشتر افراد از قبل آن را نصب کردهاند و واقعاً مفید است.
docker run --rm -it -v "$PWD:/work" -w /work --network none ubuntu:24.04 bash--rm هنگام خروج، container را حذف میکند و --network none دسترسی شبکه را کاملاً از آن میگیرد؛ این تنظیم پیشفرض مناسبی برای build یا اجرای test است. درباره کاری که این روش انجام نمیدهد، شفاف باشید: یک container از kernel میزبان استفاده میکند؛ بنابراین وجود یک باگ در kernel میتواند راهی برای خروج از ایزولاسیون باشد. همچنین بهمحض افزودن --privileged یا mount کردن /var/run/docker.sock، مرز ایزولاسیون از بین میرود تا عامل بتواند «از Docker استفاده کند». Mount کردن Docker socket در یک container، معادل دادن دسترسی root به آن container روی میزبان است.
یک VPS معمولی که بتوانید دوباره build کنید. به ابزار جدیدی نیاز ندارید، از یک مرز واقعی در سطح kernel برخوردار هستید، snapshotهای provider را در اختیار دارید و VPS پس از خاموشکردن لپتاپ شما همچنان اجرا میشود. بخشهای بعدی این راهنما همین الگو را توضیح میدهند. این الگو برای اجرای طولانیمدت عاملها نیز مناسب است، چون کاری که 4 ساعت طول میکشد، به این اهمیت نمیدهد که شما به خانه رفتهاید.
الگوی VPS: به عامل، کاربر اختصاصی خودش را بدهید
از یک سیستم امنشده شروع کنید. ده دقیقه اول روی یک VPS جدید بخشهایی را پوشش میدهد که مختص عامل نیستند: بهروزرسانیها، ورود غیرroot، SSH فقط با کلید و فایروال.
سپس حسابی ایجاد کنید که فقط برای عامل وجود داشته باشد تا یک اشتباه در آن نتواند به بخش دیگری از سرور دسترسی پیدا کند.
sudo adduser --disabled-password --gecos "" agent
sudo install -d -m 700 -o agent -g agent /home/agent/work
sudo -u agent -H bash -lc 'id; ls -la ~'--disabled-password یعنی هیچ گذرواژهای برای حدسزدن وجود ندارد و با sudo -u agent یا یک کلید SSH به این حساب دسترسی پیدا میکنید. توجه کنید که agent عمداً عضو گروه sudo نیست. عاملی که sudo داشته باشد، دسترسی root دارد و root میتواند فایلهای همه کاربران دیگر را بخواند؛ بنابراین جداسازیای که ایجاد کردهاید صرفاً ظاهری است. اگر عامل واقعاً به نصب بستهها نیاز دارد، این موضوع دلیلی برای استفاده از یک سرور کامل و اختصاصی برای آن است، نه اعطای sudo به آن روی یک سرور اشتراکی. قواعد کلی در اصل کمترین سطح دسترسی برای کاربران Linux در یک VPS آمده است.
پیش از اعتماد به این مرزبندی، آن را بررسی کنید. بهعنوان کاربر agent، تلاش کنید فایلی متعلق به حساب خودتان را بخوانید:
sudo -u agent cat /home/you/.ssh/id_ed25519باید cat: /home/you/.ssh/id_ed25519: Permission denied را ببینید. اگر بهجای آن، اطلاعات کلیدی را میبینید، دایرکتوری home شما دارای mode 755 است و جداسازی هنوز واقعی نیست. آن را با sudo chmod 700 /home/you اصلاح کنید.
اعتبارنامهها را بهطور کامل روی ماشین نگه ندارید
هدف استفاده از یک ماشین موقت، با کپیکردن اسرار محیط production روی آن از بین میرود. قاعده ساده است: هیچ موردی روی آن ماشین نباید اعتباری باشد که از چرخاندن آن در همین بعدازظهر ناراحت شوید.
برای git، بهجای کپیکردن کلید، SSH agent خود را forward کنید. کلید خصوصی روی لپتاپ شما باقی میماند و فقط درخواستهای امضا از طریق اتصال عبور میکنند.
ssh -A agent@203.0.113.10
ssh -T git@github.comدستور دوم باید به Hi yourname! You've successfully authenticated, but GitHub does not provide shell access. پاسخ دهد. این نشان میدهد که git push بدون وجود فایل کلید روی سرور کار خواهد کرد. پس از آن، ls -la ~/.ssh را روی ماشین اجرا کنید و تأیید کنید که هیچ کلید خصوصیای در آن وجود ندارد.
forward کردن agent یک نکته مهم دارد که باید صریح بیان شود: هنگام اتصال شما، هر فردی که روی آن سرور دسترسی root داشته باشد، میتواند از socket فورواردشده برای احراز هویت بهجای شما استفاده کند. در سروری که تنها کاربر دیگر آن خود شما هستید، این مصالحه قابلقبول است. در یک ماشین اشتراکی، قابلقبول نیست و deploy key محدودشده به یک repository گزینه بهتری است. این گزینهها در مبانی مدیریت کلید SSH توضیح داده شدهاند.
برای کلیدهای API، یک کلید اختصاصی با محدودیت هزینه اختصاصی به agent بدهید و آن را در فایلی ذخیره کنید که مالک آن کاربر agent باشد و mode آن 600 تنظیم شود. هنگام نابودکردن ماشین، آن کلید را revoke کنید تا مجبور نباشید درباره احتمال افشای آن حدس بزنید. قابلمشاهده نگهداشتن هزینه مدل برای هر کلید، همچنین روشی است که ارقام موجود در کنترل هزینه agent هوش مصنوعی روی VPS قابلپیشبینی باقی میمانند.
محدود کردن دسترسی agent به شبکه
ایزولهسازی فایلسیستم نیمی از مرز امنیتی است. نیمه دیگر خروجی شبکه است: پردازه مجاز است با چه مقصدهایی ارتباط برقرار کند. Linux میتواند ترافیک خروجی را بر اساس کاربری که آن را ایجاد کرده است فیلتر کند؛ این روش دقیقاً با این الگو سازگار است.
sudo iptables -A OUTPUT -m owner --uid-owner agent -o lo -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p udp --dport 53 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -p tcp --dport 443 -j ACCEPT
sudo iptables -A OUTPUT -m owner --uid-owner agent -j REJECTقواعد بهترتیب خوانده میشوند؛ بنابراین REJECT نهایی همه مواردی را پوشش میدهد که خطوط قبلی اجازه ندادهاند. این کار را با هویت agent آزمایش کنید:
sudo -u agent curl -sS -m 5 http://example.comاین اتصال باید با curl: (7) Failed to connect to example.com port 80: Connection refused ناموفق شود، زیرا قاعده reject بلافاصله پاسخ میدهد و اجازه نمیدهد اتصال معلق بماند. درخواست HTTPS به همان میزبان همچنان باید موفق شود.
دو محدودیت مهم وجود دارد. نخست، این قواعد در راهاندازی مجدد بعدی از بین میروند، مگر اینکه آنها را با sudo apt install -y iptables-persistent و سپس sudo netfilter-persistent save ذخیره کنید. دوم، این روش پورتها و نشانیها را فیلتر میکند، نه نامها را. قاعدهای که پورت 443 را مجاز میکند، دسترسی به همه میزبانهای HTTPS در اینترنت را ممکن میسازد؛ بنابراین هم برای دسترسی به API مدل کافی است و هم برای دسترسی به یک pastebin. برای ایجاد فهرست مجاز واقعی مبتنی بر دامنه، ترافیک باید از یک proxy عبور کند که نام میزبان درخواستی را میخواند. این معماری برای بیشتر محیطهای تکتوسعهدهندهای پیچیدهتر از حد مطلوب است. فقط ادعایی را مطرح کنید که واقعاً اعمال کردهاید: کنترل خروجی در سطح پورت، روی ماشینی که آماده بودهاید از دست بدهید.
بازنشانی به وضعیت پاک بین وظایف
وضعیت پاک برای هر وظیفه، مزیتی است که کمتر از ارزش واقعی آن شناخته میشود. عاملی که سه ساعت روی ticket قبلی کار کرده است، packageهای نصبشده، migrationهای نیمهاعمالشده، یک node_modules قدیمی و یک درخت کاری git با تغییراتی که هیچکس آنها را بازبینی نکرده است، بر جای گذاشته است. وظیفه بعدی همه این موارد را به ارث میبرد و شما زمان بازبینی خود را صرف تشخیص این میکنید که کدام بینظمی به کدام اجرا مربوط است.
روش ساده، ایجاد یک checkout تازه برای هر وظیفه است.
sudo -u agent -H bash -lc 'rm -rf ~/work/repo && git clone git@github.com:you/repo.git ~/work/repo'روش مطمئنتر، ایجاد یک snapshot از provider است؛ این snapshot باید یکبار، بلافاصله پس از راهاندازی machine و پیش از هرگونه دستکاری توسط agent گرفته شود. با بازگردانی این snapshot، کل system، از جمله packageها، به یک وضعیت شناختهشده بازمیگردد. بیشتر providerها این قابلیت را در control panel یا از طریق API ارائه میکنند، نه بهصورت command روی خود machine؛ بنابراین مراحل دقیق به provider شما بستگی دارد. اصل مهم این است که snapshot را زمانی بگیرید که machine هنوز تغییری نکرده است.
هر چیزی را که برایتان مهم است، خارج از machine موقتی نگه دارید؛ این کار معمولاً به معنای push کردن branchها بهجای نگهداری آنها بهصورت محلی است. اگر machine واقعاً چیزی را در خود نگه داشت که از دستدادنش برایتان مهم بود، با استفاده از پشتیبانگیری restic روی VPS از آن بهدرستی backup بگیرید. machineای که میتوانید نابود کنید، فقط زمانی مفید است که نابود کردن آن واقعاً بدون دردسر باشد.
اگر میخواهید چند environment ایزوله داشته باشید، بدون آنکه هزینه چند server را بپردازید، یک VPS بزرگتر میتواند مستقیماً میزبان VMهای guest باشد. مجازیسازی تودرتو روی VPS نحوه انجام این کار و همچنین روش بررسی مجاز بودن آن توسط provider شما را توضیح میدهد.
چه زمانی لپتاپِ دارای مراقبت کافی واقعاً مناسب است
در این مورد صادق باشید، زیرا بزرگنمایی درباره جداسازی باعث میشود افراد دیگر به این توصیهها توجه نکنند.
اگر هر فرمان را پیش از اجرا بررسی میکنید، لپتاپ مناسب است. اعلان مجوز یک کنترل واقعی است و اجرای ایمن Claude Code روی سرور بررسی میکند که هر سطح از این کنترل دقیقاً چه چیزی را مسدود میکند. اگر کار شما به یک مخزن واحد محدود است و هیچ اعتبارنامه تولیدی روی دستگاه وجود ندارد، دامنه اثرگذاری احتمالی از ابتدا کوچک است. اگر نشستهای agent شما کوتاه و تحت نظارت هستند، پنجره مواجهه نیز کوتاه خواهد بود.
بهمحض اینکه اعلانها را نادیده بگیرید، پاسخ تغییر میکند. اجراهای بدون نظارت، کارهای شبانه و هر گردشکاری که در آن یک طرح را تأیید میکنید و از دستگاه دور میشوید، کنترل انسانیِ عامل مهارکننده را حذف میکنند. در این حالت، خود دستگاه باید این کار را انجام دهد. همین موضوع درباره هر چیزی که دسترسی agent را گستردهتر میکند نیز صدق میکند؛ از جمله اجرای یک coding agent روی VPS در چند مخزن بهصورت همزمان.
تصمیم واقعاً به میزان اعتماد شما به مدل مربوط نیست. موضوع این است که وقتی مدل دچار خطا میشود، چه چیزی در کنار آن قرار دارد.
FAQ
آیا یک container برای جداسازی یک coding agent کافی است؟
برای بیشتر کارها، بله؛ اما 2 شرط وجود دارد. container نباید با --privileged اجرا شود و نباید /var/run/docker.sock در آن mount شده باشد، زیرا هرکدام از این موارد مسیری برای دسترسی process به root در host ایجاد میکند. container از kernel میزبان استفاده میکند؛ بنابراین مرز جداسازی آن از یک virtual machine ضعیفتر است. اگر agent در حال اجرای code غیرقابلاعتمادی است که از اینترنت دریافت شده، از یک VM واقعی یا server جداگانه استفاده کنید.
آیا agent به sudo روی server نیاز دارد؟
خیر. دادن sudo به آن، جداسازی ایجادشده را بیاثر میکند، زیرا root میتواند تمام accountهای دیگر روی machine را بخواند. user مربوط به agent را بدون sudo ایجاد کنید و فقط دسترسی نوشتن به work directory خودش را به آن بدهید. اگر task واقعاً به نصب package نیاز دارد، بهجای root روی machine مشترک، یک machine کامل در اختیار agent قرار دهید.
چگونه به agent اجازه بدهم بدون قرار دادن SSH key من روی box، به git push کند؟
هنگام اتصال، SSH agent خود را با ssh -A forward کنید. درخواستهای امضا از طریق connection منتقل میشوند و private key روی laptop شما باقی میماند؛ بنابراین ssh -T git@github.com احراز هویت را انجام میدهد و git push بدون private key روی server کار میکند. نکته مهم این است که root روی آن server میتواند هنگام اتصال شما از socket فورواردشده استفاده کند. بنابراین روی هر machine مشترک با افراد دیگر، از deploy key محدود به repository استفاده کنید.
agent به چه اندازهای از VPS نیاز دارد؟
کار agent عمدتاً شامل ویرایش fileها، اجرای build و اجرای test است. بنابراین machine را بر اساس نیاز build اندازهگیری کنید، نه بر اساس model. یک model میزبانیشده روی سختافزار provider اجرا میشود و network traffic ایجاد میکند، اما بار محلی بسیار کمی دارد. برای کارهای scripting از 2 GB RAM شروع کنید و اگر repository، container میسازد یا چیزی قابلتوجه را compile میکند، به 8 GB افزایش دهید.
هر چند وقت یکبار باید machine را حذف و دوباره ایجاد کنم؟
وقتی وضعیت machine دیگر قابل توضیح نیست، آن را دوباره ایجاد کنید. همچنین هر زمان که احتمال میدهید credentialی روی box افشا شده باشد، این کار را انجام دهید. بین taskهای روزمره، یک checkout تازه میتواند تغییرات تدریجی را مدیریت کند. گرفتن یک snapshot پیش از اولین اجرای agent نیز یک system image پاک برای بازگشت در اختیار شما میگذارد. اگر بازسازی پرهزینه به نظر میرسد، این نشانه آن است که چیزی مهم روی machineای قرار دارد که آن را disposable نامیدهاید.