اگر پلتفرمی میسازید که به کاربران اجازه میدهد کد خودشان را آپلود کنند، در واقع دارید یک اسب ترویان را به زیرساخت خود دعوت میکنید. Nango، پلتفرمی برای یکپارچگی APIها که رویکردی کد-محور (code-first) دارد، هر روز با این ریسک دستوپنجه نرم میکند؛ زیرا مشتریان آن منطقهای سفارشی را برای اتصال اپلیکیشنهایی مانند Salesforce، Google Calendar، Slack و صدها API دیگر مستقر میکنند.
طبق یک تحلیل فنی که در ۹ ژوئن ۲۰۲۶ منتشر شد، این شرکت اکنون ماهانه بیش از ۱۵۰ میلیون از این توابع غیرقابلاعتماد را در اشکال مختلف بار کاری پردازش میکند. اجرای کدهای شخص ثالث، یک بازی تعادلی میان امنیت و عملکرد است. برای Nango، مخاطرات بسیار بالا است زیرا آنها سه شکل متمایز از بار کاری را مدیریت میکنند:
الزامات بار کاری (Workload Requirements)
- فراخوانیهای آنی (Actions): این توابع برای یک کاربر یا عامل (Agent) اجرا میشوند و باید سریعاً شروع و پایان یابند، زیرا «شروعهای سرد» (Cold Starts) تأثیر منفی بر تجربه کاربر میگذارد.
- کارهای طولانیمدت (Syncs): اینها دادهها را در پسزمینه تکثیر میکنند و گاهی میلیونها رکورد را طی چندین ساعت پردازش میکنند. این توابع به قابلیت «اجرای قابلازسرایی» (Resumable Execution) نیاز دارند.
- رویدادهای انفجاری (Webhooks): این درخواستها در جهشهای غیرقابلپیشبینی میرسند و سیستم باید بتواند سیل ناگهانی دادهها را جذب کند.
چالش اصلی این است که اطمینان حاصل شود یک اسکریپت معیوب یا مخرب متعلق به یک مشتری، نتواند سیستم را کرش کند، اسرار سازمانی (Secrets) را بدزدد یا منابع CPU و حافظه را برای سایر کاربران محدود کند. الزامات Nango برای کدهای غیرقابلاعتماد بسیار سختگیرانه است: توابع باید از سیستمهای داخلی (دیتابیسها، اسرار و شبکهها)، از سایر مستاجران (Tenants) و حتی از سایر اجراهای همان مشتری ایزوله شوند. علاوه بر این، سیستم باید کارایی هزینه و انعطافپذیری را حفظ کند تا مجبور به پرداخت هزینه برای محاسبات بدونکار (Idle) یا مقیاسبندی دستی ناوگان سرورها نباشد.
شکست سندباکسهای درون-پروسهای (In-Process Sandboxing)
Nango مسیر خود را با استفاده از vm2 آغاز کرد که یک سندباکس محبوب برای Node.js است. در این رویکرد، کد مشتری در همان پروسهی Worker اجرا میشد و سیستم به مرزهای نرمافزاری تکیه میکرد تا دسترسی به دیتابیسها و شبکههای داخلی را مسدود کند. این روش ساده بود و به زیرساخت اضافی نیاز نداشت، اما فاقد یک محیط امنیتی واقعی بود.
در سال ۲۰۲۳، پایداری این مدل زمانی فروپاشید که نگهدارنده پروژه vm2، پس از مجموعهای از آسیبپذیریهای «فرار از سندباکس» (Sandbox-escape)، پروژه را آرشیو کرد. این باگها ثابت کردند که کد داخل سندباکس میتواند به میزبان دسترسی پیدا کرده و روی Worker اجرا شود. این اتفاق Nango را مجبور کرد بپذیرد که یک سندباکس جاوااسکریپتی درون-پروسهای، یک مرز امنیتی واقعی نیست؛ اشتراک یک پروسه با کد غیرقابلاعتماد به این معناست که شما تنها یک «فرار» با یک مشکل جدی فاصله دارید.
انتقال به اجراکنندههای مستقل (Independent Runners)
برای حل مشکل فرار از سندباکس، Nango سیستم خود را به دو بخش تقسیم کرد: یک توزیعکننده (Dispatcher) و یک اجراکننده (Runner). توزیعکننده، کد هر مشتری را از طریق HTTP به یک Runner میسپارد و تضمین میکند که سیستم اصلی هرگز پروسهای را با کد غیرقابلاعتماد به اشتراک نمیگذارد.

