FastAPI सपोर्ट कोपायलट का बैकएंड आमतौर पर सामान्य तरीके से फेल होता है। बैकएंड acct_987 के लिए अकाउंट हिस्ट्री पढ़ता है, एक मॉडल अगले कदमों का सुझाव देता है, और एक टूल कॉल txn_456 के लिए रिफंड जारी करता है क्योंकि सपोर्ट टिकट का टेक्स्ट भरोसेमंद लग रहा था। कुछ भी असामान्य नहीं हुआ। एप्लिकेशन ने टिकट से अनट्रस्टेड (भरोसे के लायक नहीं) टेक्स्ट स्वीकार किया, सुझाव को ऑथराइज़ेशन माना, और एंड-यूज़र के अधिकारों और अप्रूवल गेट को लागू करने के बजाय सर्विस के प्रिविलेज के साथ refund.create को चलाया।
इस कोर्स में सिक्योरिटी का काम उन जगहों पर ज़रूरी एनफोर्समेंट स्टेज बनाना है जहाँ उन्हें लागू किया जा सकता है। प्रॉम्प्ट की शब्दावली टूल राउटर को रिक्वेस्ट भेजने से नहीं रोक सकती, और मॉडल यह साबित नहीं कर सकता कि u_123 को txn_456 को रिफंड करने की अनुमति है। बैकएंड या तो टूल चलने से पहले रिक्वेस्ट को रिजेक्ट कर देता है, या बैकएंड टूल चलाता है और असली पैसे खर्च करता है।
हम हर लेसन के लिए एक ठोस एंकर रखते हैं ताकि हर कंट्रोल उन्हीं मूविंग पार्ट्स पर लागू हो। टेनेंट t_acme है, एंड-यूज़र u_123 है, अकाउंट acct_987 है, और रिफंड के लिए ट्रांज़ैक्शन कैंडिडेट txn_456 है। एकमात्र रिफंड टूल का नाम refund.create है, और उस तक पहुँचने वाला एकमात्र रूट POST /v1/tools/refund.create है।
हम उस एकमात्र स्कोप नाम को भी तय करते हैं जो रिफंड की अनुमति देता है। जिस प्रिंसिपल के पास support:refund नहीं है, वह पॉलिसी के बारे में चैट कर सकता है, अकाउंट हिस्ट्री का सारांश बना सकता है, और जवाब का ड्राफ्ट तैयार कर सकता है, लेकिन प्रिंसिपल को refund.create नहीं चलाना चाहिए। मॉडल का चुनाव स्पष्ट लेकिन एब्स्ट्रैक्ट रहता है। एप्लिकेशन $CHAT_MODEL के ज़रिए चैट मॉडल को कॉल करता है और $MODERATION_MODEL का इस्तेमाल करता है जहाँ बाद के लेसन में एक डेडिकेटेड स्क्रीनिंग कॉल की ज़रूरत होती है।
एक बार नाम तय हो जाने के बाद, हम एक सिंगल रिक्वेस्ट पाथ को मैप कर सकते हैं और यह मार्क कर सकते हैं कि अनट्रस्टेड डेटा कहाँ से आता है। कॉलर का मैसेज तब भी अनट्रस्टेड होता है जब वह किसी ऑथेंटिकेटेड सपोर्ट एजेंट से आया हो, क्योंकि मैसेज में कस्टमर का कॉपी किया हुआ टेक्स्ट या टिकट का कंटेंट हो सकता है। रिट्रीव की गई अकाउंट हिस्ट्री के हिस्से अनट्रस्टेड होते हैं क्योंकि रिट्रीवल में स्टोर में मौजूद हर चीज़ मिलती है, जिसमें पुराने नोट्स और फ्री टेक्स्ट भी शामिल हैं जो मॉडल को प्रभावित करने की कोशिश कर सकते हैं। टूल के नतीजे अनट्रस्टेड होते हैं क्योंकि डाउनस्ट्रीम सिस्टम अनएक्सपेक्टेड स्ट्रिंग्स या फील्ड्स लौटा सकते हैं, और मॉडल का आउटपुट अनट्रस्टेड होता है क्योंकि मॉडल पॉलिसी के पालन के बजाय भरोसेमंद लगने वाले टेक्स्ट के लिए ऑप्टिमाइज़ करता है।
यह सिस्टम ऐसे एनफोर्समेंट पॉइंट बनाता है जो उन अनट्रस्टेड इनपुट को एक सीमित और ऑडिट किए जा सकने वाले एक्शन में बदल सकते हैं। हम प्रिंसिपल को ऑथेंटिकेट और बाइंड करते हैं ताकि हर रिक्वेस्ट में t_acme और u_123 सर्वर द्वारा वेरिफाइड फैक्ट्स के तौर पर हों, न कि कॉलर द्वारा दिए गए हेडर के तौर पर। हम प्रोवाइडर कॉल से पहले कोटा को मीटर करते हैं ताकि कोई एक एंडपॉइंट एक महीने के टोकन रातों-रात खर्च न कर सके। हम कॉल साइट पर रिट्रीवल को ऑथराइज़ करते हैं ताकि बैकएंड सिर्फ़ वही चंक रिट्रीव करे जिन्हें देखने का अधिकार u_123 के पास है, और हम हर रिट्रीव किए गए चंक को अनट्रस्टेड कंटेंट ही मानते हैं। हम किसी भी राउटर, पार्सर, टेम्प्लेट या टूल द्वारा देखे जाने से पहले स्ट्रक्चर्ड मॉडल आउटपुट को वैलिडेट करते हैं। हम टूल कॉल्स को ऑथराइज़ और अप्रूव करते हैं ताकि refund.create सिर्फ़ इसलिए न चल सके कि मॉडल ने कोई आकर्षक सुझाव दिया है। हम एनालिसिस स्क्रिप्ट्स को सैंडबॉक्स करते हैं ताकि जेनरेट किया गया कोड नेटवर्क या सीक्रेट्स तक न पहुँच सके। हम हर इनकार और हर किए गए एक्शन का ऑडिट करते हैं, जिसमें यह बताने के लिए पर्याप्त फील्ड्स होते हैं कि किसने क्या किया, किस टेनेंट के लिए किया, और बैकएंड ने इसकी अनुमति क्यों दी।
जब सपोर्ट टिकट टेक्स्ट रिफंड ट्रिगर करने की कोशिश करता है, तो किसी भी टूल के चलने से पहले कौन सा स्टेज रिफंड को मना कर सकता था?
एक सही फ़ेलियर मैप (failure map) से यह साफ़ हो जाता है कि ज़िम्मेदारी किसकी है। मॉडल ने टेक्स्ट बनाया, लेकिन बैकएंड ने तय किया कि POST /v1/tools/refund.create चलेगा या नहीं; बैकएंड पर ही हम प्रिंसिपल (यूज़र/सिस्टम) का दायरा तय कर सकते हैं, ऐसे कामों के लिए मंज़ूरी ले सकते हैं जिन्हें बदला नहीं जा सकता, और एक ‘आइडम्पोटेंसी की’ (idempotency key) जोड़ सकते हैं ताकि दोबारा कोशिश करने पर पैसे दो बार खर्च न हों। एक बार जब हम यह सीमा लागू कर देते हैं, तो प्रॉम्प्ट इंजेक्शन की कोशिशें ऐसे इनपुट बन जाती हैं जो वैलिडेशन और ऑथराइज़ेशन में फ़ेल हो जाते हैं, न कि ऐसे निर्देश जो पैसे के लेन-देन में बदल जाएं।
हम मानकर चलते हैं कि आपको HTTP स्टेटस कोड की अच्छी समझ है, यानी आप जानते हैं कि नेटवर्क पर रिफ़्यूज़ल रिस्पॉन्स (अस्वीकृति का जवाब) का क्या मतलब होता है।
हम JWT की बुनियादी जानकारी मानकर चलते हैं, यानी हम किसी भरोसेमंद लाइब्रेरी का इस्तेमाल करके सिग्नेचर वेरिफ़ाई कर सकते हैं और जारीकर्ता (issuer), ऑडियंस और एक्सपायरी की जाँच कर सकते हैं।
हम FastAPI डिपेंडेंसी इंजेक्शन की जानकारी मानकर चलते हैं, यानी हम ऑथेंटिकेशन, ऑथराइज़ेशन और कोटा चेक को अलग-अलग हैंडलर में बिखेरने के बजाय ‘रिक्वेस्ट-स्कोप वाली डिपेंडेंसी’ के तौर पर जोड़ सकते हैं।
इस कोर्स में हम जो चीज़ बना रहे हैं, वह एक रेफ़रेंस बैकएंड पाइपलाइन है जिसमें हर स्टेज पर अस्वीकृति का एक साफ़ पॉइंट होता है, हर लॉग रिकॉर्ड में ऐसे स्थिर फ़ील्ड होते हैं जिनके बारे में रिव्यूअर समझ सकते हैं, और हर रिग्रेशन केस एक कंट्रोल से जुड़ा होता है। मकसद कोई चालाक प्रॉम्प्ट बनाना नहीं है। मकसद एक ऐसा बैकएंड बनाना है जो अकाउंट हिस्ट्री पर सुरक्षित रूप से RAG (Retrieval-Augmented Generation) कर सके, refund.create को तभी कॉल करे जब u_123 इसके लिए अधिकृत और मंज़ूर हो, और नेटवर्क या सीक्रेट एक्सेस दिए बिना एनालिसिस स्क्रिप्ट चला सके। नीचे दिया गया डायग्राम उस रिक्वेस्ट पाथ को तय करता है जिसे हम हर स्टेज पर मज़बूत (harden) करेंगे।