إعطاء سرّ لوكيل برمجة دون وضعه في الموجّه أبدًا

يحتاج الوكيل إلى مفتاح Stripe أو كلمة مرور قاعدة بيانات ليشغّل أمره. الصقها في المحادثة فتذهب إلى سجل المحادثة على قرصك، وإلى مزوّد النموذج، وأحيانًا داخل commit. القاعدة التي وصلنا إليها بعد ثلاثة أخطاء ارتكبناها بأنفسنا: السر يصل إلى الوكيل عبر متغير بيئة، ولا شيء غيره.

الوضع هو نفسه دائمًا. وكيل في منتصف مهمة، وعليه استدعاء واجهة Stripe التجريبية لديك، أو تشغيل ترحيل على قاعدة بيانات staging، أو الدفع إلى سجلّ حزم خاص. يطلب المفتاح. المفتاح عندك في مدير كلمات المرور، والوكيل ينتظر، وأسرع شيء في العالم هو لصقه في المحادثة.

هذا اللصق هو اللحظة التي يخرج فيها المفتاح من سيطرتك. ليس لأن النموذج خبيث، بل لأن الموجّه كائن يُخزَّن ويُمرَّر: يذهب إلى ملف سجل المحادثة على قرصك، ويذهب إلى مزوّد النموذج، ويُنسخ مع كل إعادة محاولة ومع كل وكيل فرعي يرث المحادثة.

نحن نطوّر AgentsRoom، تطبيق سطح مكتب يشغّل وكلاء البرمجة، فكان علينا حلّ هذا لأنفسنا. أخطأنا ثلاث مرات في سبتمبر 2026. إليك القاعدة التي وصلنا إليها، والأخطاء الثلاثة التي أنتجتها، وكيف تطبّقها سواء استخدمت تطبيقنا أو لا.

الإجابة القصيرة

  • السر يصل إلى الوكيل عبر متغير بيئة، ولا شيء غيره. لا رسالة، ولا تذكرة، ولا مهارة، ولا خيار في سطر الأوامر.
  • الوكيل يستخدم $NAME، لا القيمة أبدًا. يستبدله الـ shell عند تشغيل الأمر.
  • خزّن القيمة مرة واحدة، خارج المستودع، مشفَّرة بسلسلة مفاتيح نظامك، وأشِر إليها بالاسم في كل مكان آخر.
  • السر الذي مرّ في محادثة محروق. غيّره، ثم نظّف خلفك.
  • الحجب شبكة أمان، لا خطة. يلتقط ما يشبه مفتاحًا، لا كلمة مرور قاعدة بيانات تُقرأ ككلمة عادية.

لماذا هذا اللصق أسوأ مما يبدو

ثلاثة أشياء تحدث في اللحظة نفسها، والأول وحده هو الظاهر.

يذهب إلى مزوّد النموذج. هذا الجزء يراه الجميع. مفتاحك صار الآن في جسم طلب على بنية تحتية تخصّ شخصًا آخر، داخل محادثة لا تستطيع تعديلها.

يذهب إلى قرصك، كنصّ صريح. يحتفظ Claude Code وCodex وAntigravity CLI وغيرها بسجل المحادثة لتتمكن من استئنافها. ذلك الملف جالس في مجلد المنزل لديك، غير مشفَّر، ما دام الـ CLI يحتفظ بتاريخه. ابحث مرة واحدة عن السلسلة sk- في سجلات محادثاتك وانظر ما الذي يعود.

ينتشر على الجوانب. المحادثة هي ذاكرة الوكيل، فكل ما ينسخ المحادثة ينسخ المفتاح: جلسة مستأنفة، ووكيل مُشتقّ، ووكيل فرعي أُطلق بسياق الأب، وملخّص مكتوب في ملف من ملفات المشروع. رأينا مفتاحًا يسافر من رسالة محادثة إلى وصف تذكرة ثم إلى الرسالة الأولى لوكيل ثانٍ، دون أن يفعل أحد شيئًا خاطئًا.

وشبكة الأمان المعتادة لا تصمد. الحجب في المخرجات يعمل بالأنماط: sk-…، وglpat-…، وشكل JWT. لا يستطيع أن يعرف أن thursday-harbour-71 هي كلمة مرور قاعدة بيانات staging لديك. في تطبيقنا نحن نحجب القيم المطابِقة من مخرجات الطرفية، وما زلنا نعتبر ذلك شبكة تحت الأرجوحة، لا الأرجوحة نفسها.

