الخلاصة

  • يقترح draft-li-oauth-delegated-authorization-03 سلسلة مرتبة يبدأها رمز جذر يوقعه خادم التفويض، ثم يستطيع عميل أن يوقع لعميل آخر رمزاً ابناً أضيق ضمن العمق المتبقي. وهذه مسودة إنترنت فردية تنوي مسار Standards Track، وليست RFC ولا إجماعاً ولا دليلاً على تشغيل فعلي.
  • يثبت توقيع الابن أن المفتاح المرتبط بالأب المباشر وقّعه. ولا يثبت أن الجذر موثوق، أو أن المعنى ظل داخل الحدود التراكمية، أو أن صاحب المورد وافق على هذا المندوب بعينه، أو أن حالة الإلغاء حديثة.
  • يقدم العميل الأخير السلسلة الدقيقة المرتبة مع برهان DPoP. وعلى خادم المورد أن يتحقق من كل سلف ورابطة مفتاح وتضييق دلالي، ثم يطبق سياسته المحلية قبل أي أثر تطبيقي.

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

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

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

الإصدار 03 عمل قيد التطوير. يذكر رأس الوثيقة نية Standards Track، بينما لا تسجل واجهة Datatracker حالياً stream أو intended standard level. كما أن طلبات تسجيل نوع وسائط ونوع رمز ومخطط مصادقة وclaims وmetadata ليست إيصالات IANA قائمة. ولا تقدم الوثيقة تقرير تنفيذ متوافق أو دليلاً على نشر إنتاجي.

الجذر لا يستطيع أن يمنح الثقة لنفسه

يختلف أول عنصر عن بقية السلسلة. يجب التحقق منه بمفتاح لخادم التفويض عرفه خادم المورد من إعداد موثوق أو metadata موثقة. لا يجوز أخذ JWK من رمز جذر غير موثوق ثم استخدامه لإثبات ذلك الرمز؛ وإلا استطاع المهاجم تقديم الادعاء ومرجعه معاً.

في الرمز الابن الصادر عن عميل، يظهر المفتاح العام للمفوِّض في protected header. يحسب المتحقق thumbprint وفق RFC 7638، ويقارنه مع cnf.jkt في الأب المباشر، ثم يتحقق من توقيع الابن. والنتيجة الموجبة تثبت حافة محددة: صاحب المفتاح الذي أجازه الأب وقّع هذا الابن.

لكنها لا تثبت كيف حصل A على المفتاح العام لـB، ولا لماذا نسبه إلى workload أو مستأجر أو مشغل بعينه. تترك المسودة تلك الرابطة خارج نطاقها. لذلك يمكن لقناة onboarding خاطئة أن تنتج سلسلة متماسكة تشفيرياً إلى الخدمة الخطأ. استمرارية المفتاح، وهوية صاحبه، والتفويض التجاري ثلاث إيصالات مختلفة.

ولا يقبل رمز عميل كأول عنصر، ولو كان توقيعه صحيحاً. ليس للمتحقق أن يبدأ من الوسط ثم يبحث عن جذر يلائم النهاية. اتجاه السلطة جزء من البرهان؛ توقيع قوي في المنتصف لا يصنع بداية موثوقة مفقودة.

التضييق حساب دلالي لا مقارنة نصوص

الوعد المركزي هو attenuation أحادي الاتجاه: لا يحق للابن زيادة السلطة الفعلية المتراكمة في مساره. يمكن تمثيل scope كمجموعة؛ كل قيمة في الابن يجب أن تكون موجودة أصلاً في مجموعة الأب الفعلية. أما authorization_details فتحتاج إلى أكثر من تطابق JSON أو تساوي حقل type.

يلزم كل نوع تفاصيل بقاعدة subset تفهم الموارد والأفعال والـwildcards والقيم الافتراضية والمصفوفات والحقول الغائبة. قد يكون object أقصر لكنه أوسع لأن غياب حقل ما يعني «أي قيمة». وقد يحمل objectان النوع نفسه لكنهما يشيران إلى حسابين أو عمليتين مختلفتين. إذا تعذر إثبات الاحتواء بصورة حتمية، فالنتيجة الآمنة هي الرفض.

