acme टेनेंट के लिए एक सपोर्ट चैटबॉट को रिफंड के लिए एक टिकट मिलता है। कॉलर सिर्फ़ चैट टेक्स्ट भेजता है, फिर भी assist-api मॉडल को payments.refund अनुरोध बनाने देता है और सर्विस के व्यापक पेमेंट क्रेडेंशियल्स का इस्तेमाल करके उस अनुरोध को भेजता है। बैकएंड एक रिफंड प्रस्ताव जारी करता है जिसे बनाने का अधिकार u_123 के पास कभी नहीं था। इसके लिए किसी खास चीज़ की ज़रूरत नहीं थी। कॉलर के मैसेज से अनट्रस्टेड टेक्स्ट एक एक्शन में बदल गया, जबकि मॉडल के पास यह तय करने का अधिकार नहीं था कि वह एक्शन करने की इजाज़त है या नहीं।
गार्डरेल एक ऐसा कंट्रोल पॉइंट है जो यह तय करता है कि LLM एप्लीकेशन क्या स्वीकार करता है, खर्च करता है, लौटाता है या चलाता है। इस गड़बड़ी में, सबसे आसान और उपयोगी गार्डरेल रिफंड अनुरोध को तब तक अस्वीकार कर देता है जब तक कि ऑथेंटिकेटेड प्रिंसिपल के पास ज़रूरी स्कोप न हो और सर्वर-साइड अप्रूवल गेट असली रिफंड पैरामीटर्स को स्वीकार न कर ले। प्रॉम्प्ट की शब्दावली वह सुरक्षा नहीं दे सकती क्योंकि मॉडल उस टेक्स्ट का पालन करता है जो उस तक पहुँचता है; यह कॉलर को ऑथेंटिकेट नहीं करता, बजट नहीं रखता, या टूल्स को ऑथराइज़ नहीं करता है।
चल रहे सिस्टम में एक रास्ता है जिसे हम वैसा ही रखेंगे। एंड यूज़र u_123 टेनेंट acme से जुड़ा है और llm-gateway के ज़रिए assist-api को कॉल करता है। FastAPI सर्विस एक प्रॉम्प्ट तैयार करती है, $CHAT_MODEL का इस्तेमाल करके chat रूट पर प्रोवाइडर providerA को कॉल करती है, और टूल एक्शन का अनुरोध कर सकती है। u_123 के पास chat:invoke और payments:refund:propose का अधिकार है, न कि बिना किसी रोक-टोक के पेमेंट करने का अधिकार।
पेमेंट कॉन्ट्रैक्ट सीमित और स्पष्ट रहता है। एकमात्र पेमेंट टूल payments.refund है, जिसमें invoice_id जैसे inv_987, amount_cents जैसे इंटीजर 1299, और reason जैसे स्ट्रिंग शामिल हैं। प्रस्तावित रिफंड का मतलब रिफंड करने की अनुमति नहीं है। सर्वर किसी भी ऐसे पेमेंट एक्शन को चलाने से पहले टेनेंट ओनरशिप, स्कोप, आर्ग्युमेंट्स और अप्रूवल की जाँच करता है जिसे बदला नहीं जा सकता।
टेक्स्ट वाली हर सीमा अनट्रस्टेड होती है, जिसमें कॉलर का मैसेज, रिट्रीव किए गए डॉक्यूमेंट्स, टूल के नतीजे और मॉडल का आउटपुट शामिल हैं। रिट्रीव किए गए सपोर्ट डॉक्यूमेंट में ऐसे निर्देश हो सकते हैं जो एप्लीकेशन की पॉलिसी के खिलाफ़ हों, और मॉडल के आउटपुट में ऐसे फ़ील्ड हो सकते हैं जो बिना वैलिडेशन के पेमेंट API को भेजे जाने पर असुरक्षित हो सकते हैं। यह OWASP GenAI सिक्योरिटी प्रोजेक्ट द्वारा नवंबर 2024 में पब्लिश किए गए LLM एप्लीकेशन 2025 के लिए OWASP Top 10 में LLM01 प्रॉम्प्ट इंजेक्शन है। नियम पक्का है: कोई भी टूल कॉल उस अधिकार से ज़्यादा अधिकार के साथ नहीं चल सकता जो u_123 ने उसे दिया है।
फिक्स्ड पाथ (fixed path) अनट्रस्टेड इनपुट और एनफोर्समेंट बाउंड्रीज़ को एक ही व्यू में रखता है।
गेटवे यह तय करता है कि किसने कॉल किया, जबकि assist-api यूज़र के टेनेंट, स्कोप, टूल कॉन्ट्रैक्ट और मंज़ूरी की ज़रूरतों को लागू करता है। प्रोवाइडर providerA अपने खुद के प्रोवाइडर क्रेडेंशियल का इस्तेमाल करके आउटपुट बनाता है, लेकिन उस क्रेडेंशियल से u_123 की ओर से रिफंड करने का अधिकार नहीं मिलना चाहिए। ऐसे यूज़र के लिए सर्विस की ज़्यादा परमिशन का इस्तेमाल करना, जिनके पास वे परमिशन नहीं हैं, ‘कन्फ्यूज़्ड डेप्युटी’ (भ्रमित प्रतिनिधि) वाली स्थिति पैदा करता है।
बाउंड्री नियम
मॉडल
payments.refundका सुझाव दे सकता है; इसे सिर्फ़ सर्वर-साइड चेक ही मंज़ूरी दे सकते हैं या लागू कर सकते हैं।
क्योंकि हर बाउंड्री का काम अलग होता है, इसलिए मना करने पर उस स्टेज की पहचान होनी चाहिए जो सुरक्षित रूप से आगे नहीं बढ़ सकी। llm-gateway गायब, अमान्य, रद्द या कॉम्प्रोमाइज़्ड (सुरक्षा से समझौता किए गए) क्रेडेंशियल के लिए 401 Unauthorized रिस्पॉन्स देता है। ऑथेंटिकेशन के बाद, जब कॉलर के पास ज़रूरी स्कोप नहीं होता है, तो गेटवे या एप्लीकेशन 403 Forbidden रिस्पॉन्स देता है। टूल फ़ेच के लिए ब्लॉक किए गए डेस्टिनेशन के मामले में भी 403 Forbidden रिस्पॉन्स मिलता है, और ब्लॉक किए गए डेस्टिनेशन से कभी संपर्क नहीं किया जाता है।
providerA के जवाब देने के बाद, assist-api मॉडल आउटपुट को पार्सर, पेमेंट API या किसी अन्य डाउनस्ट्रीम सिंक द्वारा प्राप्त किए जाने से पहले वैलिडेट करता है। स्कीमा-अमान्य आउटपुट 422 Unprocessable Content रिस्पॉन्स देता है, जो RFC 9110 का फ़्रेज़ है जिसे पुराने डॉक्यूमेंटेशन में Unprocessable Entity कहा जाता है। अलग-अलग रिफंड पैरामीटर के साथ आइडेंपोटेंसी की (idempotency key) का दोबारा इस्तेमाल करने पर भी 422 Unprocessable Content रिस्पॉन्स मिलता है; पहली रिक्वेस्ट के एक्टिव रहने के दौरान उसी की का दोबारा इस्तेमाल करने पर 409 Conflict रिस्पॉन्स मिलता है।
बाकी नतीजे मॉडल के फ़ैसले के बजाय ऑपरेशनल बाउंड्री के बारे में बताते हैं।
202 Accepted तब मिलता है जब किसी ऐसे रिफंड को मंज़ूरी के लिए रोका जाता है जिसे बदला नहीं जा सकता, साथ ही पेंडिंग-अप्रूवल आइडेंटिफ़ायर भी मिलता है।429 Too Many Requests (साथ में Retry-After) तब मिलता है जब शेयर्ड कोटा या रेट लिमिट खत्म हो जाती है।503 Service Unavailable तब मिलता है जब एनफोर्समेंट स्टोर उपलब्ध नहीं होता और एप्लीकेशन सुरक्षित रूप से पॉलिसी लागू नहीं कर पाती।504 Gateway Timeout तब मिलता है जब providerA प्रोवाइडर-कॉल टाइमआउट से ज़्यादा समय लेता है।ये नतीजे क्लाइंट को मनाही को अस्पष्ट मॉडल विफलता मानने से रोकते हैं। वे यह भी बताते हैं कि कहाँ जाँच करनी है, चाहे गायब कंट्रोल llm-gateway पर पहचान हो, assist-api में वैलिडेशन हो, या कोई प्रोवाइडर कॉल हो जो पूरी नहीं हुई।
शुरुआती विफलता में, अटैकर के पास सिर्फ़ एक चैट मैसेज होता है, लेकिन वह रिफंड का ऐसा प्रस्ताव बनवा देता है जिसे बदला नहीं जा सकता। किस स्टेज पर सबसे पहले मना किया जाना चाहिए: A, llm-gateway पर कॉलर ऑथेंटिकेशन और टेनेंट बाइंडिंग; B, assist-api पर टूल ऑथराइजेशन और अप्रूवल; या C, मॉडल के बाद आउटपुट की जाँच?