قاعدة الباب الواحد

ها هي، في سطر واحد: بيانات الاعتماد تصل إلى الوكيل عبر متغير بيئة للعملية التي يعمل فيها، ولا عبر أي قناة أخرى.

كل ما عدا ذلك نصّ حرفي. رسالة تكتبها، ووصف تذكرة، وملف مهارة، وموجّه نظام، وخيار في سطر الأوامر: كل هذا يقرؤه إنسان أو نموذج، فالسر المكتوب هناك سرّ منشور.

سطر الأوامر يستحق جملته الخاصة، لأنه يبدو أأمن من رسالة محادثة وهو ليس كذلك. القيمة في --api-key=… مرئية لكل عملية على الجهاز عبر ps، وتهبط في تاريخ الـ shell لديك، ويسجّلها كل ما يسجّل الأمر الذي أُطلق، وتظهر في أدوات التشخيص التي تعيد طباعة سطر العملية أمامك. متغير البيئة لعملية واحدة تقرؤه تلك العملية وroot. مساحة أصغر، والراحة نفسها.

أما الوكيل فلا يحتاج القيمة أبدًا. يحتاج أن يكتب هذا:

curl -H "Authorization: Bearer $STRIPE_SECRET_KEY" https://api.stripe.com/v1/charges

يستبدل الـ shell قيمة $STRIPE_SECRET_KEY عند التنفيذ. الوكيل كتب سبعة عشر حرفًا وعلامة دولار. وسجل محادثته يحتوي سبعة عشر حرفًا وعلامة دولار.

كيف يعمل هذا في تطبيقنا

الآلية أقل أهمية من الشكل، لكن الشكل أسهل في النقل حين ترى تنفيذًا واحدًا له.

خزنة واحدة، ملف واحد. يحفظ AgentsRoom الأسرار في ملف واحد داخل مجلد المنزل لديك، بأذونات 0600، مشفَّرًا عبر سلسلة مفاتيح نظام التشغيل، ويُعاد تأكيد ذلك عند كل كتابة. لا شيء يُزامَن إلى خادم، ولا شيء يعبر إلى حاسوب آخر: السر ملك للجهاز الذي يحمله. وإن كانت سلسلة المفاتيح غير متاحة، يفشل الحفظ بدل الرجوع إلى النص الصريح.

تحفظ القيمة مرة واحدة. الأوامر والاتصالات > الأسرار، في أي مشروع. اسم (حروف وأرقام ونقطة وشَرطة وشَرطة سفلية، 64 حرفًا، فيكون صالحًا كاسم متغير بيئة) وقيمة، تُكتب في حقل كلمة مرور. السطر الذي يظهر يعرض الاسم ومرجعه، {{secret:STRIPE_SECRET_KEY}}، وزرًّا ينسخ المرجع. لا يوجد زر كشف ولا زر نسخ للقيمة، لأنه لا يوجد أي مسار في الشيفرة يعيد قيمة إلى الواجهة.

تشير إليه حيث تُبنى البيئة. تعديل الوكيل > متقدّم > متغيرات البيئة، أو إعدادات المشروع، أو إعدادات المزوّد، أو سطر أوامر تطوير:

STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}}

عند الإطلاق، تستبدل العملية الرئيسية القيمةَ في بيئة الطرفية التي توشك على إنشائها. الواجهة لا تراها أبدًا، والوكيل لا يراها أبدًا، والهاتف لا يراها أبدًا. صفحة مدير الأسرار تستعرض الشاشات.

الوكيل يكتشف أسماءً، لا قيمًا. الوكيل الموصول بأدوات MCP لدينا يستطيع استدعاء secrets_list واسترجاع قائمة الأسماء الموجودة على ذلك الجهاز. وهذا يكفي ليكون مفيدًا: يستطيع أن يقول «لديك STRIPE_SECRET_KEY محفوظ، أضف STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}} إلى بيئة هذا الوكيل وسأستخدم $STRIPE_SECRET_KEY». لا يستطيع قراءة القيمة، حتى وهو ينفّذ أمرًا يستعملها.

ثلاثة أخطاء أطلقناها

