ستة مخططات بالمسارات بتغطي كل طريقة بيتاخد بيها قرار في DWPlatform: واحد بيدوس زرار، ومسؤول بيدّي صلاحية، وزميل بيغطي تفويض، ومهندس بيكسر الزجاج وقت عطل، وخدمة بتنادي خدمة تانية. كلهم بيعدّوا من نفس الفحص، لأن أول ما واحد فيهم ياخد طريق مختصر، الطريق المختصر ده هو اللي بيبقى نموذج الأمان الحقيقي.
دي مش أمنيات مكتوبة على ويكي. كل واحدة فيهم مفروضة بالكود، وكل واحدة موجودة لأن غيابها بيعمل عطل معروف ومحدد.
الأدوار مجرد حزم صلاحيات، مش أكتر. مفيش حاجة بتتفرّع على اسم دور. لو دوّرت على اسم دور بره وحدة تعريف الأدوار، المفروض متلاقيش حاجة.
كل عملية محمية بتنادي نفس الدالة. الفحوصات المتناثرة في الكنترولرز هي اللي بتخلي نقطتين المفروض يتفقوا يبطّلوا يتفقوا من غير ما حد ياخد باله.
الشاشة بتاخد قائمة الصلاحيات علشان تعرف ترسم إيه وبس. افترض إن العميل عدو: ممكن يتعدّل، وفي الآخر هيتعدّل.
غياب التصريح = رفض. مفيش وراثة ضمنية — النطاق اللي المفروض يغطي المدير وموظفينه بيكتب الاتنين صراحةً.
مفيش حاجة اسمها salary.read. في بس salary.read على مجموعة ناس محددة. صلاحية من غير
نطاق معناها صلاحية على كل الناس.
ليه القاعدة الخامسة هي اللي بتوجع. قائمة الصلاحيات سهلة تتفهم وسهلة تتغلط فيها. في نسخة قديمة، كان المسؤول
فعلاً معاه payslip.read بنطاق ذاتي — ومع ذلك قائمة المرتبات كانت بترجّع كل الصفوف في المستأجر،
لأن البوابة كانت تقدر تسأل «معاك الصلاحية دي ولا لأ؟» وبس. الـattribute ملهاش سجل، فمش قادرة تسأل
«على مين؟». والسؤال ده لازم يتجاوب جوه الاستعلام نفسه، وعلشان كده كل قائمة وبحث وتقرير وتصدير بيركّب مُرشِّح
النطاق جوه الـSQL بدل ما يفلتر الصفوف بعد ما يجيبها. الفلترة بعد الجلب لسه بتسرّب عدد الصفوف وإجمالي الصفحات —
ودول غالبًا هما الجزء الحساس.
الصلاحيات عايشة في خدمة واحدة. باقي الخدمات بتسألها، بتخزّن الإجابة لفترة قصيرة، وبتسأل تاني أول ما رقم الإصدار يتغيّر. مفيش أي حاجة من الصلاحيات متخبّية جوه توكن الدخول دلوقتي.
ده هو النموذج كله. كل اللي تحت مجرد اختلافات عليه.
اقرا مسارات الرفض، مش المسار السعيد. المنع بيكسب المنح، يعني «المدير ده مينفعش يشوف الأجور وقت التقييم» محدش يقدر يلغيها بإنه «يساعد» ويضيف دور. وتواريخ الصلاحية بتتشيّك في كل طلب مش وقت الدخول، فالتصريح اللي بيخلص الساعة ١٢ بيقف الساعة ١٢، مش لما الشخص يخرج ويدخل تاني. والرفض نفسه بيتسجّل: تكرار الرفض هو أوضح إشارة إن فيه صلاحية متظبطة غلط أو إن حد بيجرّب الأبواب.
مش هتقدر تدّي لنفسك حاجة إنت أصلاً مش معاك. والرفض ده
بيحصل قبل حتى فحص التعارض، وعلشان كده منح النفس بيرجّع 403 مش 409 — الاتنين رفض،
والترتيب مقصود.
الأزواج اللي مينفعش يجتمعوا في شخص واحد — يجهّز مسيّر المرتبات ويعتمده، يغيّر حساب بنكي ويعتمد الصرف، يقترح علاوة ويوافق عليها — عايشين في جدول، بيتشيّكوا وقت المنح وكمان وقت الاستخدام. القاعدة اللي بتتشيّك وقت المنح بس هي قاعدة بتسقط أول ما البيانات تتغيّر تحتيها.
تلات حاجات بيخلّوا التفويض آمن بدل ما يكون هوية تانية: عمره ما يزيد عن اللي عند صاحب التفويض (وبيتشيّك وقت الاستخدام، لأنه ممكن يكون فقدها بعد كده)، ولازم ينتهي، ومش متعدّي — المفوَّض له مش هيقدر يفوّض حد تاني. وكل إجراء مكتوب «فلان نيابة عن فلان» في السجل وفي مسار الاعتماد الظاهر. لو اتسجّل باسم صاحب التفويض لوحده، ده تزوير، مهما كانت الشاشة شكلها أظبط.
ده الرسم اللي جه من عطل حقيقي وصامت. الموارد البشرية كانت بتبعت تحديثات الهيكل لخدمة الهوية بتوكن موضوعه
مش بيسمّي حد. فحص الصلاحيات عمل الصح ورفض — والعميل سجّل تحذير وكمّل. محصلش حاجة باينة. بس الهيكل هو اللي
self وdirect_reports وreporting_chain وdepartment كلهم
بيترجموا من خلاله، يعني هيكل بيتأخر عن بيانات التوظيف معناه صلاحيات بتتحسب بالساكت على تبعية الشهر اللي فات.
والحل مش استثناء لـ«المنادي الموثوق». ده تفويض ضمني، والاستثناء عمره ما بيتحدّد بنطاق ولا بيتسجّل. دلوقتي الخدمة كيان قايم بذاته: ليها تصاريح، في مستأجر باسمه، بيتقيّموا بنفس الكود بتاع البني آدم، وأفعالها بتتنسب لها هي في السجل — مش لشخص ماكانش موجود.
صلاحية المدير بتتحسب من الهيكل وقت السؤال، مش متخزّنة كتصريح. يعني النقل مش محتاج مهمة تنضيف ولا بند في checklist الخروج: المدير القديم بيفقد الرؤية لأنه بقى مش المدير، مش لأن حد فاكر يسحب حاجة. الصلاحيات اللي بتتنسي هي بالظبط اللي كان لازم حد يفتكرها.
كل اللي فوق بيتدار من قسم «الوصول» في تطبيق الهوية. دي لقطات حقيقية من النظام — والجولة العملية ضغطة‑ضغطة في دليل ضبط الأدوار:
النطاقات مش بتتداخل. لو الحزمة المفروض تغطي الشخص و موظفينه، بتكتب الاتنين — الوضوح أحسن من الشطارة، وكل قاعدة وراثة ضمنية هي قاعدة حد هيفهمها غلط.
| النطاق | بيغطي | بيتحسب من |
|---|---|---|
| self | سجل الشخص نفسه بس | الشخص المربوط بالحساب |
| direct_reports | اللي تابعين ليه مباشرة | الهيكل، لحظيًا |
| reporting_chain | كل اللي تحته لأي عمق | الهيكل، لحظيًا |
| department | إدارة وكل الإدارات اللي تحتها | بادئة مسار الشجرة |
| legal_entity | شركة واحدة جوه المستأجر | الشركة في بيانات التوظيف |
| location | فرع أو موقع واحد | الفرع في بيانات التوظيف |
| all | المستأجر كله — ولا حاجة أوسع | أمان مستوى الصف لسه هو السور الخارجي |
كشف حساب صادق أنفع من كشف حساب واثق. المقارنة تحت مع نماذج الصلاحيات في Workday وSAP SuccessFactors (الموارد البشرية)، وMicrosoft 365 وGoogle Workspace (التعاون)، وServiceNow (التشغيل متعدد المستأجرين). واللي إحنا ناقصين فيه، مكتوب إننا ناقصين فيه.
| الممارسة | الأفضل بيعملوا إيه | DWPlatform |
|---|---|---|
| فصل الدور عن الصلاحية | الأدوار حزم؛ مفيش حاجة بتقيّم اسم دور | مطابق. ٩٠ صلاحية، ١٧ حزمة، وصفر تفرّع على اسم دور في الكود |
| الفئة المستهدفة | SuccessFactors بيربط دور الصلاحية بفئة مستهدفة | مطابق. ٧ نطاقات، بتتحسب من الهيكل، ومركّبة جوه الاستعلام مش مطبّقة بعده |
| الصلاحية بالعلاقة | بتتحسب من الهيكل وقت التقييم | مطابق. عمرها ما بتتخزّن كتصريح، فالنقل مش محتاج تنضيف |
| أمان مستوى الحقل | الوصول للسجل مش معناه الوصول للحقل | مطابق وزيادة شوية. الأجر ممكن يتحوّل لشريحة بدل ما يتخفي، فالمدير يخطط من غير ما يقرا مرتبات. والمخفي بيبقى غير موجود أو معلّم صراحةً — عمره ما يكون قيمة مزيفة |
| فصل المهام | أزواج التعارض مرفوضة وقت المنح ووقت الاستخدام | مطابق، مع تحفّظ واحد. مزروعة كبيانات، ومرفوضة وقت المنح، وبتتفحص تاني في كل طلب صلاحية — وده اللي بيمسك التعارض اللي ظهر بعد المنح: تعديل دور، أو تفويض بيدّي النص التاني، أو تصريح بتاريخ مستقبلي دخل حيّز التنفيذ، أو زوج جديد اتضاف للجدول بأثر رجعي. والرفض بيسمّي الزوج مش بيرجّع ٤٠٣ عام، وبيتقيّم فوق كسر الزجاج: الطوارئ علشان معتمِد مش موجود، مش علشان تكمّل نصّي مهمة مفصولة. والموافقة على النفس فاضلة مستحيلة بالكود. التحفّظ: الزوج المحدود بنفس السجل مينفعش يتحكم فيه غير لما الطلب يسمّي السجل، فنقطة كتابة بتتحقق من الصلاحية بس من غير ما تقول بتغيّر أنهي سجل، مش بياخد الفحص ده |
| التفويض | مؤقت، غير متعدّي، ومسجّل «نيابةً عن» | مطابق. والجزء بيتشيّك وقت الاستخدام مش وقت الإنشاء بس |
| هوية الخدمات | حسابات خدمة في Google Cloud، وصلاحيات تطبيق في Microsoft Graph | مطابق. الخدمات كيانات ليها تصاريح محدودة بالمستأجر، بيتقيّموا بنفس المحرك، وبتتسجّل باسمها |
| السحب أثناء الجلسة | إجابات قصيرة العمر بتتحدّث عند التغيير | مطابق. التوكن مفيهوش صلاحيات؛ ورقم الإصدار بيجبر التحديث في ثواني |
| تسجيل الرفض | الرفض بيتسجّل مش النجاح بس | مطابق. سجل لا يُعدَّل، مفروض بصلاحية قاعدة البيانات مش بالاتفاق |
| كسر الزجاج | بسبب، ومؤقت، وبتنبيه، ومتعلّم عليه | مطابق. ٦٠ دقيقة، وسبب حقيقي مطلوب |
| إعادة اعتماد الصلاحيات | حملات مراجعة دورية — المديرين بيراجعوا مين معاه إيه | ناقص. التصاريح ظاهرة وبتتسحب، بس مفيش حاجة بتجدول مراجعة. وتراكم الصلاحيات هو العطل الطبيعي لنظام مرن بالشكل ده |
| محاكاة السياسة | «اشرح لي القرار ده» و«لو عملت كده هيحصل إيه» | جزئي. ينفع تشيّك قرار واحد وتحسب نطاق، بس مفيش محاكاة لتصريح قبل ما يتمنح |
| مفاتيح تشفير العميل / موقع البيانات | مفاتيح لكل مستأجر، وتثبيت جغرافي | ناقص. مش مطلوب في الحجم الحالي، بس ده أول سؤال بيتسأل في مشتريات المؤسسات |
| الصلاحية بخصائص السجل | شروط على حالة السجل، مش العلاقة بس | جزئي. التصريح شايل قيد، واللي مش بيتقري منه بيضيّق لصفر مش بيوسّع — بس مش لغة شروط عامة |
كانت هتقفل فجوة الخدمات في بعد الضهر. وكانت كمان هتعمل طريق من غير نطاق ومن غير تسجيل، وكل تكامل جاي كان هيروح ليه. الخدمة اللي معاها تصاريح حقيقية بتتكلّف وقت أكتر في الإعداد، بس مينفعش حد يوسّعها بالساكت.
لما المحرك مايبقاش موصول، المنادي بيبقى معاه ولا حاجة مش آخر صلاحيات عرفها. يعني العطل بيرفض الشغل مش بيفتحه. لو خدمنا نسخة مخزّنة وقت العطل، كنا فتحنا تاني نفس ثغرة السحب اللي التصميم ده موجود علشانها.
الكتالوج بيتزاد عليه، مبيتغيّرش. إعادة التسمية مش باينة وقت الترجمة وبتحوّل التصريح بالساكت لحاجة ملهاش لازمة — واللي بيوصل بعد شهور على إنه «الشخص ده فقد صلاحيته من غير سبب».
لما اسم الدور لسه بيتستخدم — طابور الرئيس التنفيذي بيوصل لسكرتيره، أو خبر موجَّه لمكتب — فهو بيسمّي الوجهة، مش اللي مسموح ليه يعمله. العضوية والسلطة بيتشافوا كل واحدة لوحدها وعن قصد.