جزئیات معماری Runner
- مقیاسپذیری مستقل: هر مشتری Runner طولانیمدت مخصوص به خود را دریافت میکند. اینها بهطور مستقل مقیاس میشوند که اجازه میدهد برای حسابهای سنگین، CPU بیشتر، حافظه بیشتر یا نسخههای (Replicas) اضافی تخصیص یابد.
- ارکستراسیون: یک لایه ارکستراسیون، Runnerها را بر اساس تقاضا فعال میکند، موارد بدونکار را بازنشسته میکند و بهروزرسانیها را در صدها مورد مدیریت میکند. زمانبندی (Scheduler) پشت توزیعکننده ابتدا روی Temporal اجرا میشد و سپس به Postgres منتقل شد.
- ایزولاسیون شبکه: Runnerها هیچ دسترسی مستقیمی به دیتابیس ندارند. برای خواندن یا نوشتن رکوردها، یک تابع باید متدی از SDK مانند
nango.batchSave(...)را فراخوانی کند. - سرویس Persist: متد SDK از طریق شبکه با یک سرویس مجزا به نام Persist Service ارتباط برقرار میکند؛ سرویس Persist با دیتابیس صحبت میکند، اما Runner هرگز این کار را نمیکند.
با اجرای این موارد به عنوان سرویسهای مجزا در Render، هر Runner تنها کد مشتری و حداقل موارد مورد نیاز برای عملکرد را در اختیار دارد.
مقیاسپذیری با AWS Lambda
تا اواخر سال ۲۰۲۵، مدل Runner مجزا در زمینه «عدالت در منابع» و «قابلیت مشاهده» (Observability) به بنبست رسید. چون یک Runner تمام اجراهای یک مشتری را با هم مدیریت میکرد، یک همگامسازی عظیم داده که میلیونها رکورد را تکثیر میکرد، میتوانست سایر توابع آن مشتری را از منابع محروم کند. عیبیابی نیز یک کابوس بود؛ وقتی یک Runner با کمبود حافظه مواجه میشد، غیرممکن بود که بهطور دقیق تشخیص دهند کدام یک از هزاران تابع باعث نشت حافظه (Memory Leak) شده است.
Nango برای دستیابی به ایزولاسیون microVM به AWS Lambda مهاجرت کرد. اکنون هر اجرا در microVM مجازیسازی شده سختافزاری خود با کرنل اختصاصی اجرا میشود که بسیار قویتر از یک پروسه مشترک است. این تغییر، قابلیت مشاهده فوری ایجاد کرد: مشکلات حافظه و CPU اکنون مستقیماً به تابعِ مربوط به یک اتصال خاص اشاره میکنند که در لاگهای همان تابع قابل مشاهده است، نه یک شکست مبهم در Runner. برای یک تیم کوچک که از صدها مشتری پشتیبانی میکند، این امر زمان عیبیابی را بهشدت کاهش داد.

با این حال، محدودیت حداکثری ۱۵ دقیقهای Lambda با همگامسازیهای طولانیمدت Nango در تضاد بود. تیم فنی این مشکل را در سطح محصول با معرفی سقف ۱۰ دقیقهای برای هر اجرا در Syncها و قابلیت «نقاط بازگشت» (Checkpoints) حل کرد. این ویژگی اجازه میدهد یک Sync بهجای تکیه بر یک اجرای طولانی، در چندین اجرای متوالی از سر گرفته شود. Nango اشاره میکند که یک اجرای قابلازسرایی برتر از یک شغل ۲۴ ساعته است، زیرا شغلی که در ساعت ۲۳ میمیرد و از صفر شروع میشود، خود نوعی شکست است.
حل شکاف ایزولاسیون مستاجر (Tenant Isolation Gap)
سرویس Lambda اجراها را ایزوله میکند، اما برای حفظ سرعت، محیطهای «گرم» (Warm) را بازاستفاده میکند. وقتی یک تابع تمام میشود، AWS ممکن است فراخوانی بعدی را به همان محیط گرم هدایت کند. اگرچه محیطها هرگز بین حسابهای مختلف AWS به اشتراک گذاشته نمیشوند، اما برای Nango، این بدان معنا بود که دو مشتری مختلف میتوانند بهطور متوالی در یک محیط گرم قرار گیرند.
حتی با وجود اینکه Nango یک سندباکس JS را داخل هر Lambda اجرا میکند، آنها میپذیرند که یک مهاجم determined میتواند از آن فرار کند. در یک محیط مشترک، یک تابع فرار کرده میتواند به فراخوانی مشتری بعدی، از جمله اعتبارنامههای (Credentials) ارسال شده برای آن، دسترسی پیدا کند. ایزولاسیون سختافزاری زمانی کمک نمیکند که یک محیط گرم به ترتیب به دو مشتری خدمت کند.
برای بستن این شکاف، Nango هر مشتری را به توابع Lambda خاص خود «پین» (Pin) کرد. این تضمین میکند که یک محیط گرم فقط برای مشتریای بازاستفاده شود که قبلاً از آن سرویس گرفته است. بهای این تصمیم، عملکرد بود: نرخ «شروع سرد» از کمتر از ۱٪ فراخوانیها به حدود ۹٪ جهش کرد و چندین ثانیه تأخیر به مسیر درخواست Actionها افزود. برای کاهش این اثر برای کاربران پولی، Nango از فراخوانیهای دورهای no-op (بدون عملیات) برای گرم نگه داشتن توابع استفاده میکند.