القاعدة أعلاه تبدو بديهية حين تُكتب. إنها ندبة ثلاثة أخطاء، كلها في سبتمبر 2026، وكلها أبلغ عنها مستخدمون.

مرجع مذكور في تذكرة كان يخرج مُستبدَلًا

19 سبتمبر. وثّق Robert ربطًا في وصف تذكرة، وهو STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}} المعقول تمامًا، كي يعرف من يلتقط التذكرة ما الذي عليه ضبطه. قراءة التذكرة عبر الـ API كانت تعيد المرجع سليمًا. لكن الوكيل المُطلَق من تلك التذكرة كان يستقبل القيمة في رسالته الأولى.

كان السبب تفصيلًا في السباكة ذا نتيجة حقيقية. موجز التذكرة يصبح الموجّه الأول للوكيل، وكان يسافر داخل متغير بيئة في أمر الإطلاق. ومحلّل المراجع لدينا كان يستبدل كل قيم البيئة، فاستبدل الموجّه أيضًا. ذهب المفتاح إلى القرص وإلى مزوّد النموذج. تغيير المفتاح واجب، لا مفرّ منه.

كان الإصلاح أن نجعل أمر إطلاق الوكيل حرفيًا: حين تحمل البيئة معرّف وكيل، يُترك المتغير الذي يحتوي الموجّه الأول دون مساس. وأمر التطوير الذي يستخدم المتغير نفسه لا يحمل معرّف وكيل فيُستبدَل كما كان. وقبلنا أثرًا جانبيًا عن قصد: المرجع المكتوب في خيارات CLI الخاصة بوكيل لا يُستبدَل هو الآخر، وهذا صحيح، لأن سطر الأوامر ينتهي في ps وفي السجلات على كل حال.

الدرس: الباب يجب أن يكون ضيقًا عن قصد. «استبدل في كل مكان قد ينفع فيه» هو بالضبط كيف ينتهي سرّ في مكان ما كان ينبغي أن يصل إليه.

مرجع ملصوق في رسالة، لا يُستبدَل أبدًا

22 سبتمبر. أبلغ Cs040618 عن المشكلة المعاكسة: «ألصق المرجع في المحادثة ولا يستطيع الوكيل فهم ما هذا المفتاح».

ليس خطأً. الرسالة نصّ حرفي بحكم التصميم، وهو بالضبط إصلاح ما قبل ثلاثة أيام. لكن لا شيء في التطبيق كان يقول ذلك لحظة القيام بالحركة، والوكيل، وهو يستقبل {{secret:…}} في رسالة، لم تكن لديه أي فكرة عما يجيب.

ثلاثة إصلاحات، كلها عن قول أين الباب: تلميح ينطلق حين تلصق مرجعًا في حقل الكتابة ويشير إلى متغيرات البيئة، ونصّ مساعدة فوق قائمة الأسرار يسمّي الحقول الثلاثة التي يُستبدَل فيها المرجع ويقول «أبدًا في رسالة»، وسطر في تعليمات الوكيل نفسه يخبره بما يجيب حين يصله مرجع في رسالة.

«الإعدادات > الأسرار» لم تكن موجودة

28 سبتمبر. قدّم وكيل Mohammad بلاغًا: المستخدم يقول إنه أضاف OTPIQ_API_KEY في الإعدادات > الأسرار، وحفظه عدة مرات خلال ثلاثين دقيقة، وsecrets_list ما زال يعيد الأسرار الثلاثة القديمة نفسها.

مسار الحفظ كان سليمًا. السر لم يصل إلى الخزنة قط، لأنه لا توجد صفحة أسرار في الإعدادات. ستة نصوص مساعدة في تطبيق سطح المكتب، وصفحة على هذا الموقع، وتعليمات الوكيل نفسها، كلها كانت ترسل الناس إلى شاشة غير موجودة. أما الموجود فعلًا في الإعدادات فهو كتلة متغيرات البيئة، وهناك كتب الرمز، بين أقواس معقوفة، وهذا ليس مرجعًا: لا يُستبدَل أبدًا، ويُرسَل إلى الوكيل كما هو، ويُزامَن مع المشروع، فغادر الرمزُ الجهاز.

