# العزل والثقة

## ما هو

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

## لماذا

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

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

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

## كيف بنيناه

![زوار التطبيقات غير الموثوقين لا يصلون إلى الخادم إلا عبر وكيل TLS والبوابة بمفتاح عام؛ والمشغّلون الموثوقون يستخدمون لوحة الإدارة أو الخادم مباشرة؛ ولكل بيئة Auth وREST وقاعدة بيانات وحسابات دخول خاصة بها، بينما محرك PostgreSQL وStorage حدود فشل مشتركة](https://base.sbarah.com/docs/diagrams/trust-boundaries.ar.svg)

*وكيل TLS وحده يواجه الشبكة، والمحرك وStorage حدود فشل مشتركة.*

![طلب بمفتاح المشروع أ على مسار البيئة أ يصل إلى REST الخاص بها وإلى القاعدة أ؛ والمفتاح نفسه على مسار البيئة ب يتلقى 401 عند البوابة؛ وحساب دخول يحاول قاعدة بيئة أخرى ترفضه قواعد الاتصال في PostgreSQL](https://base.sbarah.com/docs/diagrams/key-isolation.ar.svg)

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

![دفعة كبيرة على البيئة أ تملأ أماكنها الثمانية المضمونة وتستعير أماكن فارغة حتى سقفها 24 من أماكن البوابة الـ64، فتُقبل البيئة ب فورًا وتتلقى طلبات أ الزائدة 429؛ وخلف البوابة لكل بيئة حاوياتها بحدود للمعالج والذاكرة والقرص، وحدود اتصالاتها في المحرك المشترك](https://base.sbarah.com/docs/diagrams/load-isolation.ar.svg)

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


ما يخص كل بيئة وحدها:

- قاعدة بيانات لا تمنح صلاحية `CONNECT` إلا لحسابات دخولها، وقواعد اتصال تسمّي أزواجًا دقيقة من الحساب والقاعدة. هذه القواعد في ملف المصادقة حسب المضيف في PostgreSQL، أي HBA.
- ثلاثة حسابات دخول محصورة لخدمات Auth وREST وStorage، بكلمات مرور مولّدة.
- حساب مطوّر للترحيلات والوكلاء وStudio. ليس مستخدمًا خارقًا، ولا يستطيع استعمال أسماء مخططات المنصة، ولا إنشاء إضافات تصل إلى شبكة الخادم أو ترى كل البيئات، مثل `http` و`pg_net` و`dblink` ([الوصول إلى قاعدة البيانات](https://base.sbarah.com/docs/guides/database-access/)).
- سر توقيع Auth خاص بها، ومفاتيح API عامة وسرية خاصة بها لا يُحفظ من السرية إلا بصماتها، ومستأجر Storage ومفاتيح توقيع خاصة بها.
- حاويات Realtime وEdge Functions وStudio الخاصة بها حين تعمل. لا تصل حاوية الدوال إلا إلى Auth وREST ومستأجر Storage الخاصة ببيئتها، ولكل جلسة Studio شبكة خاصة.
- سجل توجيه يستطيع وضع البيئة في الصيانة دون المساس بغيرها.

ما هو مشترك، ولذلك حدّ فشل مشترك:

- **محرك PostgreSQL.** انهياره أو امتلاء قرصه أو قفل طويل فيه يصيب كل البيئات عليه. أدوار API القياسية (`anon` و`authenticated` و`service_role`) موجودة مرة واحدة في كل محرك، لأن أدوار PostgreSQL تشمل العنقود كله.
- **عملية Storage.** تحمل إعدادات كل المستأجرين، واختراقها اختراق لملفات المستأجرين جميعًا.
- **البوابة وفهرس التحكم.** إذا توقفا، توقفت كل البيئات عن الرد.
- **المفتاح الجذري لـVault.** أسرار Vault في كل البيئات مشفّرة بمفتاح واحد يخص الخادم. وتبقى منفصلة لأن كل بيئة لا تصل إلا إلى قاعدة بياناتها.
- **الخادم.** المعالج والذاكرة والقرص والإدخال والإخراج مشتركة. كل حاوية تعمل ضمن فئة موارد لها وزن معالج وحدود إدخال وإخراج لكل جهاز، وتُرفض البيئات الجديدة إذا نقصت الذاكرة أو القرص، أو ارتفع ضغط cgroup، أو ضاقت ميزانية الاتصالات.

الكود: [lab/resource_policy.py](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/lab/resource_policy.py) (الفئات)، و[lab/resource_admission.py](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/lab/resource_admission.py) و[lab/pressure_admission.py](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/lab/pressure_admission.py) و[lab/connection_budget.py](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/lab/connection_budget.py) (القبول)، و[lab/hba_authority.py](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/lab/hba_authority.py) (قواعد الاتصال)، و[src/gateway/handler.ts](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/src/gateway/handler.ts) (فحص المفاتيح).

## الحدود

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

## للتعمق

- [نموذج التهديد](https://base.sbarah.com/docs/explain/threat-model/): الأصول والأطراف وحدود الثقة، والأدلة وراء كل إجراء حماية، والثغرات المعروفة.
- [مراجعة الأمان والتشغيل](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/reviews/security-operations.md).
- [سياسة الموارد](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/RESOURCE-POLICY.md)، و[قبول الموارد](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/RESOURCE-ADMISSION.md)، و[قبول الضغط](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/PRESSURE-ADMISSION.md)، و[ميزانية الاتصالات](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/CONNECTION-BUDGET.md)، و[الجار المزعج](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/NOISY-NEIGHBOR.md).
- [مراجعة Storage المشترك](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/reviews/shared-storage.md) و[الاستبدال الذري لملف HBA](https://github.com/M7MMAD-OMAR/sbarbase/blob/main/docs/engineering/ATOMIC-HBA-REPLACEMENT.md).
