רוטציית סודות: היכן מפתחות סטטיים שוברים את התשתית
אותו מפתח גישה למסד הנתונים חי בקונפיגורציה של השירות, במשתני הסביבה של מערך הבנייה, בתסריטי הפריסה ובגיבוי של הקונפיגורציה על דיסק הצומת.
כעבור חצי שנה הוא מופיע גם בהתכתבות עם קבלן חיצוני, בסביבת בדיקות שהורמה מעותק של סביבת הפרודקשן, ובהיסטוריית המאגר (repository), שממנה אי אפשר להסיר אותו בתיקון של קובץ אחד. תוקף המפתח לא הוגדר — הוא שווה לתוחלת החיים של הפרויקט, ואיש אינו יכול לומר כמה עותקים באמת קיימים.
דליפת פרטי זיהוי במבנה כזה היא שאלה של «מתי», ולא של «אם». די בייצוא אחד של לוגים עם פלט דיבאג, או בארכיון שנשלח למשאב קבצים משותף. מכאן פועלת התכונה המרכזית של מפתח סטטי: הוא אחד, ולכן כל עותק שדלף שקול לגישה לכלל המערך — למסד הנתונים בפרודקשן, לתור, למאגר הארטיפקטים.
אי אפשר לבטל אותו באופן ממוקד: אותה גישה בסיסמה משותפת רשומה בעשרות צמתים ובאינטגרציות חיצוניות. ההחלפה הופכת לסבב ידני, לחלון השבתה, ובעיקר — לצומת נשכח שממשיך לעבוד עם המפתח הישן ונשאר דלת פתוחה. אין במה לבדוק שהסוד הקודם אינו בשימוש בשום מקום אחר — אין תיעוד של היכן כל מפתח משמש.
נבחן כיצד סוגרים זאת: היכן לאחסן את המפתח כך שלא ייכנס כלל לקונפיגורציות, כיצד להגדיר לו תוקף וכיצד לבטל גישה בלי לעצור את השירות.
מה משתנה לאחר אוטומציה של החלפת מפתחות
חלון הדליפה מצטמצם משבועות לדקות
הסוד חי בדיוק כל עוד צוין במדיניות, ומונפק מחדש לפי לוח זמנים, ולא «כשנתפנה לכך». גם אם המפתח דלף ללוג הבנייה או למאגר חיצוני, עד הרגע שבו ינסו לעשות בו שימוש — הוא כבר לא בתוקף. ביטול של ערך שנחשף הוא פעולה אחת, ולא סבב בעשרות צמתים עם תיקון ידני של קונפיגורציות.
מפתחות קצרי-מועד במקום מפתחות ארוכי-טווח
היישום עצמו מבקש פרטי זיהוי ממאגר הסודות ומקבל אותם לתקופה מוגבלת, ומאריך את הגישה לפני שפג תוקפה של הקודמת. אין צורך לאתחל שירותים בעת החלפת הסיסמה — הערכים החדשים נקלטים תוך כדי תנועה, והישנים מתבטלים. ההרשאות ניתנות לפי תפקיד מוגדר: שירות אחד לא מקבל גישה למסדי נתונים של אחרים, אפילו לא בטעות.
פעולות ידניות יוצאות מתורנות הכוננות
החלפת סיסמאות מפסיקה להיות משימה שמישהו זוכר ומבצע לפי לוח שנה. המהנדס מתאר את המדיניות פעם אחת — תוקף, תדירות, תחום החלות — ומכאן ההחלפה מתבצעת בלי מעורבות אדם וללא חלון השבתה. התורן כבר לא מטפל בתקלות מהסוג של «השירות נפל כי מישהו עדכן סיסמה במקום אחד ושכח במקום אחר».
סוג התקלות «שכחו להחליף» מבוטל
כל הצרכנים של הסוד מקבלים אותו ממקור אחד, ולכן חוסר הסנכרון בין סביבות נעלם כקטגוריה. בדיקות בצינור הבנייה נכשלות אם הסוד מופיע בקוד או חי יותר מהתקופה שנקבעה. הדבר ממיר את הדליפה מ«יום אחד נדע» לאירוע מדיד עם זמן תגובה ידוע — עד כדי דקות.
מצבי החלפת מפתחות: השוואת גישות ומגבלות
את מצב ההחלפה בוחרים לפי שני מאפיינים: היכן פיזית נמצא הסוד ומה משמש כטריגר לעדכון. במאגרים כמו HashiCorp Vault הסוד אינו נכנס לקונפיגורציה — סוכן בצומת מבקש אותו בעת עליית השירות, ולכן ההחלפה אינה דורשת תיקון קבצים ואתחול ידני של הצרכנים. שאר האפשרויות פשוטות יותר ליישום, אך לכל אחת נקודת כשל משלה וסוג השהיה משלו.
| אפשרות | כיצד בנויה | מתי מתאימה | מגבלות |
|---|---|---|---|
| מאגר מפתחות מרכזי + סוכן בצומת | הסוד מונפק ליישום באמצעות טוקן קצר-מועד | שירותים וסביבות רבים | המאגר הופך לצומת קריטי: נדרש נתיב הנפקה חלופי |
| החלפה לפי לוח זמנים | משימה תקופתית מעדכנת את הסוד ומאתחלת את הצרכנים | מערכים יציבים עם חלון תחזוקה | המפתח מוחלף בלי קשר לסיכון; נוהל החזרה מוכן מראש |
| החלפה לפי אירוע | הטריגר — עזיבת עובד, דליפה, החלפת קבלן | דרישות אבטחה וביקורת | בלי גלאי אירועים מתנוונת לפעולה ידנית |
| נוהל החלפה ידני | אחראי, תור בקשות, פרוטוקול | מערך קטן ללא אוטומציה | ההשהיה נמדדת בימים, גורם אנושי, אינו מתרחב |
בפועל משלבים בין המצבים: המאגר מטפל בהנפקה, האירוע — בהחלפה שלא מתוכננת, ולוח הזמנים מכסה מפתחות נשכחים. אנחנו מתעדים את הסכימה הזו בתיעוד יחד עם נוהל החזרה, כדי שעדכון הסוד לא יהפוך להשבתת שירות.
שלבי יישום רוטציית סודות במערך קיים
רוטציית סודות שוברת את הפרודקשן לא ברגע ההפעלה, אלא כשמתברר שמפתח נקרא על ידי שירות שאיש לא זכר: מתזמן, וורקר ישן, סקריפט של המהנדס התורן. לכן העבודה מתקדמת ממיפוי מלאי (inventory) להפעלה הדרגתית, ולא להפך — בכל שלב חייב להתקיים אמצעי להחזיר את המערך למצבו ההתחלתי.
- מיפוי מלאי הגישות. אוספים את כל המקומות שבהם נמצאים סיסמאות, טוקנים ומפתחות: קונפיגורציות של יישומים, משתני סביבה, מערכי בנייה, גיבויים ואינטגרציות עם מערכות חיצוניות. עבור כל סוד מתעדים בעלים, ייעוד ותוקף נוכחי.
- מפת תלויות בין שירותים. קובעים מי וכיצד קורא כל סוד: בעת עליית התהליך או תוך כדי תנועה, האם קיים מטמון, כמה זמן חי החיבור. בלי המפה הזו, החלפת מפתח גורמת לכשל מדורג במקום לעדכון מתוכנן.
- סכימת הנפקת מפתחות. מתכננים מקור אחיד לסודות, הפרדת הרשאות לפי שירותים ותפקידים, והפרדה בין סביבות. הלקוחות אינם שומרים את הערכים אצלם, אלא מבקשים אותם בעת ההפעלה ובסיום התוקף.
- הגדרה ובדיקה בסביבת בדיקות. המערך משחזר את הפרודקשן בהרכב השירותים. מריצים תרחישים עם תוקף סוד קצר בכוונה, ובוחנים את ההתנהגות כשאין גישה למקור, ובמקביל כשמספר שירותים מתעדכנים בו-זמנית.
- הפעלה הדרגתית. מתחילים מסודות שיש להם צרכן אחד ומחיר טעות נמוך, ומשם מרחיבים את הכיסוי. כל שלב הוא שינוי נפרד עם נראות (observability) ויכולת לכבות את הרוטציה עבור קבוצה מסוימת.
- נוהל חזרה ומסירה. מתארים את החזרה לערך הקודם, את פעולות התורן בעת שגיאות אימות המוניות ואת סדר הוספת שירותים חדשים. הסכימה, מפת התלויות והנוהל נשארים בידי צוות הלקוח.
מה נשאר בידי הצוות לאחר המסירה: ארטיפקטים ונהלים
המסירה אינה מסתיימת במתן גישה למאגר: הצוות מקבל סט ארטיפקטים במאגר (repository), שכל אחד מהם ניתן לפתוח, לבדוק ולשחזר במערך אחר. להלן מה נשאר בידיים ולשם מה נדרש כל מסמך.
- קונפיגורציות רוטציה: לוחות זמנים להחלפה לפי סוגי סודות — סיסמאות למסדי נתונים, מפתחות API חיצוניים, תעודות — עם מרווחים, חלון תאימות וציון אילו שירותים קולטים את הערך בלי אתחול.
- סכימת זרימת מפתחות: מהנפקה במאגר ועד להגעה לתהליך — מי קורא, דרך אילו צמתים, והיכן הערך אסור שיופיע בלוגים ובמשתני הבנייה.
- מדיניות גישה: למי נראה איזה סוד, מי רשאי להפעיל החלפה ידנית, מי רק קורא, ומה קורה כשמהנדס עוזב את הצוות.
- הוראות למשמרת התורנות: תרחישים של תקלות אופייניות — שירות מחזיק חיבור ישן, סוד חדש לא הגיע, תעודה בוטלה; למה להסתכל ובאיזה סדר לפעול.
- תיעוד תשתית: מפת שירותים ותלויות, מקומות אחסון הסודות, נקודות כשל ובעלי הצמתים.
- נוהל הוצאת צומת משימוש: רצף ביטול המפתחות ומחיקת הסודות, כדי שלאחר ההוצאה לא יישארו גישות פעילות.
- צ'ק-ליסט לבדיקת הרוטציה: כיצד לוודא שההחלפה אכן בוצעה, ולא רק נרשמה בלוג — קריאת בקרה, ביקורת לוגים, בדיקת חזרה.
מקרה בוחן: צמצום חלון הדליפה לדקות במערך מבוזר
מערך מבוזר: מספר אשכולות, סביבות נפרדות לפיתוח ולעומסי פרודקשן, בניהול של יותר מ-130 צמתים. לפני ההתחלה ערכנו מיפוי מלאי של הסודות — היכן הם נמצאים, כמה עותקים קיימים, למי יש גישה.
התמונה שהתגלתה הייתה אופיינית: סיסמאות למסדי נתונים ולשירותים חיצוניים שוכפלו במשתני סביבה, בקבצי קונפיגורציה ובחלקם גם במאגרים.
המצב לפני
את המפתח למסד הנתונים החליפו ידנית: תיאום חלון, תיקון קונפיגורציה בכל הצמתים, אתחול שירותים ובדיקה ששום דבר לא נפל — 6-8 שעות עבודה של מהנדסים. בגלל מחיר כזה ביצעו רוטציה פעם בשנה או פחות, ובעת עזיבת עובד הגישות פעמים רבות נותרו בתוקף. חלון הדליפה נמדד בשבועות, ואיש לא יכול היה לומר בוודאות כמה עותקים של המפתח חיים מחוץ למאגר.
מה שינינו
הסודות עברו למאגר מרכזי על HashiCorp Vault עם פרטי זיהוי דינמיים: היישום מקבל גישה קצרת-מועד בעת העלייה ואינו שומר אותה על הדיסק.
המדיניות הוגדרה לפי מחלקות — סיסמאות מסדי נתונים מוחלפות לפי לוח זמנים, תעודות מתעדכנות אוטומטית לפני פקיעת התוקף, ומפתחות של אינטגרציות חיצוניות מונפקים מחדש יחד עם השחרור.
מה התוצאה
- חלון הדליפה הצטמצם משבועות לדקות: ביטול גישה הוא פעולה אחת במקום סבב במאה צמתים.
- החלפת מפתח ידנית כתהליך נעלמה: ביותר מ-130 צמתים הרוטציה מתבצעת בלי מעורבות מהנדסים.
- מספר המקומות שבהם הסוד נמצא בטקסט גלוי צומצם לאפס — נותרו רק הפניות למאגר.
- עזיבת עובד מטופלת בביטול חשבון תוך דקות, בלי אתחול שירותים.
במה שונה החלפת מפתחות אוטומטית מהנפקה לפי דרישה
אלה אינם חלופות: החלפה מתוכננת וגישה לפי דרישה מכסות מחלקות סיכון שונות, ובתשתית חיה כמעט תמיד פועלים שני המצבים במקביל — מאגר סודות כמו HashiCorp Vault יודע לעשות גם את זה וגם את זה.
מצב החלפה מתוכנן הוא לוח זמנים: סיסמה למסד נתונים, מפתח חתימה, סוד שירות — מונפקים מחדש בתדירות נתונה, והיישומים לוקחים את הערך החדש מהמאגר בלי אתחול ובלי תיקון קונפיגורציה ידני.
המשמעות היא שהחלון שבו סוד שדלף נשאר פעיל מוגבל: המפתח הישן מבוטל מיד לאחר שכל הצרכנים אישרו את המעבר לחדש.
גישה לפי דרישה פותרת משימה אחרת — גישה זמנית למשימה מוגדרת. מהנדס צריך כניסה למסד הנתונים בפרודקשן למשך חקירת תקלה, ולקבלן — מפתח למערך הבדיקות לכמה שעות. כאן הסוד מונפק עם תוקף מוגבל ומבוטל אוטומטית, והארכה דורשת פעולה מפורשת עם הנמקה. הפרדת הסמכויות קובעת מי רשאי לבקש, מי מאשר ובאילו מערכות הדבר מותר.
ביקורת הפניות מתעדת למי, מתי ולכמה זמן ניתנה הגישה: זה מה שקוראים בחקירת תקלה, ולא רק בבדיקה מתוכננת.
הקריטריון המעשי פשוט: סודות שירות קבועים חיים לפי לוח זמנים, וגישה אנושית וחד-פעמית — לפי דרישה. אם מצמצמים הכול למצב אחד, מתקבלת או הנפקה ידנית של מפתחות ארוכי-טווח, או החלפה מתוכננת במקום שבו נדרשת גישה לשעה.
ספקות טכניים: חזרה לאחור, זמינות, תאימות
בפגישה טכנית הספקות נשמעים לפני האישור, וזה נורמלי. להלן ארבע שאלות שאנחנו סוגרים בפרויקט לפני הפעלת ההחלפה האוטומטית, כדי שהרוטציה לא תהפוך למקור לתקלות.
יש שירותים שאינם קוראים סודות מהמאגר
לצד שירות כזה מציבים סוכן נפרד: הוא מקבל את הסוד מהמאגר ומעביר אותו ליישום דרך קובץ, ולפי אות קורא אותו מחדש בלי לאתחל את התהליך. היישום עצמו לא משתנה — מתעדכן רק מקור הקריאה.
עבור מערכות שגם זאת אינן יודעות לעשות, הסוד מסופק בעת הוצאת השחרור, וההחלפה מסונכרנת עם חלון העדכון הקרוב.
כיצד החלפת מפתח משפיעה על הזמינות
הרוטציה מתבצעת בחפיפה של שני מפתחות: החדש מונפק ונבדק, והישן נשאר בתוקף עד שכל מופע מאשר עבודה עם החדש. המעבר בין הצמתים נעשה אחד-אחד, עם בדיקת כשירות אחרי כל שלב. אם צומת לא אישר את ההחלפה, התהליך נעצר והתעבורה אליו אינה מועברת — הזמינות למשתמשים אינה נפגעת.
המפתח החדש לא עבד — אפשר לחזור אחורה?
כן, והחזרה לאחור מובנית בנוהל מראש: הסוד הישן אינו מבוטל עד שכל הצרכנים יעבדו עם החדש לפחות מחזור אחד. גרסאות המפתחות וזמן הביטול נרשמים בלוג, והחזרה היא פעולה אחת. תוקף החירום של המפתח הישן מוגבל, ולכן ההקלה הזמנית אינה הופכת לקבועה.
אצלנו עובדים קבלנים חיצוניים
לקבלן מונפק מפתח אישי עם תוקף מוגבל ותחום הרשאות צר, ולא גישה כללית למערכת. הרוטציה מתבצעת בלי מעורבותו, ועם סיום העבודה המפתח מבוטל בפעולה נפרדת. כך הגישה של הקבלן אינה הופכת למקום שדרכו קשה אחר כך לסגור את הכניסה לתשתית.
נדון במשימה: אילו נתונים נדרשים להערכה
ההערכה ותוכנית היישום תלויות במידת הדיוק שבה אנחנו מבינים את המצב הנוכחי. להלן רשימת נתונים, שאחריהם נחזור לא עם שאלות הבהרה, אלא עם שלבי עבודה, סדר יישום והערכת מאמץ. אין צורך לשלוח את הערכים של המפתחות והסיסמאות עצמם — רק את המבנה והסכימה.
- רשימת שירותים וצרכני סודות: אילו יישומים, משימות רקע, צינורות בנייה ואינטגרציות חיצוניות קוראים מפתחות — ואילו סוגים בדיוק (סיסמאות מסדי נתונים, טוקני API, תעודות, מפתחות חתימה).
- סכימת סביבות: כיצד מופרדים פיתוח, בדיקות ופרודקשן, היכן נמצאים הנתונים, מהן ענפי הגישה וכיצד הסביבות מבודדות זו מזו.
- שיטת האחסון הנוכחית: קבצי קונפיגורציה, משתני סביבה, מנהל סודות או סקריפטים עצמאיים — די בתיאור ובדוגמה של המבנה.
- דרישות לתוקף המפתח: אילו תקופות החלפה מקובלות עבור אילו סוגים והאם קיימות מגבלות חיצוניות על תדירות ההנפקה מחדש.
- חלונות רוטציה ומידת הפגיעה המותרת: מתי אפשר לאתחל שירותים, כמה זמן אי-זמינות נסבל, והאם קיימים רכיבים עם שמירת מצב.
- תפקידים וגישה: מי הבעלים של הסודות, מי קורא אותם, כיצד מנוהל יומן הגישה, והאם נדרשת הנפקה לצוותים שונים עם הרשאות שונות.
- טיפול בתקלה וחזרה לאחור: מה קורה אם המפתח החדש לא נקלט, האם קיים נוהל חזרה ומי מקבל את ההחלטה.
- מגבלות: מה אסור לשנות, דרישות אבטחה ולוחות זמנים, תלויות בספקי שירות חיצוניים.
תארו את המשימה בהיקף הזה — נחזור עם הערכה, תוכנית יישום וסדר השלבים.