صحّحنا النصوص لتسمّي المسار الحقيقي، وجعلنا الأدوات الموجّهة للوكلاء تقول أين يُضاف السر، وأضفنا فحصًا على كتلة البيئة يُشير إلى بيانات اعتماد مكتوبة خامًا، وإلى اسم بين أقواس معقوفة ليس مرجعًا، وإلى مرجع لسرّ غير موجود على هذا الجهاز.

الدرس هنا لا علاقة له بالأسرار إطلاقًا: المسار الخاطئ في نصّ مساعدة هو خطأ أمني. إنه ينقل المستخدم إلى أقرب حقل يبدو صحيحًا.

إذا كنت لا تستخدم AgentsRoom

القاعدة تسافر. اختر من هذه ما يناسب تجهيزتك؛ كلها تنتهي إلى المكان نفسه، متغير بيئة في العملية التي يعمل فيها الوكيل.

  • CLI مدير كلمات مرور. op run -- claude مع 1Password، أو ما يعادله في Bitwarden وDoppler: تقرأ الأداة المراجع من قالب، وتحقن القيم الحقيقية في بيئة العملية الابنة، ولا يُكتب شيء على القرص.
  • direnv مع .envrc مستبعد من git. بسيط، ومحلي، ولكل مجلد. أضف .envrc و.env* إلى .gitignore قبل أول قيمة، لا بعدها.
  • ملف .env لا يقرؤه الوكيل أبدًا. أبقِه خارج المستودع وحمّله في الـ shell الذي يطلق الوكيل. وإن كان الملف داخل المستودع، فسيفتحه الوكيل في النهاية، ويقتبسه في رسالة، وتعود أنت إلى نقطة البداية.
  • بيانات اعتماد السحابة: اجعلها قصيرة العمر. GitHub OIDC في الـ CI بدل مفاتيح AWS طويلة العمر، وهوية حِمل عمل بدل ملف مفتاح حساب خدمة.

مهما اخترت، أضف القاعدة إلى تعليمات الوكيل، كي يكفّ عن السؤال. فقرة واحدة في CLAUDE.md أو AGENTS.md تكفي: لا تطلب أبدًا قيمة بيانات اعتماد، ولا تكتب واحدة في ملف أبدًا، استخدم $NAME وأخبر المستخدم أي متغير عليه ضبطه. ننشر مهارة صغيرة تقول هذا بالضبط، وطولها خمسة أسطر.

إذا كان المفتاح قد مرّ بالفعل في محادثة

بهذا الترتيب، والخطوة الأولى ليست اختيارية.

  1. غيّره. ما أُرسل في موجّه لا يُستعاد. اعتبر القيمة مكشوفة وأصدر واحدة جديدة.
  2. ابحث عن سجلات المحادثة. تحتفظ CLI بملفات المحادثة في مجلد المنزل لديك. ابحث فيها عن القيمة القديمة واحذف أو اقتطع ما يطابقها.
  3. تحقق من الأماكن التي تنسخ النصوص. تاريخ مدير الحافظة، والتذكرة أو المسألة التي جرى فيها توجيه الوكيل، وأي ملخّص كتبه الوكيل في المستودع، وgit log -p إن كان الوكيل قد نفّذ commit وهو يحمل المفتاح.
  4. وعندها فقط، ابنِ الباب. قيمة جديدة خلف متغير بيئة، ومرجع بالاسم، وتعليمات الوكيل محدَّثة كي لا يسأل التالي.

الخطوة 4 في الأخير، لأن آلية نظيفة حول مفتاح مسرَّب ليست إلا تسريبًا أكثر ترتيبًا.

أسئلة يطرحها الناس فعلاً

لماذا يجب ألا يوضع مفتاح API أبدًا في موجّه إلى وكيل ذكاء اصطناعي؟

لأن الموجّه يُخزَّن ويُمرَّر. يكتب Claude Code وCodex وبقية CLI المحادثةَ في ملف سجل المحادثة على قرصك، والرسالة نفسها تذهب إلى مزوّد النموذج. ومن هناك يصبح المفتاح أيضًا في تاريخ حافظتك، وفي أي سجل يعيد كتابة الرسالة، وفي إعادات المحاولة والوكلاء الفرعيين الذين ينسخون المحادثة. الحجب بالأنماط يلتقط ما يأتي على شكل sk- أو glpat-، لا كلمة مرور قاعدة بيانات تبدو ككلمة عادية.