الحذف نفسه يحمل معنى سلطة. إذا حذف الابن scope أو authorization_details تختفي تلك المكوّنة ولا يجوز لحفيد إعادتها. أما حذف audience فلا يضيف قيداً جديداً، فيبقى قيد الأب الفعلي. ولكل claim توسعي حاجة إلى قاعدة صريحة: هل يمكن تقديمه أول مرة، وهل يورث، وماذا يعني حذفه، وهل يمكن أن يظهر من جديد؟

هنا تظهر حدود المؤسسة التقنية. لا ينبغي لمكتبة تحقق مركزية أن تخترع معنى الحقول المهنية الجديدة. يطالب مبدأ الحد الأدنى للمواصفة الأولية في docs/heng-lu-note.md بطبقة مشتركة رقيقة وحتمية. الدلالة الجديدة إما أن تحصل على profile محلي قابل لإعادة الإنتاج أو ترفض؛ لا تحول heuristics الغموض إلى سلطة.

ويجب الحساب من الجذر بالترتيب. مجموعة من JWTs الصالحة منفردة لا تساوي سلسلة صالحة. الحذف والإرث وإعادة الظهور أمور تعتمد على المسار، ولذلك فالإيصال الحقيقي هو traversal المحسوب لا الكائن الأخير.

العمق يحد طول المسار ولا يحد الضرر وحده

يحمل كل جذر max_delegation_depth محدوداً. إذا كانت قيمة الأب الفعلية m، يجب أن تقع قيمة الابن الصريحة بين صفر وm-1؛ وإذا حذفت صارت m-1. ويمكن لورقة بعمق صفر الوصول، لكنها لا تستطيع تعيين ابن جديد.

هذا حد بنيوي مفيد، لكنه لا يقيس blast radius. فعمق ثلاثة قد ينتج آلاف الأحفاد إذا وسّع كل حامل fan-out. والرمز القصير العمر قادر على تنفيذ عمليات كثيرة. كما قد يخفي scope ضيق الاسم تحويلاً عالي القيمة أو تصديراً جماعياً. طول مسار الإثبات لا يساوي عدد الجهات القادرة على الفعل.

تطلب المسودة حدوداً لعدد الرموز والحجم المتسلسل وكلفة التحقق. وتحتاج القيادة فوق ذلك إلى حدود fan-out، وجرد للأحفاد، وأعمار للمهام، وسياسة one-token-one-key. لأن إصدار الأبناء لا يمر بخادم التفويض، لا يستطيع الخادم استخراج قائمة كاملة بالأحفاد من سجل الجذر وحده عند اختراقه.

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

الموافقة على الاستخدام ليست موافقة على التعيين

عندما يكون Resource Owner طرفاً في grant، يطلب الإصدار 03 الفصل بين موافقته على الوصول وموافقته على أن يصدر العميل تفويضاً لعملاء آخرين. «اسمح لهذا التطبيق بقراءة التقارير» ليست «اسمح له بتعيين تطبيقات أخرى لقراءتها»، حتى إذا انتهى المساران إلى scope نفسه.

ينبغي لشاشة الموافقة أن تعرض الصلاحيات وaudience والعمر والعمق الأقصى. وعليها كذلك أن تقول ما لا يحدث: خادم التفويض لن يشاهد أو يوافق بالضرورة على كل ابن. الجذر يجيز فئة محدودة من الاختيارات المستقبلية؛ ولا يثبت أن صاحب المورد رأى اسم B أو مشغله أو مهمته اللاحقة.

المفتاح الخاص المرتبط يستطيع توقيع DPoP للاستخدام الحالي، ويستطيع عند بقاء العمق توقيع رمز ابن. واجهة توقيع عامة قد تحول اختراقاً كان محصوراً في إثبات طلب إلى اختراق لقدرة التعيين. ينبغي لواجهة المفتاح وسياسة HSM أن تفصلا العمليتين والمدخلات المسموحة لكل منهما.

تظل السلطة موزعة بين ثلاثة أطراف. خادم التفويض يحدد أكبر غلاف قابل للنقل. المفوِّض يختار الطرف المقابل داخله ويتحمل إثبات رابطة المفتاح. خادم المورد يقرر إن كان الطلب مقبولاً الآن. لا يستطيع طرف أن يصدر إيصال الطرف الآخر.

