الأدلة

كيف تحافظ على أمان مفاتيح API في تطبيقك

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

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

المفاتيح العامة مقابل المفاتيح السرية

ليست كل المفاتيح سرية. معرفة الفرق تمنعك من الذعر بشأن المفتاح الخاطئ، وتمنعك من تجاهل المفتاح الصحيح.

النوعأمثلةهل يمكن وضعه في المتصفح؟
المفاتيح العامة أو القابلة للنشرمفتاح Stripe pk_…، ومفتاح خرائط مقيّد بنطاقك، وبعض معرّفات التحليلاتنعم، فقد صُمم لذلك
المفاتيح السريةStripe sk_…، ومفاتيح OpenAI وAnthropic، ومفاتيح مزودي البريد، وكلمات مرور قواعد البياناتأبدًا
مفاتيح الخدمة أو المديرمفاتيح تتجاوز قواعد الوصول في قاعدة بيانات مستضافةأبدًا؛ عاملها كأكثر المفاتيح حساسية

إذا لم تكن متأكدًا من نوع المفتاح، فراجع وثائق المزود. وعند الشك، عامله كسري.

الخطوة 1: خزّن المفاتيح كأسرار، لا في الكود

تنتمي المفاتيح إلى متغيرات البيئة أو إعدادات الأسرار لدى مستضيفك. يقرأها كودك بالاسم عند التشغيل (مثلًا process.env.OPENAI_API_KEY)، فلا تظهر القيمة في ملفاتك أبدًا. وللاطلاع على الخلفية، انظر ما هي متغيرات البيئة والأسرار.

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

ثم تحقق من عدم بقاء أي شيء:

ابحث في المشروع كله، بما في ذلك ملفات الإعداد وأي ملفات .env، عن أي شيء يشبه مفتاح API أو كلمة مرور. اذكر الملف والسطر، لا القيمة.

الخطوة 2: استخدم المفاتيح السرية على الخادم فقط

هذه هي القاعدة الأهم. أي شيء يستقبله المتصفح يستطيع الزائر قراءته؛ فمصدر الصفحة وملفات JavaScript مرئية كلها في أدوات المطور.

لذلك، إذا كان التطبيق يحتاج إلى استدعاء OpenAI، فينبغي أن يستدعي المتصفح خادمك أنت، ويستدعي خادمك OpenAI بالمفتاح. لا يغادر المفتاح الخادم أبدًا.

ميزة الدردشة تستدعي OpenAI مباشرة من المتصفح. انقل هذا الاستدعاء إلى مسار API على الخادم يقرأ OPENAI_API_KEY من متغيرات البيئة. يجب أن يستدعي المتصفح مسارنا فقط. اشترط تسجيل الدخول للوصول إلى المسار.

احذر من فخ شائع في أطر الواجهات الأمامية: المتغيرات ذات البادئة العامة، مثل VITE_ في Vite وNEXT_PUBLIC_ في Next.js، تُدرج في كود المتصفح عمدًا. والمفتاح السري الذي يحمل إحدى هذه البادئات مكشوف، حتى لو كان «في متغير بيئة».

الخطوة 3: اختبر أنه لا يوجد تسريب

لا تفترض أن الأمر نجح، بل تحقق من الموقع المباشر:

  1. افتح التطبيق المنشور في المتصفح.
  2. افتح أدوات المطور، ثم تبويب Sources أو Network.
  3. ابحث في الملفات عن أول أحرف كل مفتاح سري (مثلًا sk_ أو sk-).
  4. افحص طلبات الشبكة التي يقوم بها التطبيق. الطلب الذي يذهب من المتصفح مباشرة إلى مزود ذكاء اصطناعي مدفوع هو علامة خطر.

إذا وجدت مفتاحًا سريًا، فانقله إلى الخادم (الخطوة 2) وغيّره (الخطوة 6)، لأنه صار عامًا بالفعل.

الخطوة 4: قيّد ما يستطيع كل مفتاح فعله

