אבטחת סוכני AI באמצעות כלי MCP ב-Laravel

מתן גישה לסוכן AI לאפליקציה שלך באמצעות MCP הוא כמו למסור למישהו צרור מפתחות. אם לא תגדירו כללים, הם עלולים לפתוח את הדלתות הלא נכונות.

לאחרונה בניתי כלי MCP עבור אפליקציית Laravel מרובת-דיירים (multi-tenant). הייתה לי מטרה אחת: לאפשר לסוכן להפעיל את האפליקציה מבלי לאפשר לו לראות נתונים של מישהו אחר.

הבעיה עם כלי MCP

כל כלי MCP הוא endpoint. סוכן קורא לכלי, והשרת שלכם מריץ קוד. באפליקציה מרובת-דיירים, כל כלי חייב לענות על שתי שאלות:

  • האם מותר לך לעשות זאת?
  • האם מותר לך לעשות זאת בארגון הספציפי הזה?

אם תפספסו אחת מהן, תדליפו נתונים.

מדוע מודל multi-tenancy סטנדרטי נכשל כאן

באפליקציית אינטרנט רגילה, יש לכם sessions. אתם משתמשים ב-global scopes כדי לסנן נתונים לפי מזהה ארגון (organization ID). זה עובד כי ה-"ארגון הנוכחי" תמיד נמצא ב-session.

כלי MCP אינם משתמשים ב-sessions. הם משתמשים ב-tokens. אין middleware שקובע את הקשר (context) של הדייר. אם תסתמכו על global scope שמחפש session, הוא לא ימצא כלום. כתוצאה מכך, הוא עלול להחזיר כל שורה במסד הנתונים שלכם. זוהי דליפת נתונים שקטה.

הפתרון: סינון מפורש (Explicit Filtering)

לעולם אל תסתמכו על ambient scope עם אימות באמצעות token. סננו באופן מפורש בכל פעם.

יצרתי trait אחד כדי לטפל בזה:

trait ResolvesOrgEvents
{
    protected function resolveOrgEvent(Authenticatable $user, string $uuid): ?Event
    {
        if (empty($user->organization_id)) {
            return null;
        }

        return Event::query()
            ->withOrganization($user->organization_id)
            ->where('uuid', $uuid)
            ->first();
    }
}

הגישה הזו עוקבת אחר ארבעה כללים:

  • השתמשו ב-UUIDs: לעולם אל תשתמשו ב-IDs מסוג auto-increment. סוכנים לא אמורים להיות מסוגלים לנחש מזהים על ידי שינוי מספר.
  • מקור אמת יחיד (Single Source of Truth): המסנן של הארגון נמצא ב-trait אחד. כל כלי משתמש בו.
  • שימוש חוזר בהרשאות: אל תמציאו הרשאות חדשות עבור סוכנים. השתמשו באותן מחרוזות הרשאות (permission strings) שהאפליקציה שלכם משתמשת בהן. זה מונע מהסוכן לקבל יותר כוח ממשתמש אנושי.
  • סימון Side Effects: השתמשו ב-annotations כדי לציין אם כלי הוא לקריאה בלבד (read-only) או מאפשר כתיבה (write-enabled).

בדיקת הגבולות

עליכם לבדוק את הנתיב השלילי (negative path). אל תבדקו רק אם הכלי עובד. בדקו שמשתמש מארגון א' לא יכול לראות נתונים מארגון ב'.

אם סוכן מנסה לגשת ל-UUID של דייר אחר, הכלי צריך להחזיר "not found". הוא לא צריך להגיד לסוכן שהנתונים קיימים אך שייכים למישהו אחר.

התייחסו לכל כלי AI כאל endpoint לא מהימן. משמעת היא הדרך היחידה לשמור על הנתונים שלכם בטוחים.

מקור: https://dev.to/nasrulhazim/giving-an-ai-agent-the-keys-without-giving-it-the-building-rbac-org-scoped-mcp-tools-in-laravel-43oi