فایلسیستم یک زبان سیاستگذاری نیست
دسترسی کامل به دیسک یک اعطای دودویی روی درختی از فایلهاست. به یک پرسش پاسخ میدهد: آیا این فرایند میتواند این مسیر را باز کند؟ نمیتواند به پرسشی که برای یک عامل خودمختار اهمیت دارد پاسخ دهد: این فرایند چرا این فایل را میخواند، و آیا آن هدف توجیهکننده خواندن است؟
دو خواندن از یک مسیر را در نظر بگیرید. یک عامل در حال حل یک وابستگی، یک فایل پیکربندی را میخواند تا مکان یک رجیستری بسته را کشف کند. یک عامل در حال آمادهسازی یک خلاصه پشتیبانی، یک مخزن اعتبارنامه را میخواند تا یک توکن API استخراج کند. در لایه فایلسیستم اینها عملیات یکسانی هستند. مدل مجوز هیچ واژگانی برای قصد ندارد، بنابراین نمیتواند آنها را تفکیک کند. اعطا یا حاضر است یا غایب، و زمانی که حاضر باشد به هر خواندنی که عامل در طول عمر فرایند انجام میدهد اعمال میشود.
تصمیم Apple برای سختتر کردن دسترسی کامل دیسک macOS برای عاملهای هوش مصنوعی، پاسخی معقول به تغییری واقعی در پروفایل ریسک است. یک عامل یک اپراتور انسانی نیست. با سرعت ماشین اجرا میشود، میتواند فراخوانیهای ابزار را بدون توقف برای قضاوت زنجیره کند، و ممکن است بر اساس دستورالعملهایی عمل کند که از همان کانالی میآیند که دادههای خواندهشده از آن میآیند. با این حال، کاهش خطر همچنان نسخهای درشتتر از همان ابتدایی است: یک اعلان، یک دیالوگ رضایت، یک اعطای محدودتر. چه کسی میتواند بخواند را محدود میکند، اما همچنان نمیتواند بیان کند که خواندن برای چیست. واحد واقعی اعتماد، سهگانه عامل، کلاس داده و هدف است. هیچ مدل مجوز فایلسیستمی نمیتواند آن سهگانه را بیان کند، زیرا فایلسیستم وظیفه عامل را نمیداند.
کلاسهای داده بهعنوان واحد دامنهبندی
یک جایگزین عملی این است که از تلقی فایلسیستم بهعنوان مرز سیاستگذاری دست برداریم و کلاس داده را بهعنوان واحد دامنهبندی در نظر بگیریم. دادههای قابل خواندن را پیش از اجرای هر عاملی به سطوح طبقهبندی کنید:
- عمومی: مستندات، مطالب مرجع منتشرشده، مجموعهدادههای باز.
- عملیاتی: پیکربندی سرویس، مانیفستهای استقرار، لاگهای غیرحساس.
- شخصی: سوابق کاربر، رونوشتهای پشتیبانی، هر چیزی که یک فرد را شناسایی کند.
- محرمانه: اعتبارنامهها، توکنها، کلیدهای خصوصی، مواد امضا.
یک عامل سطوحی را که نیاز دارد بهعنوان بخشی از مانیفست اجرای خود اعلام میکند. یک عامل بازیابی که مستندات عمومی را خلاصه میکند، public را اعلام میکند. یک عامل تریاژ که رونوشتهای پشتیبانی را میخواند، public و personal را اعلام میکند. یک عامل که اعتبارنامهها را میچرخاند secret را اعلام میکند، و آن اعلام باید بهقدری غیرمعمول باشد که بازبینی را فعال کند.