تتيح كثير من المزودات تقييد المفتاح:

  • مفاتيح محدودة النطاق (scoped) أو مقيّدة لا تستطيع إلا ما يحتاجه تطبيقك. فـStripe مثلًا يدعم المفاتيح المقيّدة بصلاحيات محددة.
  • قيود النطاق أو عنوان IP للمفاتيح التي يجب أن تكون عامة، مثل مفاتيح الخرائط.
  • مفاتيح منفصلة لكل تطبيق ولكل بيئة، حتى لا يكشف تسرب واحد كل شيء، ولا يؤدي إلغاء مفتاح إلى كسر البقية.
  • مفاتيح الاختبار أثناء البناء، ومفاتيح الإنتاج الحقيقية فقط في التطبيق المنشور.

الخطوة 5: ضع سقفًا للضرر

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

  • اضبط حدود إنفاق أو تنبيهات لدى كل مزود مدفوع.
  • اشترط تسجيل الدخول لأي ميزة تكلّف مالًا في كل استدعاء.
  • أضف حدًا للمعدل لكل مستخدم. انظر ما هو تحديد المعدل (rate limiting).

أضف حدًا قدره 30 طلب ذكاء اصطناعي لكل مستخدم في الساعة إلى /api/chat. أعد رسالة واضحة عند بلوغ الحد. ارفض الطلبات من المستخدمين غير المسجلين.

الخطوة 6: غيّر المفاتيح المتسربة

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

  1. أنشئ مفتاحًا جديدًا لدى المزود.
  2. حدّث السر في إعدادات تطبيقك.
  3. أعد النشر حتى يستخدم التطبيق المنشور المفتاح الجديد.
  4. احذف المفتاح القديم لدى المزود.
  5. تحقق من سجلات الاستخدام لدى المزود بحثًا عن نشاط لا تتعرف عليه.

حذف رسالة المحادثة أو commit في Git لا يكفي. فسجل Git يحتفظ بالنسخ القديمة، وأي شيء عام ربما نُسخ بالفعل.

أخطاء شائعة

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

قائمة التحقق

  • كل مفتاح مخزّن كسر أو متغير بيئة، وليس في الكود.
  • لا يوجد ملف .env ولا مفتاح مرفوع إلى Git.
  • المفاتيح السرية تُستخدم في كود الخادم فقط.
  • لا يوجد متغير سري يستخدم بادئة عامة مثل VITE_ أو NEXT_PUBLIC_.
  • بحثت في JavaScript الموقع المباشر عن بادئة كل مفتاح ولم أجد شيئًا.
  • المفاتيح محدودة النطاق أو مقيّدة حيث يسمح المزود بذلك.
  • مفاتيح الاختبار والإنتاج منفصلة.
  • الميزات المدفوعة تتطلب تسجيل الدخول ولها حدود لكل مستخدم.
  • لكل مزود مدفوع سقف أو تنبيه للإنفاق.
  • أعرف كيف أغيّر كل مفتاح، وأي مفتاح تعرّض للكشف يومًا تم تغييره.

الحفاظ على المفاتيح في Mythex

يُبقي Mythex المفاتيح خارج كودك ومحادثاتك بطريقتين:

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

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

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

الأسئلة

هل من الآمن وضع مفتاح API في كود الواجهة الأمامية؟

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

ماذا أفعل إذا لصقت مفتاح API في محادثة أو في مستودع عام؟

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

أين يجب تخزين مفاتيح API؟

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

كيف أعرف إن كان مفتاح API مكشوفًا في موقعي؟

افتح موقعك المنشور، واعرض مصدر الصفحة وملفات JavaScript في أدوات المطور بالمتصفح، وابحث عن بداية المفتاح. إذا ظهر، فهو مكشوف ويجب نقله إلى الخادم وتغييره.

Mythex · Pricing · ابنِ أي شيء بالذكاء الاصطناعي · قوالب المواقع والتطبيقات · مقارنات Mythex · مصطلحات بناء التطبيقات بالذكاء الاصطناعي · أدوات مجانية لبناء التطبيقات بالذكاء الاصطناعي · English

English አማርኛ Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)