چشمانداز گستردهتر ایزولاسیون
تکامل Nango بازتابی از یک روند گستردهتر در صنعت است که در آن اجرای کدهای غیرقابلاعتماد به دلیل عوامل هوش مصنوعی (AI Agents) در حال تبدیل شدن به یک جریان اصلی است. این شرکت اشاره کرد که پلتفرمهای دیگر نیز به ایزولاسیون در سطح سختافزار رسیدهاند: E2B و Fly از microVMها استفاده میکنند، در حالی که Modal از gVisor بهره میبرد.
آنها بهطور صریح از رویکرد V8-isolate در Cloudflare Workers دوری کردند. اگرچه V8 سریع است، اما مرز ضعیفتری را میپذیرد؛ باگهای فرار از کانتینر runc در سال ۲۰۲۵ یادآور این بود که یک کرنل مشترک امن نیست. علاوه بر این، V8 برای Nango مناسب نبود زیرا توابع مشتریان بستههای دلخواه npm را وارد میکنند که V8 نمیتواند آنها را بهطور ایمن سندباکس کند.

درسهایی از مقیاس
این سفر معماری نشان میدهد که امنیت یک فرآیند تدریجی است. بحثهای داخلی تیم دو دیدگاه را برجسته کرد: یکی اینکه آنها در حال «خم کردن» یک Runtime هستند تا با نیازهایی سازگار شود که برای آن ساخته نشده است، و دیگری اینکه این یک پیشرفت تدریجی و درست است که بزرگترین ریسکهای فعلی را میبندد.
برداشتهای کلیدی آنها عبارتند از:
- شناسایی مرزهای واقعی: یک سندباکس درون-پروسهای ایمن به نظر میرسد اما قابل فرار است؛ نباید آن را به عنوان ایزولاسیون واقعی شمرد.
- ترسیم زودهنگام خط امنیتی: هدف اصلی آنها این بود که تضمین کنند کد مشتری هرگز به سیستمهای داخلی نمیرسد و یک مشتری هرگز به مشتری دیگر دسترسی پیدا نمیکند.
- صداقت درباره راهکارهای موقت (Workarounds): پذیرفتن اینکه از راهکارهای موقت استفاده میکنند، مانع از آن میشود که این روشها بهطور بیصدا به معماری دائمی تبدیل شوند.
- ترجیح کارهای قابلازسرایی: اجراهای کوتاه و قابلازسرایی در برابر شکستها دوام میآورند و با محدودیتهای نرخ (Rate-limits) بهتر از شغلهای طولانیمدت عمل میکنند.
اجرای ایمن کدهای دیگران کاری است که هرگز بهطور کامل تمام نمیشود. گام بعدی Nango، ایزولاسیون دقیقتر تا سطح هر تابع کد است، بهطوری که مرز Lambda یک تابع واحد را در بر بگیرد و سطح حمله را بیشتر کاهش دهد. برای توسعهدهندگان، این ثابت میکند که سندباکسهای سطح نرمافزار بهندرت برای محیطهای با ریسک بالا کافی هستند؛ تنها مرز قابلاعتماد، ایزولاسیون در سطح سختافزار است.




گفتگو