کلیدهای API شما احتمالاً در فایلهای متنی .env قرار دارند و تنها یک اشتباه در ارسال یک commit تصادفی به گیتهاب کافی است تا تمام دسترسیهای شما لو برود. در ۲۱ ژوئیه ۲۰۲۶، توسعهدهندهای به نام روبن گلیز (Ruben Glez) معماری Lokalite را معرفی کرد؛ ابزاری برای مدیریت رمزها در macOS که دقیقاً برای حل مشکل «نشت اعتبارنامهها» طراحی شده است؛ مشکلی که بهطور خاص توسط عاملهای کدنویسی (Coding Agents) تشدید شده است.
اکثر برنامهنویسان به دلیل سادگی از فایلهای .env استفاده میکنند، اما این فایلها ذاتا ناامن هستند. آنها متنیاند، بهراحتی بین پروژهها کپی میشوند، در تاریخچه شل (Shell History) نشت میکنند و هیچ مکانیزمی برای ثبت افرادی که آنها را خواندهاند وجود ندارد. سالها این موضوع یک مصالحه پذیرفتهشده بود، چون تنها کسانی که این فایلها را میخواندند، خودِ توسعهدهنده و کدهای او بودند. اما ظهور عاملهای کدنویسی این مشکل را به موضوعی حیاتی و بلندتر تبدیل کرد.
در حالی که مدیریتکنندههای ابری مانند 1Password، Doppler یا Infisical مشکلات واقعی را حل میکنند، اما اغلب نیازمند حسابهای پرداخت شده هستند و کلیدهای حساس را روی سرورهای خارجی ذخیره میکنند. برای یک توسعهدهنده مستقل، پرداخت هزینه به ازای هر کاربر برای سپردن اعتبارنامهها به سرور شخص دیگر، رویکردی معکوس به نظر میرسد. روبن گلیز میخواست واسطهها را از این چرخه حذف کند. او به دنبال سیستمی بود که همه چیز را روی دستگاه محلی، بهصورت درست رمزنگاریشده و بدون نیاز به حساب کاربری، وابستگیهای ابری یا سیستمهای تلهمتری (Telemetry) نگه دارد.
Lokalite با حذف واسطهها، رمزها را بهصورت محلی با استفاده از استاندارد AES-256-GCM از طریق Apple CryptoKit رمزنگاری میکند. کلید خزانه (Vault Key) ۲۵۶ بیتی در اولین استفاده تولید شده و در Keychain ورود macOS ذخیره میشود تا تضمین شود که کلید اصلی هرگز در داخل خود فایل خزانه قرار نمیگیرد. برای جلوگیری از دسترسی غیرمجاز، اپلیکیشن نوار ابزار پیش از نمایش هرگونه داده، نیاز به تایید Touch ID دارد و پس از مدتی عدم فعالیت، بهطور خودکار قفل میشود. اگر در حالی که خزانه قفل است، درخواستی از طریق CLI یا MCP برسد، اپلیکیشن یک اعلان Touch ID شامل نام درخواستدهنده نمایش میدهد و در صورت رد شدن درخواست، دسترسی بهطور کامل مسدود میماند.
معماری امنیت محلی
طبق مستندات این پروژه، Lokalite سه رابط مجزا برای تعامل با خزانه رمزنگاریشده ارائه میدهد که همگی از یک منبع محوری تغذیه میکنند:
- اپلیکیشن نوار ابزار برای لحظات انسانی: برای جستوجو، کپی و مشاهده رمزها استفاده میشود. رمزهایی که اخیراً کپی شدهاند به بالای لیست منتقل میشوند و یک میانبر جهانی (پیشفرض
⌘⇧Space) پنجره پاپاور را از هر جای سیستم باز میکند. - رابط خط فرمان (CLI) برای ترمینال: مجموعهای از دستورات شامل
add،get،copy،list،import،exportوrunرا فراهم میکند. - سرور MCP برای عاملها: این بخش، خزانه را به عاملهای AI متصل میکند و به آنها اجازه میدهد بدون دیدن مقادیر خام رمزها، فعالیت کنند.