ترتيب البايتات جزء من البرهان

يقترح credential باسم DA تسلسل JWTs المضغوطة من الجذر إلى الورقة، مفصولة بعلامة ~. يجب رفض العنصر الفارغ أو الرمز المشوه أو الترتيب المتغير أو السلسلة المتجاوزة للحد. وتربط قيمة ath في DPoP للورقة البايتات الدقيقة للتسلسل المقدم. لا يجوز فك الرموز أو normalize أو إعادة serialize قبل حسابها.

يمنع ذلك مراقباً من حذف عنصر أو إضافته أو نقله داخل طلب ملتقط من دون برهان جديد بالمفتاح الأخير. لكنه لا يجعل العناصر صالحة. يثبت DPoP أن صاحب مفتاح الورقة ربط هذا الطلب بهذه البايتات؛ ولا يزال خادم المورد مطالباً بتوقيع الجذر وكل توقيع عميل وكل رابطة cnf.jkt وكل قيد.

وهذا هو الفارق عن مقال BTW الموجود حول RFC 9449. فـDPoP يملك sender constraint وربط method وURI والحداثة وreplay وربط hash الرمز. تستخدم المسودة تلك الآلية للحافة الأخيرة من رسم سلطة أكبر؛ أما عملها المميز فهو حفظ التضييق خلال أسلاف أصدرهم العملاء.

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

الإلغاء مشكلة توزيع حالة لا مجرد استجابة HTTP

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

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

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

لذلك يحتاج وعد الإلغاء السريع إلى أعمار قصيرة أو introspection أو feeds متزامنة أو قناة حديثة أخرى. وعلى كل قرار محلي أن يسجل مصدر الحالة وإصدارها أو وقت ملاحظتها. من دون ذلك لا يمكن تفسير «ألغي 10:01» مع «قبل 10:04» تفسيراً قابلاً للمراجعة.

القرار النهائي يبقى محلياً عند المورد

بعد نجاح التشفير والتضييق، يطبق خادم المورد scope وauthorization details وaudience والزمن والclaims مع سياسة المستأجر وحالة المورد والإلغاء والضوابط المحلية.

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

كما أن قرار allow ليس إيصال الأثر التجاري. قد يفشل database commit أو queue، وقد يقع أثر جزئي، وقد يكرر retry العملية. ضوابط DPoP للـreplay لا تعد بتنفيذ exactly-once. مفتاح idempotency وإيصال transaction يبدآن بعد التفويض.

عشر إيصالات أفضل من حدث واحد اسمه «نجح التفويض»

الإيصال الحد الأدنى من الدليل ما لا يثبته
موافقة الجذر Grant، موافقة تفويض منفصلة، العمق الموافقة على ابن مستقبلي مسمى
إصدار الجذر Issuer، hash، audience، الحقوق، الوقت، cnf.jkt وصول المورد الآن
رابطة المندوب Workload، المستأجر، thumbprint، القناة بقاء الابن داخل الحدود
إصدار الابن حافة الأب، hash الابن، القيود، العمق المتبقي الثقة بالجذر
تحقق السلسلة التواقيع والروابط والأزمنة والاحتواء حيازة الورقة أو allow محلي
برهان الورقة Method، URI، ath الدقيق، nonce، replay صلاحية الأسلاف
الحالة ملاحظات حالة الأسلاف وحداثتها وصولها إلى كل متحقق
القرار المحلي إصدار السياسة، العملية، النتيجة application commit
الأثر Transaction/idempotency والحالة النتيجة الخارجية المطلوبة
المطابقة ملاحظة مسماة والاستثناءات سلطة تنفيذ فعل آخر

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

إذن ليست الفكرة «تفويضاً بلا خادم مركزي» فحسب. يستطيع الخادم الغياب عن إصدار الابن لأن الجذر حد ذلك الغياب مسبقاً، ثم أعاد المورد بناء كل حد محلياً. قد يكون الرمز الابن صالحاً؛ أما السلطة فتظل ملك السلسلة كلها ونقطة القرار الأخيرة.