Stopping Guest-Inviting-Guest Sprawl in Entra External Collaboration Settings | لما الـ Guest بيعزم Guest تاني: إزاي توقف فوضى التعاون الخارجي في Entra ID
لما الـ Guest بيعزم Guest تاني: إزاي توقف فوضى التعاون الخارجي في Entra ID
حكاية تينانت بدأ بـ 12 guest وخلص بـ 400، وإزاي تمسك الخيط من الأول قبل ما يتفلت.
المقدمة
حصل معايا الموضوع ده فعلاً في تينانت لعميل عنده شركة استشارات صغيرة. البداية كانت طبيعية جداً: قسم الـ Sales عزم شريك خارجي واحد على SharePoint site عشان يتشارك في عرض. المشكلة إن الشريك ده كان عنده صلاحية Invite Guest افتراضياً في التينانت بتاعه، فراح عازم اثنين من زمايله يساعدوه، وهما كل واحد عزم واحد تاني "للمراجعة"، وفي أسبوعين بقى عندك 40 guest جديد ولا أحد فاكر ليه أصلاً كل واحد فيهم موجود. المشكلة الحقيقية مش إن الـ external collaboration حاجة وحشة، هي أداة أساسية للشغل، لكن لو سايبها على Default Settings من غير حدود، هتلاقي نفسك بعد شهور مش عارف مين موجود في التينانت وليه، وده كابوس حقيقي وقت أي Access Review أو Audit.
- صلاحية Global Administrator أو External ID User Flow Administrator على الأقل عشان تعدل authorization policy
- Entra ID P1 (أو P2 لو هتستخدم Entitlement Management و Access Reviews)
- Microsoft Graph PowerShell SDK متوصل (Connect-MgGraph مع الصلاحيات المناسبة)
- Log Analytics workspace متوصل بالـ Entra ID logs لو عايز تعمل مراقبة بـ KQL
ليه المشكلة دي بتحصل أصلاً
Default Setting في أي تينانت جديد إن "كل المستخدمين، وحتى الـ Guests نفسهم، يقدروا يعزموا مستخدمين خارجيين". يعني الـ Guest اللي انت عزمته أصلاً، ممكن يعزم غيره، وده بيتم بدون أي مراجعة أو موافقة منك. المشكلة تتضخم لأن مفيش أي نوتيفيكيشن تلقائي بتوصلك إن guest عزم guest تاني، ولو الـ Access Reviews مش مفعّلة، هتلاقي الـ guests دول متراكمين لشهور من غير أي تنظيف.
الفكرة الأساسية إن الحل مش "نمنع الـ external collaboration بالكامل"، ده هيوقف الشغل. الحل إنك تتحكم في مين يقدر يعزم، وتحدد نوع الحسابات اللي تقدر تنضم، وتراقب اللي بيحصل بدل ما تفاجأ به.
تحكم في مين يقدر يعزم guest أصلاً
الخطوة الأولى: شوف الوضع الحالي
Connect-MgGraph -Scopes "Policy.Read.All" Get-MgPolicyAuthorizationPolicy | Select-Object AllowInvitesFrom, AllowedToSignUpEmailBasedSubscriptions
لو النتيجة رجعت everyone في AllowInvitesFrom، يعني أي مستخدم عادي، وحتى أي guest، يقدر يبعت دعوة. ده أخطر إعداد ممكن يفضل شغال بدون ما حد يلاحظه.
الخطوة الثانية: قصّر صلاحية الدعوة على الأدمنز فقط
Connect-MgGraph -Scopes "Policy.ReadWrite.Authorization" Update-MgPolicyAuthorizationPolicy -AllowInvitesFrom "adminsAndGuestInviters"
القيم المتاحة في allowInvitesFrom هي: none، adminsAndGuestInviters، adminsGuestInvitersAndAllMembers، و everyone. لو عندك تينانت شركة عادية، أنصح تروح لـ adminsAndGuestInviters كنقطة انطلاق، وده بيمنع الـ Guests من عزم أي حد تاني نهائياً، وبيسيب صلاحية الدعوة للأدمنز والمستخدمين اللي أنت حددتهم كـ Guest Inviter Role بالاسم.
⚠️ لو عندك Microsoft Graph API مباشرة بدون PowerShell، الطلب بيكون:
PATCH https://graph.microsoft.com/v1.0/policies/authorizationPolicy/authorizationPolicy
Content-Type: application/json
{
"allowInvitesFrom": "adminsAndGuestInviters"
}
الخطوة الثالثة: اضبط الـ Guest User Access Restrictions
ده إعداد مختلف عن الدعوة نفسها، وده بيحدد الـ Guest بعد ما ينضم، هو يقدر يشوف إيه من الـ directory. تلاقيه في External Identities > External collaboration settings في البورتال، تحت "Guest user access". اختار "Guest user access is restricted to properties and memberships of their own directory objects" لو مش محتاج الـ guests يتصفحوا باقي المستخدمين أو الجروبات.
استبدال الدعوة الحرة بـ Entitlement Management
لو عندك Entra ID P2، أفضل حل جذري هو إنك توقف الدعوة اليدوية بالكامل وتحول كل التعاون الخارجي لـ Access Packages. الميزة إن كل طلب انضمام بيعدي على approval workflow واضح، وله تاريخ انتهاء (expiration)، وبيتم مراجعته دورياً بـ Access Reviews، فمينفعش guest يفضل موجود "للأبد" من غير أي متابعة.
# مثال لعمل Access Package لجهة خارجية معينة عبر Graph
Connect-MgGraph -Scopes "EntitlementManagement.ReadWrite.All"
$params = @{
displayName = "Partner Collaboration Access"
description = "External partner access, reviewed quarterly"
catalogId = "<catalog-id>"
}
New-MgEntitlementManagementAccessPackage -BodyParameter $params
✅ لما تحول التعاون لـ Access Packages بـ expiration محددة (مثلاً 90 يوم مع تجديد تلقائي بعد approval)، الـ sprawl بيتحل من نفسه لأن أي guest مش نشط أو مش متجدد بيتشال أوتوماتيك.
مراقبة اللي بيحصل بالفعل عبر KQL
مش كل مشكلة تتحل بإعداد واحد، لازم كمان تعرف إذا كان في نشاط غريب في الدعوات. لو عندك الـ Entra ID logs متوصلة بـ Log Analytics أو Defender XDR advanced hunting، الكويري ده بيوريك كل عمليات دعوة الـ guests في آخر 7 أيام:
AuditLogs | where TimeGenerated > ago(7d) | where OperationName == "Invite external user" | extend InitiatedBy = tostring(InitiatedBy.user.userPrincipalName) | extend TargetUser = tostring(TargetResources[0].userPrincipalName) | project TimeGenerated, InitiatedBy, TargetUser, Result | summarize InvitesSent = count() by InitiatedBy | sort by InvitesSent desc
لو لاقيت حساب guest واحد ظاهر في عمود InitiatedBy وباعت أكتر من دعوة أو اتنين، ده علم أحمر إن الحساب ده بيستخدم بشكل غير متوقع، حتى لو الإعدادات الأساسية متضبطة.
| القيمة في allowInvitesFrom | مين يقدر يعزم Guests | مناسب لـ |
|---|---|---|
| everyone | أي عضو أو Guest في التينانت | مؤسسات تعليمية أو مفتوحة جداً، غير مناسب للشركات |
| adminsGuestInvitersAndAllMembers | كل الأعضاء الداخليين فقط، الـ Guests ممنوعين | شركات فيها تعاون خارجي متكرر وموثوق |
| adminsAndGuestInviters | أدمنز والأشخاص المحددين بدور Guest Inviter فقط | أغلب بيئات الشركات، توازن بين التحكم والمرونة |
| none | أدمنز فقط بأدوار محددة | بيئات عالية الحساسية أو Regulated industries |
مشاكل شائعة وحلولها
| المشكلة | الحل |
|---|---|
| غيرت allowInvitesFrom لكن الـ guests لسه قادرين يدعوا | تأكد إن التغيير اتطبق فعلاً بـ Get-MgPolicyAuthorizationPolicy، وشيك إن مفيش policy ثاني على مستوى الـ B2B collaboration settings بيطغى عليه |
| عندي guests قدام مش متأكد ليه اتعزموا أصلاً | شغّل Access Review على مستوى الجروب أو الـ resource، وسيب المستخدمين الداخليين يأكدوا هل لسه محتاجين الوصول ولا لأ |
| شركاء بيشتكوا إنهم مش قادرين يعزموا زمايلهم زي زمان | دي علامة صحية غير Bug، حولهم لـ Access Package عندهم Approval Workflow واضح بدل الدعوة الحرة |
| Guests قديمة نشطة من سنين ومحدش يعرف تشيلها ليه أصلاً | فعّل Access Review دوري (كل 90 يوم) على كل الـ guests في التينانت، مش فقط على resource واحد |
نصائح الأمان 🔐
- خلي الـ Guest Inviter Role مربوطة بـ PIM بدل ما تكون Standing Assignment، عشان محدش يفضل معاه الصلاحية دايماً بدون احتياج
- لو مضطر تسيب الدعوة مفتوحة لأعضاء داخليين، ضيف Conditional Access policy تفرض MFA على الـ guests بمجرد ما ينضموا، مش تعتمد على الشركة الأصلية بتاعتهم
- راجع الـ Cross-tenant access settings مع الشركاء الأساسيين، وحدد Inbound/Outbound trust بدل ما تسيبه Default لكل الدنيا
- متسيبش Access Package بدون expiration date، حتى لو الشريك دائم، خليها تتجدد بـ approval كل فترة
- راقب الكويري بتاع KQL فوق كـ Scheduled Alert في Sentinel أو Defender، مش تفتحه يدوي بس وقت الشك
الخلاصة
مشكلة guest-inviting-guest مش حاجة تحصل بسبب هجوم أو ثغرة، هي نتيجة طبيعية لإعدادات افتراضية سايبة مفتوحة من غير حد يراجعها. الحل مش معقد تقنياً، بس محتاج قرار واضح إنك تتحكم في مين يعزم، بدل ما تسيب الباب مفتوح للكل.
- راجع قيمة allowInvitesFrom الحالية وقصّرها لـ adminsAndGuestInviters على الأقل
- حول التعاون المتكرر مع شركاء لـ Access Packages بـ expiration واضح بدل الدعوة اليدوية
- شغّل مراقبة دورية بـ KQL على عمليات الدعوة، ومتعتمدش على المراجعة اليدوية فقط
- فعّل Access Reviews دورية على كل الـ guests في التينانت، مش على resource واحد بس
إنت واجهت الموضوع ده في تينانت بتاعك قبل كده؟ شاركنا في التعليقات إزاي لقيت الـ sprawl عندك وإزاي عالجته.

Comments
Post a Comment