Laravel MCP Tools দিয়ে AI Agents-কে সুরক্ষিত করা
MCP-এর মাধ্যমে আপনার অ্যাপে একটি AI agent-কে অ্যাক্সেস দেওয়া মানে হলো কাউকে একটি চাবির রিং (keyring) দিয়ে দেওয়া। আপনি যদি নিয়ম নির্ধারণ না করেন, তবে তারা ভুল দরজা খুলে ফেলতে পারে।
আমি সম্প্রতি একটি multi-tenant Laravel অ্যাপের জন্য MCP tools তৈরি করেছি। আমার একটিই লক্ষ্য ছিল: এজেন্ট যেন অ্যাপটি পরিচালনা করতে পারে, কিন্তু অন্য কারো ডেটা দেখতে না পারে।
MCP Tools-এর সমস্যা
প্রতিটি MCP tool হলো একটি endpoint। একটি agent একটি tool কল করে এবং আপনার সার্ভার কোড রান করে। একটি multi-tenant অ্যাপে, প্রতিটি tool-কে দুটি প্রশ্নের উত্তর দিতে হবে:
- আপনি কি এটি করার অনুমতিপ্রাপ্ত?
- আপনি কি এই নির্দিষ্ট অর্গানাইজেশনে এটি করার অনুমতিপ্রাপ্ত?
আপনি যদি একটিও মিস করেন, তবে ডেটা লিক (leak) হতে পারে।
কেন সাধারণ Multi-Tenancy এখানে ব্যর্থ হয়
একটি সাধারণ ওয়েব অ্যাপে আপনার সেশন (session) থাকে। আপনি organization ID অনুযায়ী ডেটা ফিল্টার করতে global scopes ব্যবহার করেন। এটি কাজ করে কারণ "current organization" সবসময় সেশনে থাকে।
MCP tools সেশন ব্যবহার করে না। এগুলো টোকেন (token) ব্যবহার করে। টেন্যান্ট কনটেক্সট (tenant context) সেট করার জন্য কোনো middleware নেই। আপনি যদি এমন কোনো global scope-এর ওপর নির্ভর করেন যা সেশন খোঁজে, তবে সেটি কিছুই খুঁজে পাবে না। এর ফলে এটি আপনার ডাটাবেসের প্রতিটি রো (row) রিটার্ন করে দিতে পারে। এটি একটি নিঃশব্দ ডেটা লিক (silent data leak)।
সমাধান: Explicit Filtering
টোকেন অথেন্টিকেশনের (token authentication) ক্ষেত্রে কখনোই ambient scope-এর ওপর নির্ভর করবেন না। প্রতিবার সুনির্দিষ্টভাবে (explicitly) ফিল্টার করুন।
আমি এটি হ্যান্ডেল করার জন্য একটি মাত্র 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();
}
}
এই পদ্ধতিটি চারটি নিয়ম অনুসরণ করে:
- UUID ব্যবহার করুন: কখনোই auto-increment ID ব্যবহার করবেন না। এজেন্ট যেন কেবল একটি সংখ্যা পরিবর্তন করে ID অনুমান করতে না পারে।
- Single Source of Truth: অর্গানাইজেশন ফিল্টারটি একটি মাত্র trait-এ থাকবে। প্রতিটি tool এটি ব্যবহার করবে।
- Permissions পুনরায় ব্যবহার করুন: এজেন্টদের জন্য নতুন permission তৈরি করবেন না। আপনার ওয়েব অ্যাপে যে permission string ব্যবহার করেন, সেটিই ব্যবহার করুন। এটি এজেন্টকে একজন সাধারণ ব্যবহারকারীর চেয়ে বেশি ক্ষমতা দেওয়া থেকে বিরত রাখে।
- Side Effects চিহ্নিত করুন: একটি tool শুধুমাত্র পড়ার জন্য (read-only) নাকি লেখার জন্য (write-enabled) তা বোঝাতে annotations ব্যবহার করুন।
সীমানা পরীক্ষা করা (Testing the Boundary)
আপনাকে নেগেটিভ পাথ (negative path) অবশ্যই পরীক্ষা করতে হবে। টুলটি কাজ করছে কি না তা পরীক্ষা করলেই হবে না। পরীক্ষা করে দেখুন যে Organization A-এর একজন ব্যবহারকারী Organization B-এর ডেটা দেখতে পাচ্ছে না কি না।
যদি কোনো এজেন্ট অন্য কোনো টেন্যান্টের UUID অ্যাক্সেস করার চেষ্টা করে, তবে টুলটির "not found" রিটার্ন করা উচিত। এটি এজেন্টকে এটা বলা উচিত নয় যে ডেটাটি বিদ্যমান কিন্তু সেটি অন্য কারো।
প্রতিটি AI tool-কে একটি untrusted endpoint হিসেবে বিবেচনা করুন। আপনার ডেটা সুরক্ষিত রাখার একমাত্র উপায় হলো শৃঙ্খলা।
