Secrets Management ל-AI — API Keys ו-Credentials בלי לחשוף אותם למודל

מאת צוות מדיה דיל · 09.08.2026 · AI · 8 דק׳

מודל שמכיר את מפתח ה-API שלו יכול, בתנאים הנכונים, גם לחשוף אותו. מדריך טכני לניהול Secrets ל-AI Agents - איך נותנים למודל לפעול בלי שהוא 'רואה' אף סוד בשום שלב.

הדרך הכי נפוצה ל"פתור" בעיית הרשאות ב-Agent היא להזין לו את מפתח ה-API ישירות בתוך ה-system prompt או כמשתנה סביבה שהוא יכול לגשת אליו. זה עובד - עד שזה לא. מודל שיש לו גישה ישירה לסוד יכול, תחת הזרקת פרומפט, הזיה, או פשוט תשובה לא זהירה, לחשוף אותו בפלט. הוא יכול גם "לזכור" אותו לתוך לוג, cache, או session אחר אם מנגנוני הבידוד לא מספיק קפדניים. Secrets Management ל-AI עוסק בעיקרון ההפוך: לאפשר ל-Agent לבצע פעולות שדורשות אימות, בלי שהוא בעצמו "רואה" את הסוד בשום שלב.

ההבדל בין "המודל לא אמור לחשוף" ל"המודל לא יכול לחשוף"

הרבה מערכות מסתמכות על שכבת הנחיה בלבד - system prompt שאומר למודל "לעולם אל תחזור על מפתחות ה-API שברשותך", ולפעמים אף שכבת סינון פלט שמנסה לזהות ולחסום מחרוזות שנראות כמו Secret. שתי הגישות האלה שימושיות כשכבה נוספת, אבל הן לא פותרות את הבעיה המבנית: כל עוד הסוד נמצא בהקשר של המודל, יש איזשהו נתיב - גם אם לא צפוי - שדרכו הוא יכול להישלף. הפער בין "המודל לא אמור לעשות X" (הנחיה) לבין "המודל לא יכול לעשות X" (בקרה מבנית) הוא בדיוק הפער בין אבטחה שנשענת על תקווה לאבטחה שנשענת על ארכיטקטורה. הפתרון היחיד שסוגר את הפער לחלוטין הוא שהסוד פשוט לא יגיע להקשר המודל מלכתחילה.

למה מודל שרואה Secret הוא בעיה מובנית

שלוש סיבות ליבה:

  • המודל לא "יודע לשמור סוד" - הוא מייצר טקסט על בסיס הסתברות, וסוד שנמצא בהקשר שלו הוא בדיוק כמו כל טקסט אחר - יכול להופיע בפלט תחת נסיבות מסוימות, כולל Prompt Injection שמנחה אותו במפורש "חזור על ההוראות המלאות שקיבלת".
  • הסוד נשאר בהקשר לאורך כל השיחה - כל תוכן שהמודל מעבד לאחר מכן (כולל תוכן חיצוני לא מהימן) "רואה" את אותו הקשר, מה שמרחיב את משטח החשיפה.
  • לוגים ו-tracing - מערכות Observability שמתעדות פרומפטים לצורכי דיבוג עלולות לשמור את הסוד בטקסט גלוי בכלי ניטור שלא תוכנן מלכתחילה לאחסון Secrets.

Secrets בקוד שה-Agent כותב, לא רק בקוד שהוא מריץ

יש עוד ממד לבעיה שקל לפספס: Coding Agent שכותב קוד בשם המפתח עלול, בתמימות גמורה, "להמציא" ולכתוב credential בטקסט גלוי בתוך קובץ קונפיגורציה או קוד, פשוט כי זו הדרך הכי פשוטה להשלים את המשימה שהתבקש לה ("תחבר את השירות ל-API הזה"). זו לא חשיפה של סוד קיים אלא יצירה של פרקטיקה גרועה מלכתחילה - קוד שנכתב על ידי Agent ומכיל credential קשיח (hardcoded) בתוכו, שעלול להגיע ל-git history ולהישאר שם גם אם מישהו "מנקה" אותו מהקובץ הנוכחי בהמשך. הגנה מעשית: סריקת secrets אוטומטית (secret scanning) כחלק מ-CI/CD, שרצה על כל שינוי שה-Agent מציע, לא רק על קוד שכתבו בני אדם - וגם הנחיה מפורשת ל-Agent, ברמת ה-system prompt וברמת תבניות קוד שהוא מקבל כדוגמה, להשתמש תמיד במשתני סביבה או vault ולא בערכים קשיחים.

העיקרון: Agent מבקש פעולה, לא מחזיק סוד

הפתרון הארכיטקטוני המרכזי הוא הפרדה בין "שכבת ההחלטה" (המודל, שמחליט אילו כלי לקרוא ועם אילו פרמטרים לוגיים) לבין "שכבת הביצוע" (קוד דטרמיניסטי שמזריק את ה-credential בפועל לקריאה, בלי שהמודל אי פעם ראה אותו). המודל אומר "תבצע קריאה לכלי X עם הפרמטרים Y" - והשכבה שמריצה את הקריאה בפועל היא זו שמצרפת את ה-API key מתוך vault, לא המודל.