كيف يستخدم وكيل البرمجة سرًّا لا يستطيع قراءته؟

عبر متغير بيئة. تضع القيمة في متغير بيئة للعملية التي يعمل فيها الوكيل، فيكتب الوكيل $STRIPE_SECRET_KEY في الأمر بدل القيمة. ويستبدله الـ shell عند تشغيل الأمر. لا يرى الوكيل الأحرف أبدًا، فهي لا تدخل محادثته ولا سجل محادثته.

هل أستطيع تمرير السر كوسيط في سطر الأوامر بدلًا من ذلك؟

تستطيع، ولا ينبغي لك. سطر الأوامر مرئي لكل عملية على الجهاز عبر ps، ويدخل في تاريخ الـ shell، وفي سجلات العمليات، وفي أي أداة تشخيص تقرأ الأمر الذي أُطلق. أما متغير بيئة لعملية واحدة فتقرؤه تلك العملية وroot، وهذه مساحة أصغر بكثير.

أين يخزّن AgentsRoom الأسرار التي يستخدمها الوكلاء؟

في ملف واحد داخل مجلد المنزل لديك، بأذونات 0600، مشفَّر عبر سلسلة مفاتيح نظام التشغيل، وعلى ذلك الجهاز وحده. لا شيء يُزامَن إلى خادم، ولا يوجد زر يعيد عرض القيمة. التطبيق يعرض أسماء، والوكيل يرى أسماء، ولا تُفكّ القيمة إلا في العملية الرئيسية، لحظة بدء طرفية أو أمر.

ماذا يحدث إذا لصقت مرجع سرّ في رسالة إلى الوكيل؟

لا شيء يُستبدَل، وهذا مقصود. الرسالة ووصف التذكرة والمهارة وموجّه النظام نصّ حرفي، فالمرجع المكتوب هناك يصل إلى الوكيل كما هو. وحدها قيمة متغير البيئة تُستبدَل. تعلّمنا ذلك بالطريقة الصعبة: مرجع مذكور في وصف تذكرة كان يخرج مُستبدَلًا في الرسالة الأولى للوكيل المُطلَق منها.

مفتاح مرّ بالفعل في محادثة. ماذا أفعل؟

غيّره أولًا، قبل أي شيء آخر، لأن ما أُرسل لا يُستعاد: هو عند المزوّد وفي ملف سجل المحادثة على قرصك. ثم احذف أو اقتطع سجلات المحادثة التي تحتويه، وتحقق من مدير الحافظة لديك، وابحث في المستودع تحسّبًا لأن يكون الوكيل قد كتبه في ملف. وعندها فقط ضع القيمة الجديدة خلف متغير بيئة.

باختصار

الوكيل لا يحتاج إلى قراءة مفتاحك. يحتاج إلى عملية تحتوي بيئتُها المفتاحَ أصلًا.

احفظ القيمة مرة واحدة، خارج المستودع، مشفَّرة بنظام التشغيل. أشِر إليها بالاسم حيث تُبنى البيئة. ودع الوكيل يكتب $NAME. وأبقِ كل القنوات الأخرى حرفية، بما فيها تلك التي كان الاستبدال فيها ليكون مريحًا، لأن القنوات المريحة هي بالضبط التي تُخزَّن وتُمرَّر.

وحين تخطئ، وستخطئ، غيّر المفتاح أولًا ورتّب ثانيًا.

تحميل AgentsRoom

شغّل كل وكلاء الذكاء الاصطناعي لديك، في كل مشاريعك، من نافذة واحدة.

مجانيتحميل AgentsRoom

التطبيق المرافق: تابع وكلاءك أينما كنت

استخدم Claude أو Codex أو Antigravity CLI أو أي مزود AI آخر.

تثبيت الملحق
Chrome Web Store

أرسل الأخطاء والطلبات مباشرة إلى قائمة المهام العامة.

مشاريع متعددة
متعدد المزوّدين
وكلاء متعددون
حالة مباشرة
فرق الملفات والـ commit
تطبيق الهاتف
معاينة مباشرة
فرق الوكلاء
أتمتة المتصفح
تطوير موجّه بالـ backlog
مكتبة البرومبت
مكتبة المهارات
عرض جميع الميزات

تابع القراءة