טוקנים ומשך זמן סשן – Azure AD
תראה לי את מצב הזהויות אצלך בארגון ואומר לך מהי רמת האבטחה שלך – אפשר ללמוד כל כך הרבה על אופי, גישה ורמת האבטחה בענן, או בסביבה היברידית מתוך תשתית הזהויות והאופן שבו המשתמשים עובדים ביומיום.
בסביבות ענניות והיברידיות הזהות היא הדבר החשוב מכל! לכן, אימות, הפעלות, טרנזקציות, משך החיים של טוקן ובקרות גישה יכולות להעיד בצורה נרחבת על סוגי הגנות, מגבלות, נקודות תקיפה, חשיפות ועוד.
כולנו מכירים את העובדה שתשתית Active Directory מקומית היא שטח רחב לתקיפה וניצול, ולכן ישנם מקרים מסויימים/בודדים (לא נחלת הכלל) שבהם ישנה היגיינת אבטחה מספקת או מתקדמת. ומה עם הענן? לצד העובדה שזהויות ענניות מביאות גישה אחרת הם עדיין לא קיבלו התייחסות מתאימה. אגב, אותה תשתית Active Directory מחוברת לתשתית זהויות בענן ולכן, אנו לוקחים חלק מהבעיות מתוך הסביבה המקומית ישירות אל הענן.
ביומיום אני נתקל במצבים מגוונים בהם ישנה חשיפה עקב ניהול זהויות לקוי, בין היתר אפשר למצוא מקרים כמו:
- ריבוי דירקטורי שמתפרסים על גבי מספר סביבות וכל זהות קיימת בנפרד עם סיסמאות שונות, טוקן לייפטיים שונה, הרשאות ספציפיות ושאר פערים.
- קיים ספק זהויות אך הוא אינו מחובר לכלל התשתיות המרכזיות ולכן משתמשים עובדים באופן שונה בכל תשתית.
- בקרות גישה אינן קיימות על כלל המשתמשים ולכן אין אפשרות לנטר גישה ולהבין סיכונים ואיומים.
- תשתית זהויות עם פערים שמאפשרת לתקוף את הענן בתריסרי טקטיקות ועם אפשרויות ניצול למכביר.
כמו במקרים אחרים גם כאן, הגדרות ברירת מחדל או מיסקונפיגורציה מובילות לפערים עצומים בתשתית Azure AD ומכן זה מוביל לגניבת זהויות, גניבת טוקנים, חוסר פסיכי בנראות והאפשרות לנחות ולנוע במרחב הענן אינה דבר גס.
אחד הדברים שאני מעלה תקופה כל כך ארוכה היא העובדה שאין אפשרות לזהות גורם תקיפה שמבצע אנומרציה וסריקות מול הנכסים בענן ובפרט זהויות, עם זאת, ישנם מצבים מסויימים שאנו יכולים לזהות נגיעות בגדר, גם כאלה של זהויות, למשל, ניסיונות לביצוע Spary / BF.
דוגמה מהשטח. למי שעובד עם Defender for Cloud (MDA) או CASB כלשהוא שווה ערך שיודע לזהות ניסיונות תקיפת זהויות אז ניתן לראות בבירור מי מנסה לגעת בגדר. במקרים רבים קבוצות וגורמי תקיפה מריצים ניחוש או ריסוס סיסמאות על זהויות היברידיות, ולכן גורמים לנעילה של המשתמשים, באופן טבעי לכל הזהות עצמה ולכן המשתמש יהיה נעול מקומית ולא רק בענן. העניין הוא שלרוב אנו לא יודעים בכלל שגורם תקיפה מסוים סורק אותנו מבחוץ – במקרים כאלה שאין בקרות או שאינן מוגדרות בצורה מיטבית, ארגונים מוצאים את עצמם רודפים אחרי תקלות טכניות שלכאורה נראות רגילות אבל משהו עומד מאחורי הבעיות האלה.
שאילתה פשוטה בממשק MDA יכולה לזהות גורמים שמגיעים מתוך כתובות או מיקומים זדוניים – לרוב, אין לזה נראות או פוליסי שמעלה דגל בבקרות.
טיפ: בכדי לעבוד נכון עם השאילתה יש להוסיף תנאים נוספים של מסגרות זמן, סף נגיעות, טווחי כתובות ושאר תנאים שיכולים לדייק את הזיהוי ברמת הבורג.
סשן וכאלה
סשן (web/idp session) הוא רצף של בקשות HTTP ותגובה המשויכות לאותו משתמש. אפליקציות דורשות שמירה על המידע או על מצב המשתמש למשך בקשות מרובות. לכן, סשנים מספקים את היכולת ליצור משתנים – כגון זכויות גישה והגדרות לוקליזציה – שיחולו על כל אינטראקציה שיש למשתמש עם האפליקצייה למשך המופע.
אפליקציות יכולות ליצור סשנים בכדי לעקוב אחר משתמשים אנונימיים וזאת לאחר הבקשה הראשונה. דוגמה לכך תהיה שמירה על העדפות המשתמש. בנוסף, אפליציות יעשו שימוש בסשנים לאחר אימות המשתמש. זה בתורו מבטיח את היכולת לזהות את המשתמש בכל בקשה עוקבת ומתמשכת, כמו גם את היכולת להחיל בקרות גישה לאבטחה, גישה מורשית לנתונים, ולהגדיל את השימושיות של האפליקציה. לכן, אפליקציות מספקות יכולות ברמת הסשן הן לפני והן לאחר האימות.
לאחר יצירת סשן מאומת, מזהה הסשן, ליתר דיוק הטוקן גישה שווה באופן זמני לשיטת האימות החזקה ביותר המשמשת את האפליקציה, כגון שם משתמש וסיסמה, סיסמאות חד-פעמיות (OTP), קרדס/אישורים דיגיטליים, כרטיסים חכמים או ביומטריה ושאר מזהים חכמים.
HTTP הוא פרוטוקול חסר מצב, שבו כל זוג בקשות ותגובות אינו תלוי באינטראקציות ווב אחרות. לכן, על מנת להציג את הרעיון של הסשן, נדרש ליישם יכולות ניהול סשן המקשרות הן את מודולי האימות והן את מודולי בקרת הגישה או ההרשאה הזמינים בדרך כלל באפליקציות.
מזהה הסשן או הטוקן, הוא זה שמאגד את אישורי אימות המשתמש מול תעבורת HTTP של המשתמש ולבקרי הגישה המתאימים הנאכפים ע״י האפליקציות.
המורכבות של שלושת המרכיבים הללו; אימות, ניהול ובקרת גישה באפליקציות, בתוספת העובדה שהיישום שלהם מוצמד, הופכת את היישום של מודול ניהול הסשן מאובטח למאתגר מאוד.
החשיפה, הלכידה, החיזוי, ברוט פורס ואחרים יובילו לחטיפת סשן, שבהן תוקף מסוגל להתחזות באופן מלא למשתמש. תוקפים יכולים לבצע שני סוגים של התקפות חטיפת סשן: ממוקדות או גנריות. בהתקפה ממוקדת, מטרתו של התוקף היא להתחזות למשתמש ספציפי או מורשה. עבור התקפות גנריות, המטרה של התוקף היא להתחזות או לקבל גישה כמו כל משתמש חוקי או לגיטימי.
אם כך מה עושים עם טוקן, סשן וגישה בתשתיות ניהול זהויות (idp)? בתשתית הזהויות של Azure AD ישנן יכולות מורחבות שיודעות להתמודד עם מצבים רבים כולל מצבי קצה של טוקן, גישה וסשן. לצד זה שהתשתית מציעה סט רחב של אפשרויות בהשוואה לאחרים הוא עדיין אינו סוגר מצבים רבים.
מתחת למכסה מנוע של Azure AD
תשתית Azure AD הוא שירות זהות וניהול גישה מבוסס ענן המספק אימות ואישור מאובטח ליישומים ומשאבים שונים. אחת התכונות של Azure AD היא ניהול Lifetime Session, המאפשר להגדיר כמה זמן משתמשים יכולים לגשת ליישומים ומשאבים אלה מבלי לאשר מחדש.
ישנם סוגים שונים בקשות וזיהוי ב Azure AD, כגון טוקן SSO, טוקן רענון, טוקן גישה וטוקן רענון (PRT). לכל סוג סשן יש משך זמן ברירת מחדל שניתן לשנות באמצעות מדיניות Adure AD או מדיניות גישה מותנית (Azure AD Condtional Access). לדוגמה, לטוקן הפעלה של SSO יש משך זמן ברירת מחדל של 24 שעות למופעים שאינם מתקיימים ומשך זמן של 180 יום למופעים מתמשכים. לטוקן רענון יש משך זמן ברירת מחדל של 90 יום.
ניהול משך זמן הסשן יכול לעזור בשיפור אבטחה וחוויית משתמש על ידי צמצום הסיכון לגישה בלתי מורשית או גניבת קרדס/אישורים, כמו גם צמצום הנחיות והפרעות אימות. עם זאת, ישנם גם כמה שיקולים בעת קביעת תצורה של אפשרויות לסשן, כגון תאימות ליישומים מדור קודם, השפעות ביצועים, תאימות למכשירים ועוד.
אם כך מה קורה מתחת למכסה מנוע של Azure AD? הרבה מאוד, ואנו נוגעים במאמר רק בחלקים מסויימים וקטנים.
השאלות הפשוטות שעולות בניהול סשנים ובגישה מתרכזות לסוגיה מוכרת ובשאלה; למשך כמה זמן המשתמשים מחוברים? מהי הגמישות האפשרית בביטול גישה של משתמש שנפרץ? הבעיה פשוטה, אך התשובה מורכבת: איזה איזון ניתן למצוא בין חוויית המשתמש לבין משך חיי הסשן והגישה? התשובות יכולות להיות בין היתר:
- צריך להגדיר את משך הזמן הקצר ביותר האפשרי – זה לא נדיר לרצות להגדיר כמה שעות או בכל כניסה מחדש לפי תנאי.
- חוויית המשתמש יכולה להיות כל כך גרועה שהיא תוביל באופן פרדוקסלי לירידה באבטחה.
ההשלכות הישירות הן שמשתמשים מבצעים אימות מבלי לחשוב שזה מהווה סיכון לפישינג או הנדסה חברתית.
כדי לשלוט באורך החיים וניהול משך זמן של הסשנים אנו צריכים לנהל את הסיכונים הקשורים. התשתית של Azure AD מספקת תריסרי אפשרויות, אלה הם הבסיסיות שבהן:
- הגדרת KMSI או השאר אותי מחובר.
- מדיניות גישה מותנית עם תדירות כניסה והתמדה ברמת הסשן.
- הערכת גישה רציפה (CEA).
- קביעת תצורה של משך החיים של טוקן גישה.
- ברירות המחדל של עמידות.
הבנת האפשרויות השונות של Azure AD היא המפתח למציאת האיזון הטוב ביותר עבור האבטחה הנדרשת.
טיפ: מכיוון שתשתית Azure AD מציעה גרנולריות מתקדמת אנו יכולים ליצור תנאים וחוקים למצבים שונים ברמת סינגלים שונים.
כאשר משתמש מבצע אימות ליישום Azure AD, לדוגמה, Exchange Online, הוא יקבל זוג טוקנים שיאפשרו לו לצרוך את השירות וסרוויסים נלווים:
טוקן גישה
- טוקן גישה משמש לאימות למשאב והוא מכיל מספר פיסות מידע כגון תאריך התפוגה וההרשאות שלו, לדוגמה: Mail.ReadWrite. ניתן להשתמש בטוקן גישה רק עבור שילוב ספציפי של משתמש, לדוגמה: elli@lab-365.onmicrosoft.com, עם היישום המבקש Outlook ומשאב שהוא Exchange Online.
- טוקן גישה חתום שיכול למנוע זיוף טוקן.
- מכיוון שטוקן גישה הוא טוקן נושא, כל אדם בעל טוקן גישה יכול לבצע אימות באמצעות ההרשאות המוגדרות.
- טוקן גישה אינו כולל מצבי CEA שבהם ניתן להשפיע על משך החיים של טוקן.
טוקן רענון
- כברירת מחדל, טוקן גישה תקפים למשך שעה אחת. כאשר תוקפם פג, הגישה מנותבת מחדש אל Azure AD כדי לרענן אותם. תקופת רענון זו מספקת הזדמנות להעריך מחדש מדיניות עבור גישה.
- אם בקשת הגישה אינה מפרה את המדיניות, טוקן הרענון משמש ליצירה מחדש של זוג טוקנים – גישה / טוקן רענון חדש מבלי לבקש מהמשתמש לבצע אימות מחדש.
- לטוקן הרענון יש משך זמן (חלון) של 90 יום – משמעות הדבר היא כי במקרה של שימוש מתמשך, זה אף פעם לא פג.
- החל מתאריך 30 בינואר 2021, משך הזמן זה אינו ניתן עוד לשינוי.
כדאי לדעת כי טוקן הרענון הוא ספציפי למבקש אך ניתן להשתמש בו עבור מספר משאבים. במילים אחרות, טוקן הרענון מאפשר לבצע אימות ליישומי Azure AD שונים, לדוגמה, Exchange Online או Teams מבלי שתצטרך לבצע אימות מחדש במפורש בכל פעם:
- בתוך בראוסר.
- בתוך אפליקציות למכשירים שבהם מותקן טוקן תוכנה מבוסס Microsoft.
- בתחנת עבודה רשומה, כגון: Hybrid Azure AD או Azure AD Joined.
במקרה של נקודת קצה המוכרת ע״י Azure AD, ייווצר טוקן רענון ראשי (PRT) בכל חיבור בתחנת העבודה של המשתמש. מכאן, ייעשה בו שימוש חוזר בתוך האפליקציות השונות לצורך אימות.
אם כך באילו מקרים מבטלים טוקן?
מבחינה היסטורית, לא ניתן לבטל טוקן גישה. ברוב המקרים, טוקן רענון יכול להיות מבוטל עקב שינוי באישורים/קרדס, פעולת משתמש או אכיפת מדיניות ספציפית. התנאים השונים לביטול טוקן רענון:
- תוקף הסיסמה פג
- שינוי הסיסמה ע״י המשתמש
- המשתמש מבצע SSPR
- בוצע איפוס סיסמה
- ביטול טוקן באמצעות PowerShell
כדאי לשים לב שרק ביטולים מפורשים של טוקן רענון באמצעות PowerShell יכולים להבטיח את ביטולם של כלל הטוקנים, ללא קשר לסוג האימות, סיסמה או קובצי Cookie.
טיפ: בתקריות רבות בהם ישנו הפרה של זהות המשתמש ביטול הטוקן אינו נעשה בצורה הנכונה ומשאיר את הטוקן זמין
KMSI – הישאר מחובר
הפורם של הישאר מחובר מופיע לאחר שמשתמש נכנס בהצלחה. תהליך זה נקרא השאר אותי מחובר – KMSI. אם משתמש עונה בחיוב לבקשה זו, שירות KMSI מעניק לו טוקן רענון. לאחר הכניסה לבראוסר, המשתמש יוצג עם האפשרות הישאר מחובר? אם הוא לוחץ על כן, נוצרת הפעלת בראוסר מתמשכת על מנת לאפשר למשתמש להישאר מחובר לאחר סגירה ופתיחה מחדש של חלון הבראוסר שלו – וזאת לא מאשר, באמצעות קובץ Cookie.
הגדרת KMSI זמינה בהגדרות המשתמש. תכונות מסוימות של SharePoint Online או Office תלויות בכך שמשתמשים יוכלו לבחור להישאר מחוברים. אם מבטלים את סימון האפשרות הצג כדי להישאר מחובר, המשתמשים עשויים לראות בקשות אחרות במהלך תהליך הכניסה.
רקורדים אודות שגיאת הכניסה נמצאים ביומני הרישום של Azure AD.
- קוד שגיאה: 50140.
- קוד כשל: שגיאה זו אירעה עקב אפשרות השאר אותי מחובר כאשר המשתמש נכנס.
יש אפשרות למנוע ממשתמשים לראות את ההודעה על-ידי הגדרת האפשרות הצג כדי להישאר מחוברים בהגדרה של דיסבול בהגדרות המשתמש. הגדרה זו הופכת את בקשת KMSI ללא זמינה עבור כל המשתמשים של Azure AD.
ישנה אפשרות להשתמש בהפעלת בראוסר מתמיד מתוך גישה מותנית כדי למנוע ממשתמשים לראות את בקשת KMSI. אפשרות זו מאפשרת לך להפוך את בקשת KMSI ללא זמינה עבור קבוצה נבחרת של משתמשים מבלי להשפיע על אופן הפעולה של הכניסה עבור כלל המשתמשים.
כדי להבטיח שבקשת KMSI תוצג רק כאשר היא יכולה להועיל למשתמש, בקשת KMSI אינה מוצגת במכוון בתרחישים הבאים:
- המשתמש מחובר באמצעות SSO ואימות משולב של IWA
- המשתמש מחובר באמצעות שירותי הפדרציה של Active Directory ו- IWA
- המשתמש הוא אובייקט Guest
- משתמש עם דירוג גבוה ברמת הסיכון
- הכניסה מתרחשת במהלך זרימת הסכמת המשתמש או מנהל המערכת
- תנאי התמדה ברמת הבראוסר מוגדרת במדיניות גישה מותנית
מדיניות גישה מותנית
מדיניות גישה מותנית מאפשרת לכפות אופן פעולה של תדירות כניסה (User sign-in frequency) והתמדה (Persistence) עבור סשנים. זוהי השיטה לקבוע מתי משתמשים צריכים לבצע אימות מחדש.
כדאי לדעת שאם ספק זהויות צד שלישי (או IDP) אחראי על אימות המשתמש, הוא יכול לאפשר גישה רק לשירות/סרוויס. מצד שני, ברגע שנכנסים פנימה, משך זמני הסשן המוגדרים כברירת מחדל חלים ולא ניתן לנהל אותם ללא אחת מהאפשרויות הבאות.
טיפ: תכונה זו מחליפה את היכולת לשנות את משך החיים של טוקן הרענון שהוסר החל מתאריך 31 בינואר 2021.
אם הפרמטר תדירות כניסה פעיל אז טוקן רענון ישן יותר יבוטל במהלך הערכתו מחדש (ברמת הגישה), ולכן, המשתמש יצטרך לבצע אימות מחדש ויראה את ההודעה המוכרת של לוגין.
תדירות הכניסה פועלת עבור מצבים של מימוש OAuth2 או OpenID Connect. אפליקציות תואמות במידה ואימות מופעל. עם זאת, מיקרוסופט מציבה שתי נקודות תשומת לב קדימה:
- אם יש מכשירים רשומים ב Azure AD, כאשר משתמש מבטל את נעילת המכשיר שלו או נכנס באופן אינטראקטיבי, אירוע זה יספק גם את מדיניות תדירות הכניסה, מכיוון שייווצר טוקן רענון חדש.
- אם האפשרות זכור MFA בהתקנים מהימנים מופעלת, יש להשבית אותה לפני השימוש בתדירות הכניסה, מכיוון ששימוש בשתי הגדרות אלה יחד עלול להוביל להצגת הודעה למשתמשים באופן בלתי צפוי ואינו יבעוד נכון עם הטוקנים.
טיפ: אם ההגדרה הפעלת בראוסר מתחלפת מופעלת: מדיניות הגישה המותנית עוקפת את האפשרות השאר אותי מחובר שנבחרה על-ידי המשתמש.
במכשירים המצורפים אל Azure AD ביטול נעילת המכשיר או כניסה אינטראקטיבית ירעננו את טוקן הרענון הראשי (PRT) רק כל 4 שעות. חותמת הזמן האחרונה של הרענון שנרשמה עבור PRT בהשוואה לחותמת הזמן הנוכחית חייבת להיות בתוך הזמן המוקצב במדיניות SIF כדי ש PRT יספק את SIF ויעניק גישה ל PRT שיש לו דרישת MFA קיימת. במכשירים הרשומים ביטול נעילה/כניסה לא יספקו את מדיניות SIF מכיוון שהמשתמש אינו ניגש למכשיר רשום של Azure AD באמצעות חשבון Azure AD. עם זאת, התוסף Azure AD WAM יכול לרענן PRT במהלך אימות אפליקציה בצמוד ל WAM.
טיפ: חותמת הזמן שנלכדה מכניסה של המשתמש אינה בהכרח זהה לחותמת הזמן האחרונה שתועדה של רענון PRT בגלל מחזור הרענון של 4 שעות. המקרה שבו הוא זהה הוא כאשר פג תוקפו של PRT וכניסת משתמש מרעננת אותו למשך 4 שעות.
הערכת גישה רציפה
כדי להגביל את הסיכון הקשור לחלון זמן עבור טוקן גישה, ניתן להשתמש באפשרות של הערכת הגישה הרציפה (Continuous access evaluation).
תפוגת טוקנים ורענון הם מנגנון סטנדרטי. כאשר אפליקציה מתחברת לשירות כגון Exchange Online, בקשות API מאושרות באמצעות טוקן גישה של OAuth 2.0. כברירת מחדל, טוקן גישה תקפים למשך שעה אחת, כאשר תוקפם פג, המשתמש (בקשה/אפליקציה) מנותבת מחדש אל Azure AD כדי לרענן אותם. תקופת רענון זו מספקת הזדמנות להעריך מחדש פריטי מדיניות עבור גישת משתמשים. לדוגמה: ייתכן שנבחר שלא לרענן את הטוקן עקב מדיניות גישה מותנית, או משום שהמשתמש מדוסבל במערכת מאז הבקשה האחרונה.
תגובה בזמן להפרות מדיניות או לבעיות אבטחה דורשת למעשה שיח בין מנפיק הטוקן שהוא Azure AD לבין הצד המסתמך (אפליקציה כלשהיא). השיח הדו-כיווני מעניק יכולות חשובות. הצד המסתמך יכול לראות מתי מאפיינים משתנים, כגון מיקום רשת, ולהודיע על כך למנפיק. זה גם נותן למנפיק דרך לומר לצד המסתמך להפסיק לכבד טוקן עבור משתמש נתון בגלל פגיעה בחשבון, השבתה או חשש אחר. המנגנון לשיח הוא הערכת גישה רציפה (CAE). המטרה של הערכת אירועים קריטיים היא שהתגובה תהיה קרובה לזמן אמת, אך ניתן להבחין בהשהיה של עד 15 דקות בגלל זמן התפשטות האירוע; עם זאת, אכיפת מדיניות מיקומי IP היא מיידית.
תכונה זו מאפשרת לבטל טוקן גישה ולכפות אימות מחדש של המשתמש במקרה של אירוע או שינוי הקשר עבור לקוחות תואמים.
במקרה של התרחשות אירוע: השירותים מקבלים כעת מידע במקרה של אירוע קריטי:
- חשבון המשתמש נמחק או מושבת
- סיסמה עבור משתמש משתנה או מאופסת
- אימות רב-גורמי זמין עבור המשתמש
- המערכת מבטלת במפורש את כל טוקן הרענון עבור משתמש
- סיכון משתמש גבוה שזוהה ע״י Azure AD Identity Protection
במקרה של שינוי יחס והקשר – אפליקציות/סרוויס, כגון Exchange Online, SharePoint Online, Teams ו Graph מאחזרים עותק של מדיניות הגישה המותנית. במקרה של שינוי הקשר שזוהה, הוא יאלץ את המשתמש לבצע אימות מחדש. פונקציונליות זו זמינה עבור תנאים מסויימים.
במקביל לכך ישנו שיפור קל בערכי ברירת המחדל של משך החיים של טוקן הגישה:
- עבור מצב לתנאי CAE: בין 20 ל-28 שעות, בהתאם לשירות
- עבור מצב שאינו תואם לתנאי CAE: כשעה
העלייה במשך החיים של טוקן הגישה יכולה להוות בעיית אבטחה מכיוון שחילוץ של טוקן גישה עם משך חיים ארוך יהפוך אותו לניצול למשך זמן ארוך וזה לא ממש מתחבר בהיגיון ובגישה של מודל Zero Trust.
תצורה במשך החיים של טוקן הגישה
עם כניסתה של הערכת גישה רציפה (CEA), ייתכן שיהיה מעניין לחשוב על משך החיים של טוקן גישה, אם ערכי ברירת המחדל שהוגדרו אינם מתאימים, בהתאם למצב של 1 שעות עבור תנאי תואם CAE ועד 28 שעות עבור תנאי CAE.
כדי לשנות אותם, יש צורך להגדיר מדיניות טוקנים ולהחיל אותה:
- כברירת מחדל לכל היישומים.
- או ליישום ספציפי.
- לפי תנאים נוספים במדיניות.
יצירה זו נעשית באמצעות PowerShell.
עם זאת, חשוב לציין כי כל טוקן גישה חדש יכבד ערך זה.
אילו שיטות עבודה מומלצות? במאמר הבא.
עוד על זהויות במאמר הבא Microsoft identity platform documentation – Microsoft Entra | Microsoft Learn