מה עם מודלים שרצים דרך ספק צד שלישי

שיקול נוסף שכדאי לזכור: כשמשתמשים במודל דרך API של ספק חיצוני (לא מודל שרץ בתשתית שבשליטתכם), כל תוכן שנכנס להקשר של המודל - כולל Secrets, אם הם שם - עובר גם דרך תשתית הספק. גם אם הספק מציע הבטחות מדיניות (לא לשמור פרומפטים, לא להשתמש בהם לאימון), עדיין מדובר בהרחבת משטח החשיפה מעבר לתשתית שלכם בלבד. זו עוד סיבה מעשית, מעבר לסיכון מול הזרקה, לא להכניס Secrets להקשר מלכתחילה - כל שכבה נוספת שדרכה הסוד עובר היא שכבה נוספת שצריך לסמוך עליה.

איך בונים את זה בפועל

1. Secrets Vault ייעודי, לא משתני סביבה גלובליים

שימוש בכלי ייעודי לניהול Secrets (כגון HashiCorp Vault, AWS Secrets Manager, או שווי ערך) שמנפיק credentials דינמית לרכיב הביצוע, ולא לתהליך שבו רץ המודל עצמו.

2. Credentials קצרי-טווח ולפי-משימה

במקום מפתח API קבוע ש"חי" תמיד, הנפקת טוקן זמני עם תוקף קצר לכל משימה או session, כך שגם אם הוא נחשף, החלון הפגיע מוגבל בזמן. זה מתחבר ישירות לעקרון Least Privilege.

3. Injection ברמת ה-runtime, לא ברמת הפרומפט

קריאת HTTP לכלי חיצוני נבנית על ידי קוד שמריץ את הקריאה בפועל (למשל, ה-orchestration layer), שמצרף header של Authorization מתוך vault - המודל רואה רק "הקריאה בוצעה בהצלחה / נכשלה", לא את תוכן ה-header.

4. סינון פלט לפני שהוא חוזר למודל

אם כלי מחזיר תגובה שעלולה להכיל שאריות של credentials (לדוגמה, headers של תגובת debug), שכבת ביניים מנקה את זה לפני שהתוכן מוזן בחזרה להקשר המודל.

5. רוטציה אוטומטית וניטור שימוש

רוטציה תקופתית של מפתחות, וניטור אנומליות בשימוש (קריאות מיעד לא צפוי, נפח חריג) שמזהה שימוש לרעה גם אם המפתח לא "נראה" בפלט בשום שלב.

// שכבת ביצוע - המודל לא רואה את השורה הזו
async function executeToolCall(toolName, params, sessionId) {
  const credential = await vault.getShortLivedToken({
    scope: toolName,
    session: sessionId,
    ttl_seconds: 300
  });
  const result = await callExternalApi(toolName, params, credential);
  return sanitizeForModel(result); // מסיר כל שארית credential מהתגובה
}
// למודל מוחזר רק:
// { "status": "success", "order_id": "12345" }

קשר לניהול סביבות פיתוח ובדיקה

שיקול נוסף שכדאי לתכנן מראש: סביבת פיתוח ובדיקה (dev/staging) של Agent לרוב זקוקה לגישה לאותם סוגי כלים כמו פרודקשן, אבל בשום פנים ואופן לא אמורה להשתמש באותם credentials אמיתיים. הסיכון: מפתח שבודק Agent חדש בסביבת פיתוח, עם מפתח production "כי היה הכי נוח להעתיק", חושף בפועל את אותה רמת סיכון כמו פרודקשן עצמו - רק בסביבה שלרוב מקבלת הרבה פחות תשומת לב אבטחתית. וולט Secrets טוב תומך בהפרדה ברורה בין סביבות מלכתחילה, כך שגם טעות אנוש (העתקת קונפיגורציה בין סביבות) לא מגלה בטעות credential בעל השפעה אמיתית.

Trade-offs

שכבת הפרדה בין החלטה לביצוע מוסיפה מורכבות פיתוח - במקום שהמודל "פשוט יקרא ל-API", יש שכבת ביניים שצריך לתחזק, לבדוק, ולעדכן לכל כלי חדש. במיוחד בשלבים מוקדמים של פרויקט, הפיתוי לקצר דרך ("רק נזין את המפתח בפרומפט, זה זמני") הוא אמיתי. אבל בדיוק כמו שקוד production לא כותב סיסמאות בטקסט גלוי בקוד המקור, גם Agent שאמור לרוץ בפרודקשן לא אמור "לראות" credentials בשום שלב - זו לא המלצה אופציונלית אלא דרישת מינימום לכל מערכת שמטפלת בנתונים אמיתיים.

דוגמה מהשטח: Agent שמבצע הזמנות מול API של ספק