برای تسهیل در پذیرش، این ابزار دستور lokalite import .env را دارد که فایلهای متنی موجود را مستقیماً به داخل خزانه میکشد. کاربران این رمزها را در قالب «پروژهها» سازماندهی میکنند و هر پروژه میتواند محیطهای متعددی داشته باشد (مانند development، staging یا production) که هر کدام مقادیر خاص خود را دارند. همچنین پروژهها میتوانند به دایرکتوری خاصی روی دیسک لینک شوند که این امر «رزولوشن خودکار پروژه» را برای عاملهای AI فعال میکند.
در هنگام اجرای یک فرآیند، دستور lokalite run امنترین گزینه پیشفرض است. این دستور رمزها را فقط به عنوان متغیرهای محیطی در محدوده (scope) همان زیر-فرآیند خاص تزریق میکند. مثالها عبارتند از:
lokalite run -- npm startlokalite run --keys OPENAI_API_KEY,ANTHROPIC_API_KEY -- claude
برای نیازهای گستردهتر در یک جلسه، دستور eval $(lokalite shell) کلیدها را به جلسه فعلی شل صادر (export) میکند. مستندات CLI درباره این مصالحه صادق هستند: این روش راحتتر است اما همه چیز را به جلسه صادر میکند که ریسک را بالا میبرد. برای به حداقل رساندن ریسک، کپیهای کلیپبورد پس از ۳۰ ثانیه بهطور خودکار پاک میشوند و بهگونهای علامتگذاری میشوند که مدیریتکنندههای پیشرفته کلیپبورد آنها را نادیده بگیرند.
حل مشکل نشت بستر متنی عاملها
وقتی عاملهای کدنویسی مثل Claude Code، Cursor یا Windsurf به یک اعتبارنامه نیاز دارند، مسیر سادهلوحانه این است که کلید را در محیط گفتگو Paste کنند. این کار خطرناک است زیرا رمز در بستر (Context) مدل قرار میگیرد و احتمالاً در لاگها یا ترانسکریپتها باقی میماند، بدون اینکه ردی از این افشا وجود داشته باشد.
Lokalite این مشکل را از طریق پیادهسازی پروتکل زمینه مدل (Model Context Protocol یا MCP) حل میکند. عامل رمزها را در چت دریافت نمیکند؛ در واقع، هرگز مقدار خام را نمیبیند. وقتی عامل ابزار get_secret را فراخوانی میکند، مکانیزم زیر رخ میدهد:
۱. سرور مقدار رمز را در یک اسکریپت شل یکبار مصرف مینویسد.
۲. سرور یک دستور source را به عامل برمیگرداند.
۳. عامل آن دستور را در شل خود اجرا کرده و متغیر را بارگذاری میکند.
۴. اسکریپت بلافاصله پس از اجرا، خود را حذف میکند.

