كيف تمنع وكلاء الذكاء الاصطناعي من تسريب مفاتيح API
قد يسرّب وكيل يملك مفاتيح API أسرارك بأمر واحد. تعلّم استخدام رموز محدودة وقصيرة العمر عبر بوابة بيانات اعتماد، بدلًا من المفاتيح الحقيقية.
ما يعنيه إبقاء الأسرار خارج وكلاء الذكاء الاصطناعي
وكيل الذكاء الاصطناعي هو عملية Linux عادية تنفذ الأوامر. ويمكن للشفرة التي تنفذها العملية قراءة كل متغير بيئي تحتفظ به. لذلك، فإن وجود مفتاح API في البيئة الخاصة بالوكيل يعني أن الوكيل يستطيع إرساله إلى أي مضيف يمكنه الوصول إليه. ويعني إبقاء الأسرار خارج الوكيل منحه وسيلة وصول بدلًا من المفتاح: رمزًا محدود النطاق وقصير العمر، أو عنصرًا نائبًا تستبدل به جهة أخرى القيمة الحقيقية عند حدود الشبكة.
لا يتعلق الأمر بتحول نموذج إلى جهة عدائية. فالآلية أبسط من ذلك. يقرأ الوكيل صفحة ويب أو ملف README أو تعليقًا في issue يحتوي على تعليمات، ثم يتبعها، لأن النموذج اللغوي لا يميز بين النص الذي كتبته والنص الذي جلبه. هذا هو حقن التعليمات. وبمجرد حدوث ذلك، يتحدد الضرر بعامل واحد تمامًا: ما تستطيع العملية قراءته. وإذا لم تنشئ حدًا بعد، فإن تشغيل وكيل برمجي بأمان على خادم يوضح مستويات العزل التي يستند إليها هذا الدليل.
نموذج التهديد بعبارات واضحة
شغّل هذا الأمر باستخدام المستخدم الذي يعمل به وكيلك.
tr '\0' '\n' < /proc/self/environ | grep -iE 'key|token|secret|password'كل سطر يطبعه يمثل طلب HTTP واحدًا يمكن أن يصل إلى خادم يملكه طرف غريب. افحص الآن ما يوجد على القرص بالقرب من الوكيل.
grep -rIl --exclude-dir=.git -e 'API_KEY' -e 'SECRET' ~/projects
find ~ -maxdepth 3 -name '.env' -o -name 'credentials' -o -name '*.pem'لا يحتاج وكيل لديه shell إلى استغلال معقد لإخراج تلك البيانات. تكفي أربعة مسارات عادية، وتبدو جميعها كعمل طبيعي في السجل:
- طلب
curlأوfetchصادر إلى أي مضيف، مع وضع القيمة في سلسلة الاستعلام. - تنفيذ
git commitوgit pushعلى مستودع يستطيع الوكيل الكتابة فيه. - برنامج تثبيت حزمة يشغّل تعليمات برمجية عشوائية كمستخدم الوكيل.
- إجراء بحث DNS عن اسم مضيف يحتوي على القيمة، إذ يخرج هذا الطلب حتى عند حظر الاتصالات الصادرة عبر HTTP.
لا يمكنك حل هذه المشكلة بمجرد المراجعة. الحل هو التأكد من عدم وجود أي بيانات قيّمة في متناول الوكيل.
السر الموجود في شجرة العمل هو سر موجود في نافذة السياق
يقرأ الوكيل الملفات. سيُقرأ ملف .env الموجود في المستودع الذي يعمل فيه، وبمجرد قراءته يصبح موجودًا في نافذة السياق، أي في السجل، وفي أي سجل تحتفظ به، وفي كل ما يكتبه الوكيل بعد ذلك.
في السابق، عندما كان المفتاح موجودًا في شجرة العمل التي يستخدمها الوكيل:
cd ~/projects/billing
cat .env
# STRIPE_SECRET_KEY=sk_live_...
# DATABASE_URL=postgres://app:hunter2@db.internal:5432/billingبعد ذلك، عند نقل الملف إلى مكان لا يمكن للوكيل الوصول إليه:
sudo install -d -m 750 -o root -g agent-review /etc/agent-review
sudo install -m 640 -o root -g agent-review ~/projects/billing/.env /etc/agent-review/billing.env
rm ~/projects/billing/.envلم يعد بإمكان مستخدم الوكيل فتح الملف، لأن شجرة العمل لم تعد تحتوي عليه. تُعد قواعد المنع في إعدادات الوكيل نفسه طبقة ثانية، وليست الطبقة الأولى. يقرأ Claude Code قواعد الأذونات من .claude/settings.json في المشروع:
{
"permissions": {
"deny": ["Read(./.env)", "Read(./secrets/**)", "Read(./**/*.pem)"]
}
}يمنع ذلك الخطأ غير المقصود المتمثل في فتح الوكيل ملفًا أثناء الاستكشاف. لكنه لا يمنع تنفيذ تعليمات مُحقنة للأمر base64 .env، لأن هذا أمر shell وليس قراءة ملف. تعامل مع الإعدادات باعتبارها حاجز حماية، ومع أذونات نظام الملفات باعتبارها الحاجز الفعلي. ينطبق الفصل نفسه داخل الحاويات: يغطي ملفات البيئة والأسرار في Docker Compose إصدار هذه المشكلة في طبقة أدنى.
امنح كل وكيل حساب مستخدم خاصًا به من دون امتيازات
إذا شغّلت الوكيل بحسابك، فسيرث مفاتيح SSH وبيانات اعتماد السحابة وسجل الصدفة لديك. إنشاء حساب مستخدم منفصل يتطلب أمرًا واحدًا ويزيل كل ذلك.
sudo adduser --disabled-password --gecos "" agent-review
sudo chmod 700 /home/agent-review
sudo -u agent-review cat ~/.ssh/id_ed25519يجب أن يفشل السطر الأخير مع cat: /home/you/.ssh/id_ed25519: Permission denied. إذا طبع مفتاحًا بدلًا من ذلك، فهذا يعني أن الدليل الرئيسي لديك قابل للقراءة من المجموعة أو من الجميع، ويعالج chmod 700 ~ ذلك. لا تضف حساب الوكيل إلى sudo، ولا تمنحه قاعدة NOPASSWD أوسع من الأمر الوحيد الذي يحتاج إليه فعلًا. يشرح حسابات المستخدمين الأقل امتيازًا على VPS تفاصيل المجموعات وملف sudoers.
من المفيد إضافة حد أمني آخر على VPS سحابي. تستجيب خدمة بيانات التعريف الخاصة بالمثيل على عنوان محلي للرابط ثابت، وغالبًا ما تمنح بيانات اعتماد الدور لأي جهة تطلبها.
sudo iptables -A OUTPUT -m owner --uid-owner agent-review -d 169.254.169.254 -j REJECTتحقق من ذلك من جهة الوكيل. يجب أن يطبع sudo -u agent-review curl -s --max-time 3 http://169.254.169.254/ لا شيء وأن ينتهي بحالة غير صفرية، لأن الحزمة تُرفض قبل أن تغادر الخادم.
حقن بيانات الاعتماد عند الحد الفاصل
النمط الذي يحل هذه المشكلة فعليًا هو حقن بيانات الاعتماد. لا يحتفظ الوكيل بمفتاح حقيقي مطلقًا. يرسل طلبه عبر بوابة محلية، وتستبدل البوابة قيمة نائبة بالسر الحقيقي أثناء إرسال الطلب. يُخزَّن السر في وحدة تخزين البوابة، ضمن عملية مختلفة، ويملكه مستخدم مختلف.
OneCLI هو أحد تطبيقات المصدر المفتوح لهذا النمط، ومرخّص بموجب Apache-2.0، ويعمل في حاوية بجانب الوكيل. اعتبارًا من يوليو 2026، يوثّق المشروع هذا الإعداد:
git clone https://github.com/onecli/onecli.git
cd onecli
docker compose -f docker/docker-compose.yml up -d --waitتستمع لوحة المعلومات على المنفذ 10254، وتستمع البوابة على المنفذ 10255. تخزّن بيانات الاعتماد الحقيقية مرة واحدة، ثم تمنح كل وكيل قيمة نائبة بدلًا من المفتاح، إلى جانب رمز وصول خاص به ومحدّد النطاق، ويرسله في ترويسة Proxy-Authorization. تطابق البوابة الطلب الصادر باستخدام المضيف والمسار، ثم تفك تشفير بيانات الاعتماد المطابقة وتستبدل القيمة النائبة بها. لا تحتوي بيئة الوكيل على أي شيء يستحق السرقة.
القيمة هنا ليست في التشفير. بل في أن السؤال: «ما الذي استخدمه هذا الوكيل، ومتى؟» يتحول إلى استعلام في السجل. تقرأ سجل تدقيق واحدًا بدلًا من التخمين بشأن أي من البيئات الست احتوى نسخة من المفتاح.
سلِّ السر إلى العملية، لا إلى البيئة
إذا شغّلت العامل باستخدام systemd، فلست بحاجة إلى متغيرات البيئة على الإطلاق. يضع LoadCredential= السر في دليل خاص لا يمكن إلا لهذه الخدمة قراءته، ويظهر على أنه %d في ملف الوحدة وعلى أنه $CREDENTIALS_DIRECTORY داخل العملية. لا تظهر القيمة مطلقًا في /proc/<pid>/environ، لذلك لا يستطيع ps eww عرضها، ويختفي الدليل عند توقف الخدمة.
شفِّر بيانات الاعتماد على الجهاز أولًا. تأتي هذه الأوامر من وثائق systemd، وتعمل على systemd 250 أو أحدث، وهذا يشمل Ubuntu 24.04 وDebian 13:
echo -n 'sk-example-value' > /tmp/plain.txt
sudo systemd-creds encrypt --name=api_key /tmp/plain.txt /etc/credstore/api_key.cred
shred -u /tmp/plain.txt
sudo systemd-run -P --wait -p LoadCredentialEncrypted=api_key:/etc/credstore/api_key.cred \
systemd-creds cat api_keyيطبع الأمر الأخير sk-example-value. وهذا يثبت أن الملف المشفّر يُفك تشفيره على هذا المضيف. ثم أشِر إليه من الوحدة:
[Service]
User=agent-review
LoadCredentialEncrypted=api_key:/etc/credstore/api_key.cred
Environment=AGENT_KEY_FILE=%d/api_key
ExecStart=/usr/local/bin/agent-workerيفتح رمز العامل الملف في $AGENT_KEY_FILE عندما يحتاج إلى القيمة. تستغرق قراءة الملف لحظة. أما متغير البيئة فيستمر طوال مدة تشغيل العملية، وفي كل عملية فرعية تنشئها.
فضّل الرموز المميّزة قصيرة العمر على المفاتيح طويلة العمر
يبقى المفتاح الذي لا تنتهي صلاحيته صالحًا كلما ظهر لاحقًا، حتى بعد أشهر، في سجل أو نص مفرّغ. عندما توفّر الخدمة رمز جلسة، استخدم رمز الجلسة واضبط أقصر مدة تسمح بها المهمة.
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/agent-readonly \
--role-session-name agent-review \
--duration-seconds 900تقبل AWS STS (خدمة الرموز الأمنية) مدة لا تقل عن 15 دقيقة، وتكون هذه المدة كافية عادةً لمهمة وكيل واحدة. بالنسبة إلى GitHub، امنح مستخدم الوكيل تسجيل دخول خاصًا به عبر gh، مع رمز مميّز دقيق النطاق ومحصور في المستودع الواحد الذي يعمل عليه، بحيث يعيد gh auth token داخل تلك الجلسة قيمة لا يمكنها الوصول إلى أي شيء آخر. حدّد النطاق حسب المورد أولًا، ثم حسب المدة.
تحقّق، ثم واصل التحقّق
يجدر تشغيل 3 فحوصات بعد أي تغيير في إعداد وكيل. شغّلها بصفة مستخدم الوكيل، وليس بصفتك أنت.
sudo -u agent-review env | grep -iE 'key|token|secret'
sudo -u agent-review ls -la /home/you/ 2>&1 | head -3
sudo -u agent-review curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 https://api.github.com/userيجب ألا يطبع الفحص الأول أي شيء على الإطلاق. ويجب أن يطبع الفحص الثاني ls: cannot open directory '/home/you/': Permission denied. أما الفحص الثالث، فيوضح الهوية التي يعرضها مسار شبكة الوكيل. وهذا هو السؤال الذي يجيب عنه نمط البوابة: تعني 401 أن الوكيل لا يحمل بيانات اعتماد GitHub خاصة به، بينما تعني 200 أنه يحمل بيانات اعتماد، ولذلك يجب أن تعرف الرمز المميز الذي يستخدمه. إذا كنت تشغّل الوكلاء دون مراقبة، يشرح التحكم في تكاليف وكلاء الذكاء الاصطناعي على VPS حدود الميزانية التي تقترن بحدود الوصول هذه.
FAQ
هل يمكنني ببساطة الوثوق بأن النموذج لن يسرّب مفاتيحي؟
لا، لأن النموذج ليس المهاجم في نموذج التهديد هذا. يقرأ الوكيل النصوص من صفحات الويب والمستودعات ومتتبعات المشكلات، وقد تحتوي هذه النصوص على تعليمات. ولا يملك النموذج طريقة موثوقة للتمييز بين تعليماتك والنص الذي جلبه. يفشل أي تحكم يعتمد على اختيار النموذج الصحيح في أول مرة تكون فيها التعليمات المحقونة مقنعة. لذلك يجب أن يكون التحكم في نظام التشغيل أو الشبكة.
هل متغيرات البيئة سيئة حقًا لأسرار الوكيل؟
هي سيئة بطريقة محددة: إنها موروثة. تحصل كل عملية فرعية ينشئها الوكيل على نسخة منها، بما في ذلك برنامج بناء ومشغّل اختبارات وأي خطاف لتثبيت الحزم. ويمكن أيضًا قراءة المتغيرات عبر /proc/<pid>/environ من جانب المستخدم نفسه. لذلك تستطيع أي عملية يشغّلها الوكيل قراءتها من دون أن يمررها الوكيل إليها. أما قراءة ملف في لحظة الاستخدام، باستخدام LoadCredential= أو بوابة، فتحدّ من التعرض بتلك اللحظة.
هل يحل وضع الأسرار في مخزن الأسرار هذه المشكلة بمفرده؟
يحلها جزئيًا فقط. يعالج مخزن الأسرار مشكلة التخزين. لكنه لا يعالج الخطوة الأخيرة، حيث يستخرج شيء ما السر من المخزن ويسلمه إلى الوكيل كمتغير بيئة، وبذلك تعود إلى نقطة البداية. المهم هو تحديد الجهة التي تجري الاستبدال. إذا جلب الوكيل السر، فإن السر أصبح بحوزته. أما إذا أجرت البوابة أو نظام التهيئة الاستبدال خارج عملية الوكيل، فلن يحتفظ الوكيل به.
كيف أعرف ما إذا كان الوكيل قد سرّب شيئًا من قبل؟
لا يمكنك عادةً معرفة ذلك بعد وقوعه، وهذا أحد أسباب استخدام البوابة. من دونها، تكون أدلتك موزعة بين سجل الصدفة، وسجل محادثة الوكيل، وسجلات الاتصالات الصادرة التي من المحتمل أنك لا تحتفظ بها. مع بوابة بيانات اعتماد، يكون كل استخدام لبيان اعتماد سطرًا واحدًا يتضمن هوية الوكيل وطابعًا زمنيًا. إذا اشتبهت في حدوث تسريب، فبدّل المفتاح أولًا ثم ابدأ التحقيق. تبديل المفتاح منخفض التكلفة، أما اليقين فليس كذلك.
ما الحد الأدنى الذي ينبغي أن أفعله اليوم؟
انقل كل ملف .env خارج الأدلة التي تعمل فيها وكلاؤك، وأنشئ مستخدمًا غير مميز لكل وكيل. يستغرق هذان التغييران نحو عشر دقائق، ويغلقان المسار الأكثر شيوعًا، وهو قراءة وكيل لملف بيانات اعتماد لم يكن هناك سبب لوضعه بجوار الشيفرة. البوابة والرموز قصيرة العمر هما الخطوة التالية، وليسا الخطوة الأولى. وتنطبق نقطة البداية نفسها على أي بيئة تشغيل للوكلاء، بما في ذلك تشغيل وكيل مستقل بأمان على VPS.