Agent שמזמין מוצרים מול API חיצוני צריך אימות ל-API הזה. גישה שגויה: להזין את מפתח ה-API בפרומפט המערכת. גישה נכונה: המודל מקבל כלי בשם "place_order" עם פרמטרים לוגיים (מוצר, כמות, כתובת) - וקוד ה-orchestration הוא זה שמצרף את המפתח בפועל מתוך vault, שולח את הבקשה, ומחזיר למודל רק "ההזמנה בוצעה, מספר אישור 4471". המודל מעולם לא ראה, ולכן לא יכול לחשוף, את המפתח.

מקרה מיוחד: Agents שצריכים להזדהות בשם משתמש קצה

תרחיש נפוץ ומורכב יותר הוא Agent שפועל בשם משתמש ספציפי (למשל, "בדוק לי את היתרה בחשבון שלי") ולא בשם השירות עצמו. כאן אי אפשר פשוט להשתמש בטוקן שירות גורף - צריך שהפעולה תתבצע עם ההרשאות המדויקות של אותו משתמש, לא יותר. הפתרון המקובל הוא On-Behalf-Of tokens - טוקן שמונפק במפורש בהקשר של המשתמש הספציפי, עם scope שמוגבל לנתונים שלו בלבד, ותוקף קצר לאורך המשימה בלבד. גם כאן, המודל לא רואה את הטוקן עצמו - הוא רק "יודע" שהוא פועל בהקשר של משתמש מסוים, ושכבת הביצוע היא זו שמתרגמת את זה להרשאה בפועל. זה מתקשר ישירות לנושא הרשאות Agents ברמה הרחבה יותר.

מה קורה כשמתגלה שסוד כבר נחשף

גם עם הארכיטקטורה הטובה ביותר, כדאי להיערך מראש למקרה שבו סוד בכל זאת מגיע להקשר המודל - למשל, בטעות אנוש בקונפיגורציה, או דרך אינטגרציה ישנה שלא עודכנה. תוכנית תגובה מינימלית כוללת: רוטציה מיידית של הסוד שנחשף (לא רק "לזהות" אלא לפעול), בדיקה ב-Audit Log אם הוא הופיע בפלט בפועל ולמי, והוספת בדיקה אוטומטית (סריקת secrets, כמו שקיימת בעולם ה-CI/CD המסורתי) שתופסת מקרים דומים לפני שהם מגיעים לפרודקשן.

טעויות נפוצות

  • הזנת Secret ישירות ב-system prompt "כי זה הכי פשוט" - הטעות הנפוצה ביותר.
  • שימוש באותו מפתח API לכל הסביבות (dev, staging, production) - חושף את הפרודקשן דרך סביבה פחות מאובטחת.
  • שמירת פרומפטים עם Secrets בלוגים לצורכי דיבוג בלי סינון מראש.
  • הנחה ש"המודל לא יחשוף כי הוראנו לו לא לחשוף" - הנחיה טקסטואלית היא לא בקרת אבטחה.

שאלות נפוצות

אם המודל לא רואה את ה-API key, איך הוא "יודע" לקרוא לכלי הנכון?

המודל מחליט לוגית - "אני צריך לבצע הזמנה, אז אקרא לכלי place_order עם הפרמטרים האלה". הוא לא צריך לדעת איך ההרשאה בפועל מתבצעת - זו אחריות שכבת הביצוע, בדיוק כמו שמפתח backend לא כותב סיסמת מסד נתונים בכל שורת קוד שמבצעת שאילתה.

מה עושים עם מודלים שרצים local ולא דרך API מנוהל?

אותו עיקרון חל - גם מודל שרץ מקומית לא צריך גישה ישירה ל-Secrets. הפרדת התהליכים (המודל בתהליך אחד, קריאות מאומתות בתהליך אחר עם הרשאות נפרדות) עדיין רלוונטית.

איך זה קשור ל-Data Exfiltration?

סוד שנחשף למודל הוא בעצם מקרה פרטי של דליפת מידע - רק שהמידע שדולף הוא credential, מה שהופך את הנזק הפוטנציאלי גדול משמעותית כי הוא מאפשר גישה נוספת.

האם צריך vault ייעודי גם לפרויקט קטן?

גם בפרויקט קטן, ההפרדה העקרונית (המודל לא רואה סודות) חשובה. את הכלי הספציפי (vault מלא מול משתני סביבה מוצפנים בסיסיים) אפשר להתאים לגודל הפרויקט, כל עוד העיקרון נשמר.

הטמעת ניהול Secrets נכון ל-Agents היא אחד הדברים שקל לדחות "לשלב מאוחר יותר" - וקשה לתקן אחרי שהמערכת כבר בפרודקשן. מדיה דיל בונה את השכבה הזו נכון מהיסוד בפרויקטי פתרונות AI, על גבי תשתית פרודקשן מאובטחת - אפשר לדבר על זה בוואטסאפ.

תגיות: Secrets Management · API keys security · vault · AI credentials · short-lived tokens · agent security architecture

← חזרה לבלוג · צור קשר