اجرا باید در لایه ابزار باشد، نه لایه سیستمعامل. عامل یک ولوم مانتشده و یک مسیر دریافت نمیکند. توابعی دریافت میکند: read_public_doc(id)، read_support_ticket(id)، read_credential_ref(name). هر تابع مجموعه سطوح اعلامشده عامل را با سطح دادهای که در شرف بازگرداندن آن است بررسی میکند. اگر عامل secret را اعلام نکرده باشد، تابع اعتبارنامه یک رد را برمیگرداند، نه یک دسته فایل. چون کد خود عامل هرگز یک مسیر فایلسیستم را نمیبیند، نمیتواند با باز کردن مستقیم یک فایل ارتقا یابد. مرز یک ویژگی رابط است، نه سطح دسترسی فرایند.
این همچنین یک رد حسابرسی تولید میکند که یک لاگ فایلسیستم نمیتواند بازسازی کند. یک لاگ فایلسیستم ثبت میکند که فرایند 4821 فایل /etc/credentials/store را باز کرده است. یک لاگ لایه ابزار ثبت میکند که عامل triage-v3، با هدف اعلامشده summarise open support tickets، درخواست read_support_ticket(88213) کرده و یک رکورد در سطح personal دریافت کرده است. وقتی یک خواندن میانسطحی رخ میدهد، لاگ هدف اعلامشده را در کنار آن حمل میکند. این تفاوت بین دانستن اینکه یک فایل باز شده و دانستن اینکه عامل در تلاش برای انجام چه کاری بوده است، است.
یک مکانیزم مشخص
الگو یک پوشش قابلیت با یک بررسی سطح و یک مهر هدف است. بهطور خلاصه:
TIERS = {"public": 0, "operational": 1, "personal": 2, "secret": 3}
def guarded_read(agent, resource, tier):
if TIERS[tier] > TIERS[agent.declared_max_tier]:
audit.deny(agent.id, resource, tier, agent.purpose)
raise ScopeError(f"{agent.id} is not scoped for {tier}")
audit.allow(agent.id, resource, tier, agent.purpose)
return resource.fetch()
حداکثر سطح اعلامشده عامل در شروع اجرا ثابت میشود. گسترش آن در میانه اجرا یک تغییر پیکربندی نیست؛ یک اجرای جدید با مانیفست جدید و تأیید جدید است. جریان حسابرسی فقط-افزودنی است و با هویت عامل و هدف اعلامشده کلید میخورد، بنابراین یک بازبین میتواند نه فقط آنچه خوانده شده بلکه اینکه کدام وظیفه انگیزه هر خواندن بوده را بازسازی کند.
این یک سندباکس به معنای سیستمعاملی نیست. یک لایه سیاستگذاری است که فرض میکند عامل منحصراً از طریق ابزارهای پوششدادهشده با جه
این چه هزینهای دارد
طبقهبندی سطح دستی است، و دچار انحراف میشود. یک منبع داده جدید میرسد؛ کسی به آن سطحی اختصاص میدهد؛ شش ماه بعد منبع حاوی فیلدی است که قبلاً نداشت، و سطح اکنون نادرست است. طبقهبندی به یک مالک و یک آهنگ بازبینی نیاز دارد، و آن مالک یک هزینه مستمر واقعی است. هیچ راه خودکاری برای استنتاج سطح صحیح یک فیلد از محتوای آن وجود ندارد، و تلاشها برای انجام این کار معمولاً یا بیش از حد مجاز یا بیش از حد پرنویز برای اعتماد هستند.
اجرا در لایه ابزار فرض میکند که عامل نمیتواند لایه ابزار را دور بزند. این در داخل یک سندباکس بدون دسترسی مستقیم به syscall و بدون خروج شبکه خارج از رابطهای پوششدادهشده درست است. لحظهای که عامل در فرایندی اجرا شود که میتواند فایلها را باز کند، زیرفرایندها را ایجاد کند، یا مستقیماً به شبکه دسترسی یابد، نادرست است. لایه سیاستگذاری تنها بهقدر جداسازی زیرین خود قوی است، که یعنی طراحی به هر دو نیاز دارد: رابطهای ابزار سطحبندیشده و یک رانتایم که واقعاً نتواند از آنها فرار کند.
معاوضه عمدی است. کار طبقهبندی بیشتر در ابتدا، یک مالک برای انحراف سطح، و یک رانتایم که جداسازی را اجرا میکند — در ازای یک سطح مواجهه که خوانا، قابل اجرا و قابل حسابرسی است. یک اعطای فایلسیستم ارزان برای صدور و غیرقابل استدلال پس از واقع است. یک اعلام سطح گران برای نگهداری و در زمان بازبینی خوانا است.
یک قاعده طراحی
هرگز به یک عامل همان ابتدایی دسترسی را که به یک اپراتور انسانی میدهید اعطا نکنید. انسان قضاوتی دارد که عامل ندارد؛ عامل توان عملیاتی دارد که انسان ندارد. یک انسان با دسترسی کامل به دیسک آنچه وظیفه نیاز دارد را میخواند و متوقف میشود. یک عامل با دسترسی کامل به دیسک آنچه سیاست یا پرامپتش او را به خواندنش هدایت میکند را میخواند، با سرعتی که هیچ بازبینی انسانی نمیتواند با آن برابری کند. ابتدایی باید آن عدم تقارن را منعکس کند نه نادیده بگیرد.
خواندنها را به باریکترین کلاس دادهای که وظیفه را برآورده میکند محدود کنید. هر گسترشی را بهعنوان تغییری که نیازمند تأیید مجدد است در نظر بگیرید، نه بهعنوان یک کلید پیکربندی. اگر یک عامل برای یک مرحله از یک خط لوله به داده personal نیاز دارد، آن مرحله باید یک اجرای جداگانه با مانیفست خودش باشد، نه یک اعطای گستردهتر برای کل خط لوله.
رابطهای پرسوجو-شکل را به رابطهای داده-شکل ترجیح دهید. تابعی که نرخ ارز فعلی برای یک جفت ارز را برمیگرداند پرسوجو-شکل است: عامل بیان میکند چه نیاز دارد و دقیقاً همان را دریافت میکند. یک ولوم مانتشده از فایلهای CSV داده-شکل است: عامل همه چیز را دریافت میکند و باید تصمیم بگیرد چه بخواند. رابطهای پرسوجو-شکل هدف را در محل فراخوانی صریح میکنند، که دقیقاً همان جایی است که سیاست باید در آن زندگی کند. رابطهای داده-شکل تصمیم را به داخل عامل میرانند، جایی که برای مدل مجوز و اغلب برای لاگ حسابرسی نامرئی است.
سختتر کردن دسترسی کامل دیسک توسط Apple نشانهای است که صنعت متوجه شده عاملها نوع متفاوتی از اصل هستند. گام بعدی این است که از گسترش ابتدایی فایلسیستم دست برداریم و شروع به بیان سهگانهای کنیم که واقعاً بر مواجهه حاکم است: کدام عامل، خواندن کدام کلاس داده، برای کدام هدف. آن سهگانه سیاست است. فایلسیستم فقط جایی است که بایتها اتفاقاً در آن زندگی میکنند.