این فرآیند تضمین میکند که کلید API خام هرگز وارد پرامپت یا تاریخچه LLM نشود. هر دسترسی در یک لاگ فعالیت ثبت میشود که با هویت عامل مهر شده است. دیمون (Daemon) سیستم، هویت فراخوان را از kernel peer PID میگیرد، بنابراین هیچ کلاینتی نمیتواند جعل کند یا پنهان کند که چه کسی درخواست رمز را داده است.
برای یکپارچگی، دستور lokalite install بهطور خودکار سرور را در Claude Code ثبت میکند. همچنین از Claude Desktop، Cursor و Windsurf با پیکربندی مشابه زیر پشتیبانی میکند:{ "mcpServers": { "lokalite": { "command": "lokalite", "args": ["mcp"] } } }
بهطور پیشفرض، سرور در حالت «فقط خواندنی» است. ابزار list_secrets نامها و توضیحات را برمیگرداند اما هرگز مقادیر را لو نمیدهد، get_secret انتقال موقت اسکریپت را مدیریت میکند و ابزارهای دیگر مانند list_projects ،list_environments و use_environment محدوده پروژه را مدیریت میکنند. حالت --read-write برای افزودن، تنظیم یا حذف رمزها در دسترس است، اما کاربر باید بهطور آگاهانه آن را فعال کند.
کنترلهای پیشرفته دسترسی و ارجاعات
Lokalite از رزولوشن پروژه برای بهبود کارایی عاملها استفاده میکند. وقتی یک فراخوانی ابزار، پروژهای را مشخص نمیکند، سرور آن را از روی دایرکتوری کاری فراخوان و مسیر لینکشده پروژه شناسایی میکند. این یعنی اگر توسعهدهنده در پوشه یک پروژه است، عامل بهطور خودکار فقط رمزهای مربوط به همان پروژه را بازیابی میکند.
برای جلوگیری از دسترسیهای بیش از حد عاملها، Lokalite سطوح دسترسی (Tiers) را برای هر رمز پیاده کرده است:
- Allow: تنظیم پیشفرض.
- Block: رد درخواست عامل بهطور کلی.
- Approve و Strict: نیاز به تایید دستی Touch ID پیش از آزادسازی مقدار، صرفنظر از هویت فراخوان.
از آنجایی که عاملها میتوانند نام خود را تغییر دهند تا شناسایی در درخت فرآیند (Process-tree) را دور بزنند، این سطوح رضایت (Consent Tiers) به عنوان گیت واقعی عمل میکنند، زیرا اعلان Touch ID به تشخیص نام عامل وابسته نیست. علاوه بر این، CLI نیز از همین قوانین پیروی میکند: دستورات lokalite get و lokalite copy اگر متوجه شوند عاملی در درخت فرآیند فراخوان وجود دارد، از چاپ هر چیزی خودداری میکنند تا مانع از این شوند که عامل با اجرای دستورات شل، سیستم دستدهی (Handoff) را دور بزند.
Lokalite همچنین مشکل فایلهای پیکربندی MCP که بهصورت متنی هستند (مانند ~/.claude.json یا .mcp.json پروژه) را حل کرده است. این فایلها اغلب توکنها را در بلوکهای متنی محیطی حمل میکنند. Lokalite اینها را با «ارجاعات» جایگزین میکند. کاربر به جای توکن، عبارت lokalite://myproject/GITHUB_TOKEN را مینویسد و دستور را در lokalite run --refs-only -- قرار میدهد.
مثال پیکربندی:{ "mcpServers": { "github": { "command": "lokalite", "args": ["run", "--refs-only", "--", "npx", "-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_TOKEN": "lokalite://myproject/GITHUB_TOKEN" } } } }
از آنجایی که ارجاع هیچ داده حساسی را حمل نمیکند، فایل را میتوان با خیال راحت در مخزن گیت Commit کرد. دستور lokalite run درست پیش از ایجاد فرآیند فرزند، ارجاع را با مقدار واقعی در محیط جایگزین میکند. اگر ارجاعی اشتباه، ناشناخته یا رد شده باشد، سیستم در حالت «شکست بسته» (Fail Closed) عمل کرده و بهجای مقدار، نام متغیر و رشته ارجاع را برمیگرداند.
واقعیت مدل تهدید
روبن گلیز صراحتاً بیان میکند که این سیستم «ضد گلوله» (Bulletproof) نیست. ابزارهای امنیتی که تظاهر به شکستناپذیری میکنند، خطرناکتر از یک فایل متنی هستند. مرزهای مشخصی برای این مدل امنیتی وجود دارد:
- متادادهها رمزنگاری نشدهاند: نام رمزها، توضیحات، نام پروژهها و لاگ دسترسیها بهصورت رمزنگارینشده در فایل خزانه هستند. اینها نشان میدهند از چه سرویسهایی استفاده میکنید، اما خود اعتبارنامهها را لو نمیدهند. این بخشها به مجوزهای استاندارد دایرکتوری Home در macOS و FileVault متکی هستند.
- مرز اعتماد: مرز واقعی اعتماد، یک جلسه (Session) باز و بازشده در macOS است، مشابه آنچه در
~/.aws/credentialsمیبینیم. - قابلیتهای عامل: در حالی که مکانیزم انتقال، مقادیر را از ترانسکریپتها دور نگه میدارد، عاملی که بتواند نام یک رمز را حدس بزند، همچنان میتواند آن را در شلی که کنترل میکند بارگذاری کند.
با این وجود، بهبود نسبت به فایلهای .env ملموس است: مقادیر در حالت استراحت رمزنگاری شدهاند و هر دسترسی ثبت میشود. این سیستم یک آسیبپذیری متنی را با یک مدل امنیتی محدود و حسابرسیشده جایگزین میکند.
یک لایه حفاظتی ثانویه نیز وجود دارد: کلاینت MCP. ابزارهایی مثل Claude Code ممکن است پیش از اینکه فراخوانی به Lokalite برسد، بررسیهای دسترسی خود را انجام دهند. کلاینت تصمیم میگیرد که آیا ابزار اصلاً اجرا شود یا خیر، و Lokalite تصمیم میگیرد که آیا رمز خاص آزاد شود یا نه. به کاربران هشدار داده شده که Allowlist کردن ابزار برای متوقف کردن اعلانها، سوال کلاینت را برای تمام رمزهای پروژه (از جمله کلیدهای Production) حذف میکند. در چنین مواردی، علامتگذاری رمزهای حساس به عنوان approve تضمین میکند که Touch ID همچنان آخرین دروازه امنیتی باشد.
ساخته شده در زمان چرت زدن کودک
توسعه Lokalite در قطعات کوچک اتفاق افتاد. روبن گلیز این پروژه را در دوران مرخصی زایمان، در پنجرههای کوتاهی که پسرش «لئو» خواب بود، طراحی کرد. چون مدیریت رمزها از قطعات کوچک و تعریفشده تشکیل شده است، با ریتم نوشتن یک مشخصات (Spec) کوتاه و اجرای آن در زمان چرت زدن کودک کاملاً سازگار بود.
منطق برنامه ساده بود اما پرداخت رابط کاربری (UI polish) یک فرآیند تکرار شونده بود. گلیز از SwiftUI برای ساخت اپلیکیشن نوار ابزار استفاده کرد و با چالشهایی مثل اندازهبندی صحیح پاپاورها برای پروژههای خالی، ایجاد حالتهای خالی (Empty States) بدون حاشیههای خاکستری و حفظ یک چیدمان متوازن سه ستونی هنگام تغییر اندازه پنجره دستوپنجه نرم کرد. ظاهر و حس نهایی برنامه حاصل چندین دور پالایش کوچک بود.
آیکون نوار ابزار یک «آرمادیس» (ورزون) است. این ماسکوت به این دلیل انتخاب شد که آرمادیس هنگام احساس تهدید، خودش را به شکل یک توپ بسته در میآورد و محافظت خود را با خود حمل میکند، بهجای اینکه به یک لانه خارجی تکیه کند. این دقیقاً بازتاب فلسفه خزانه محلی (Local-first) است: متصل نگه داشتن محافظت به دادهها در دستگاه خود کاربر.
اگر میخواهید کلیدهای خود را از حالت متنی خارج کنید، میتوانید ابزارها را از طریق Homebrew نصب کنید:
- CLI:
brew install RubenGlez/lokalite/lokalite - GUI:
brew install --cask RubenGlez/lokalite/lokalite-app
گام بعدی شما
- اگر از Cursor یا Claude Code استفاده میکنید، فایلهای
.envخود را باlokalite importبه خزانه محلی منتقل کنید. - تمام توکنهای حساس در فایلهای کانفیگ JSON را با فرمت
lokalite://جایگزین کنید تا ریسک Push تصادفی به گیت-هاب حذف شود. - برای رمزهای محیط Production، سطح دسترسی را روی
Strictقرار دهید تا هر فراخوانی توسط Agent نیاز به تایید Touch ID داشته باشد.
اما داستان سختافزاری تأمین امنیت این دادهها در سطح هسته سیستمعامل حتی پیچیدهتر است — به تحلیل ما دربارهی مدیریت حافظه در معماریهای ARM مراجعه کنید.




گفتگو