Git में सीक्रेट्स: फ़ाइल को डिलीट करने से समस्या क्यों नहीं सुलझती

Git में सीक्रेट्स: फ़ाइल को डिलीट करने से समस्या क्यों नहीं सुलझती

कॉन्फ़िग फ़ाइल के बारे में एक सामान्य सा सवाल दिन की सबसे गंभीर खोज में बदल गया

इस हफ़्ते किसी ने मुझसे एक उबाऊ सवाल पूछा: "वो प्रोडक्शन कॉन्फ़िग फ़ाइल कहाँ है?" बीस मिनट बाद मैं Git रिपॉजिटरी में मौजूद एक लाइव क्लाउड एक्सेस की (key) देख रहा था, जिसे टीम का हर सदस्य और हर वो व्यक्ति पढ़ सकता था जिसने कभी उसे क्लोन किया हो।

आज 29 सितंबर, 2026 है, और यह एक बहुत ही वर्तमान कारण से लगातार हो रहा है। टीमें मौजूदा प्रोडक्ट्स में AI फीचर्स को जोड़ने के लिए तेज़ी से आगे बढ़ रही हैं, और हर नए इंटीग्रेशन के साथ एक और की (key) आती है: एक मॉडल API की, एक क्लाउड सर्विस अकाउंट, एक स्टोरेज क्रेडेंशियल। उन कीज़ को कहीं न कहीं रहना होता है, और सबसे आसान रास्ता एप्लिकेशन की कॉन्फ़िग फ़ाइल है। अगर वह फ़ाइल पहले से ही Git में ट्रैक की जा रही है, तो किसी के कमिट करते ही वो सीक्रेट पब्लिश हो जाता है।

इस पोस्ट का मकसद यह कहना नहीं है कि "सीक्रेट्स कमिट न करें।" यह सब जानते हैं। इसका मकसद यह है कि जब आपको कोई सीक्रेट मिले तो क्या करना चाहिए, क्योंकि जो पहली बात दिमाग में आती है वह गलत होती है।

इसकी शुरुआत एक उबाऊ सवाल से हुई

मैं एक .NET एप्लिकेशन देख रहा था। जिस कॉन्फ़िग फ़ाइल की बात हो रही थी वो थी appsettings.Production.json, जो कि एक .NET ऐप की अपनी प्रोडक्शन सेटिंग्स रखने की मानक जगह है। सवाल बस यह था कि कौन सी कॉपी प्रामाणिक (authoritative) थी, क्योंकि फ़ाइल एक साथ तीन अलग-अलग जगहों पर मौजूद होती है:

  • रिपॉजिटरी में, सोर्स ट्री के अंदर
  • डिप्लॉय किए गए पाथ पर, रन हो रहे कंटेनर के अंदर
  • डिप्लॉय के समय बिल्ड पाइपलाइन द्वारा रीराइट की गई, जो डेटाबेस कनेक्शन स्ट्रिंग को इंजेक्ट करती है

वह तीसरी वाली महत्वपूर्ण है। क्योंकि पाइपलाइन ओवरराइट करती है कुछ वैल्यूज़ डिप्लॉय के समय, तो यह मान लेना आसान है कि यह ओवरराइट करती है सभी को ऐसा नहीं है। जो कुछ भी पाइपलाइन इंजेक्ट नहीं करती है, उसका उपयोग बिल्कुल वैसे ही किया जाता है जैसे उसे कमिट किया गया था।

जाँच करने वाली पहली बात यह है कि क्या फ़ाइल ट्रैक की जा रही है

यह एक लाइन की जाँच है और किसी भी ऐसी कॉन्फ़िग फ़ाइल पर चलाना सही रहेगा जिसके बारे में आप अनिश्चित हैं:

git ls-files --error-unmatch path/to/appsettings.Production.json

अगर वह कमांड सफल होती है, तो फ़ाइल ट्रैक की जा रही है, जिसका अर्थ है कि यह रिपॉजिटरी और उसकी हिस्ट्री में है। मेरे मामले में यह सफल रहा, और .gitignore में कॉन्फ़िग फ़ाइलों के लिए कोई नियम ही नहीं था।

अंदर लगभग एक दर्जन सीक्रेट्स थे: एक डेटाबेस कनेक्शन स्ट्रिंग, कई पासवर्ड, वेब पुश नोटिफ़िकेशन कीज़, एक AI मॉडल API की (key), और एक क्लाउड एक्सेस की (key) पेयर।

"हम बस इसे डिलीट कर देंगे" वाला तरीका काम क्यों नहीं करता

यहाँ वह बात है जो लोगों को हैरान करती है। किसी फ़ाइल से सीक्रेट को हटाने और उस बदलाव को कमिट करने से वह सीक्रेट नहीं हटता।

Git केवल वर्तमान स्थिति ही नहीं, बल्कि हिस्ट्री भी स्टोर करता है। पुराना कमिट अब भी मौजूद रहता है। कोई भी यह रन कर सकता है:

git log --oneline -- path/to/appsettings.Production.json
git show <old-commit>:path/to/appsettings.Production.json

और असली वैल्यूज़ पढ़ सकता है। रिपॉजिटरी का हर क्लोन उस पूरी हिस्ट्री को साथ रखता है। इसलिए जिस डेवलपर ने पिछले साल प्रोजेक्ट को क्लोन किया था, उसके लैपटॉप पर आज भी वह सीक्रेट मौजूद है, भले ही आप उसे "रिमूव" कर दें।

आप इसके लिए बने टूल्स की मदद से हिस्ट्री को रीराइट कर सकते हैं, लेकिन इसके लिए फ़ोर्स पुश की आवश्यकता होती है, यह हर मौजूदा क्लोन को ब्रेक कर देता है, और सबसे महत्वपूर्ण बात, यह उन कॉपीज़ का कुछ नहीं करता जो लोगों के पास पहले से मौजूद हैं। हिस्ट्री रीराइट करना बस सफाई है। यह कोई समाधान नहीं है।

एकमात्र कार्रवाई जो वास्तव में एक्सपोज़र को खत्म करती है, वह खुद सीक्रेट को बदलना है।

पता लगाएँ कि वास्तव में यह किसके पास है

यह तय करने से पहले कि यह कितना ज़रूरी है, इसके धारकों की ईमानदारी से गिनती करें। एक आम छोटी टीम में यह लिस्ट देखने में जितनी लगती है, उससे कहीं ज़्यादा लंबी होती है:

  • हर वह वर्तमान डेवलपर जिसके पास रिपॉजिटरी का एक्सेस है
  • हर वह पूर्व डेवलपर या कॉन्ट्रैक्टर जिसने इसे कभी क्लोन किया हो, जिसके लैपटॉप पर अब आपका कोई कंट्रोल नहीं है
  • बिल्ड एजेंट वर्किंग डायरेक्टरीज़ और उनके कैशे
  • सर्वर और वर्चुअल मशीन के बैकअप और स्नैपशॉट्स
  • रिपॉजिटरी का कोई भी मिरर (mirror)

उस आखिरी ग्रुप को भूलना आसान है। बैकअप को टिकाऊ होने के लिए डिज़ाइन किया जाता है, जो कि लीक हुए क्रेडेंशियल के लिए बिल्कुल गलत बात है।

पता लगाएँ कि की (key) वास्तव में क्या कर सकती है

गंभीरता लीक होने की बात से नहीं, बल्कि प्रिविलेज से जुड़ी है। एक स्टोरेज बकेट के लिए रीड-ओनली की (key), एक एडमिनिस्ट्रेटिव की (key) की तुलना में एक बहुत ही अलग समस्या है।

यहाँ यूज़र अकाउंट का नाम ऐसा रखा गया था मानो वह केवल स्टोरेज वाला अकाउंट हो। ऐसा नहीं था। इसकी वास्तविक परमिशन चेक करने पर एक अलग ही कहानी सामने आई:

aws iam list-attached-user-policies --user-name app-s3
aws iam list-user-policies        --user-name app-s3
aws iam list-groups-for-user      --user-name app-s3

इसके पास हर बकेट पर पूर्ण स्टोरेज एक्सेस था, प्रोडक्शन चलाने वाली कंप्यूट सर्विस का पूर्ण नियंत्रण देने वाले एक ग्रुप की मेंबरशिप थी, और कंपनी के डोमेन से ईमेल भेजने की परमिशन थी। एक ऐसा नाम जो छोटे दायरे का संकेत देता है, लेकिन जिसके पीछे व्यापक शक्तियां थीं।

फिर, वह सवाल जो आपकी टाइमलाइन तय करता है:

aws iam get-access-key-last-used --access-key-id AKIAEXAMPLEKEYID

उसी सुबह इसका इस्तेमाल किया गया था। इसलिए की (key) कोई भूली-बिसरी चीज़ नहीं थी। प्रोडक्शन में कुछ चीज़ें इस पर निर्भर थीं, जिसका मतलब है कि इसे तुरंत डिलीट करने से आउटेज (outage) हो सकता था।

रोटेट करें, केवल निरस्त न करें

यह आखिरी बात प्लान को बदल देती है। इस्तेमाल हो रहे एक लाइव क्रेडेंशियल को रोलओवर की ज़रूरत होती है, अचानक निरस्त करने की नहीं। यहाँ वो सीक्वेंस दिया गया है जो प्रोडक्शन को ब्रेक किए बिना इस खामी को दूर करता है।

कदम 1: पुष्टि करें कि की (key) लाइव है और उसका ब्लास्ट रेडियस (blast radius) खोजें

ऊपर दिए गए परमिशन और लास्ट-यूज़्ड चेक रन करें। की (key) के नाम से नहीं, बल्कि वह क्या कर सकती है इससे उसकी अर्जेंसी तय करें।

कदम 2: पहली के साथ एक दूसरी की (key) बनाएँ

ज़्यादातर क्लाउड प्रोवाइडर प्रति यूज़र दो एक्टिव एक्सेस कीज़ की अनुमति देते हैं ताकि आप सुरक्षित रूप से रोलओवर कर सकें।

aws iam create-access-key --user-name app-s3

अभी पुरानी की (key) को मत छुएँ।

कदम 3: नई की (key) को ऐसी जगह रखें जो रिपॉजिटरी न हो

इसे उस सीक्रेट स्टोर में ले जाएँ जिसका आपकी पाइपलाइन पहले से इस्तेमाल करती है। ज़्यादातर टीमों के पास पहले से ही एक स्टोर होता है और वे बस उसका लगातार उपयोग नहीं कर रही होती हैं। इसे बिल्ड से रेफरेंस दें ताकि वैल्यू डिप्लॉय के समय इंजेक्ट हो जाए और कभी भी सोर्स में न लिखी जाए।

कदम 4: डिप्लॉय और वेरीफाई करें

रीडिप्लॉय करें, फिर पुष्टि करें कि की (key) का इस्तेमाल करने वाले फ़ंक्शन्स अभी भी काम कर रहे हैं। मेरे मामले में इसका मतलब आउटबाउंड ईमेल और फ़ाइल स्टोरेज चेक करना था। निरस्त करने से पहले वेरीफाई करें, कभी भी बाद में नहीं।

कदम 5: पुरानी की (key) को डीएक्टिवेट करें

पहले डिलीट करने के बजाय डीएक्टिवेट करें, क्योंकि अगर आपसे कोई कंस्यूमर छूट गया हो तो डीएक्टिवेशन को तुरंत रिवर्स किया जा सकता है।

aws iam update-access-key --user-name app-s3 --access-key-id AKIAEXAMPLEKEYID --status Inactive

कुछ दिनों तक एरर्स पर नज़र रखें, फिर इसे डिलीट कर दें।

कदम 6: केवल अब, रिपॉजिटरी को साफ़ करें

git rm --cached path/to/appsettings.Production.json
echo "appsettings.Production.json" >> .gitignore

यह कदम जानबूझकर आखिरी है। यह अगले लीक को रोकता है। यह इस वाले को ठीक नहीं करता है।

कदम 7: जब आप यहाँ हैं, तो परमिशन्स को भी कड़ा करें

अगर स्टोरेज के नाम वाले किसी अकाउंट का आपके प्रोडक्शन कंप्यूट पर कंट्रोल था, तो उसे भी ठीक करें। ओवर-प्रिविलेज्ड की (key) को रोटेट करने से आपको बस एक नई ओवर-प्रिविलेज्ड की (key) मिल जाती है।

निष्कर्ष

जब आपको Git में कोई सीक्रेट मिलता है तो पहली बात जो दिमाग में आती है वह उसे डिलीट करके राहत महसूस करने की होती है। इस तरह का विचार एक साफ़ दिखने वाली रिपॉजिटरी तो बनाता है लेकिन रिस्क में कोई बदलाव नहीं होता। हिस्ट्री पर्मानेंट है, क्लोन हर जगह हैं, और बैकअप चीज़ों को हमेशा के लिए सुरक्षित रखने के लिए बनाए जाते हैं। एकमात्र चीज़ जो सच में मदद करती है वह है क्रेडेंशियल को बदलना, और उसे ऐसे क्रम में करना जिससे प्रोडक्शन डाउन न हो। चेक करें कि क्या यह लाइव है, मापें कि यह क्या कर सकता है, एक नई की (key) लाएँ, वेरीफाई करें, फिर पुरानी वाली को बंद कर दें। रिपॉजिटरी की सफ़ाई आखिरी कदम है, पहला नहीं।

खूबियाँ

  • डिटेक्शन चेक एक सिंगल कमांड है और किसी भी रिपॉजिटरी पर काम करता है
  • रोटेशन एक पर्मानेंट फ़िक्स है, जो कि फ़ाइल डिलीट करने या हिस्ट्री रीराइट करने जैसा नहीं है
  • दूसरी की (key) के साथ रोलओवर करने का मतलब है कि लाइव सिस्टम्स के लिए कोई डाउनटाइम नहीं
  • रोटेशन के दौरान परमिशन्स का ऑडिट करने से अक्सर ओवर-प्रिविलेज्ड अकाउंट्स सामने आते हैं
  • सीक्रेट्स को किसी मौजूदा सीक्रेट स्टोर में ले जाने के लिए आमतौर पर किसी नए टूल की ज़रूरत नहीं होती है
  • फाइनल डिलीट होने तक पूरी प्रक्रिया को रिवर्स किया जा सकता है

कमियाँ

  • रोटेशन के लिए की (key) के हर कंस्यूमर को खोजना पड़ता है, जो शायद ही कभी डॉक्युमेंटेड होता है
  • आप मूल एक्सपोज़र को अनडू नहीं कर सकते, केवल इसकी कीमत को सीमित कर सकते हैं
  • हिस्ट्री रीराइट करना मौजूदा क्लोन को ब्रेक कर देता है और टीम के लिए नुकसानदायक होता है
  • लैपटॉप और बैकअप में पहले ही कॉपी किए गए सीक्रेट्स आपके कंट्रोल से बाहर हैं
  • सफ़ाई का काम फीचर के काम के साथ समय के लिए लड़ता है और इसे टालना आसान होता है
  • कुछ पुराने सिस्टम क्रेडेंशियल रोटेशन को सचमुच अजीब बना देते हैं

सावधानी

यह आर्टिकल शिक्षाप्रद है और यह आपके एनवायरनमेंट के लिए कोई नुस्खा बताने के बजाय एक सामान्य दृष्टिकोण का वर्णन करता है। यहाँ मौजूद हर कमांड, फ़ाइल पाथ, अकाउंट नेम और की (key) आइडेंटिफ़ायर एक प्लेसहोल्डर है और इसे आपके अपने सिस्टम की वैल्यूज़ से बदला जाना चाहिए। अगर कोई कंस्यूमर छूट जाता है तो क्रेडेंशियल रोटेट करने से लाइव सर्विसेज़ में रुकावट आ सकती है, इसलिए पहले नॉन-प्रोडक्शन एनवायरनमेंट में हर स्टेप को वेरीफाई करें, किसी की (key) को डीएक्टिवेट करने से पहले यह कन्फर्म करें कि उस पर क्या निर्भर करता है, और यहाँ लिखी किसी भी बात पर भरोसा करने से पहले अपने क्लाउड प्रोवाइडर और टूलिंग के वर्तमान डॉक्युमेंटेशन की जाँच करें।

अक्सर पूछे जाने वाले सवाल

  • क्या Git रिपॉजिटरी से सीक्रेट डिलीट करने पर वो रिमूव हो जाता है? — नहीं। वैल्यू कमिट हिस्ट्री और हर मौजूदा क्लोन में बनी रहती है, इसलिए रिपॉजिटरी वाला कोई भी व्यक्ति इसे अभी भी पढ़ सकता है।
  • क्या लीक हुए सीक्रेट को ठीक करने के लिए Git हिस्ट्री रीराइट करना काफ़ी है? — नहीं। यह रिपॉजिटरी को साफ़ करता है लेकिन उन कॉपीज़ का कुछ नहीं करता जिन्हें लोगों ने पहले ही क्लोन कर लिया है, इसलिए क्रेडेंशियल को अभी भी रोटेट किया जाना चाहिए।
  • मैं कैसे चेक करूँ कि कोई कॉन्फ़िग फ़ाइल Git द्वारा ट्रैक की जा रही है या नहीं? — रन करें git ls-files --error-unmatch <path>. अगर यह सफल होता है, तो फ़ाइल ट्रैक की जा रही है और इसके कॉन्टेंट्स हिस्ट्री में हैं।
  • क्या मुझे लीक हुई की (key) को तुरंत डिलीट कर देना चाहिए? — केवल तभी जब यह अनयूज़्ड (unused) हो। अगर प्रोडक्शन में कोई चीज़ इस पर निर्भर करती है, तो पहले एक रिप्लेसमेंट बनाएँ, डिप्लॉय करें, वेरीफाई करें, फिर पुरानी वाली को डीएक्टिवेट करें।
  • मुझे कैसे पता चलेगा कि लीक हुई क्लाउड की (key) अभी भी इस्तेमाल की जा रही है? — ज़्यादातर प्रोवाइडर एक्सेस कीज़ के लिए एक लास्ट-यूज़्ड टाइमस्टैम्प दिखाते हैं, जो आपको बताता है कि क्या कोई कंस्यूमर अभी भी इस पर निर्भर है।
  • इसके बजाय एप्लिकेशन सीक्रेट्स को कहाँ रहना चाहिए? — किसी सीक्रेट स्टोर में या आपके बिल्ड सिस्टम के क्रेडेंशियल स्टोर में, जिसे डिप्लॉय के समय इंजेक्ट किया जाता है ताकि वह वैल्यू सोर्स कंट्रोल में कभी न दिखाई दे।
  • डिप्लॉयमेंट पाइपलाइन ने सीक्रेट को सुरक्षित क्यों नहीं किया? — पाइपलाइन अक्सर डेटाबेस कनेक्शन स्ट्रिंग जैसी केवल कुछ ही सेटिंग्स को इंजेक्ट करती हैं, और बाकी सभी वैल्यूज़ को बिल्कुल वैसे ही छोड़ देती हैं जैसे कमिट की गई थीं।
  • मैं इसे दोबारा होने से कैसे रोक सकता हूँ? — कॉन्फ़िग फ़ाइलों को इसमें जोड़ें .gitignore, अपनी रिपॉजिटरीज़ पर ऑटोमेटेड सीक्रेट स्कैनिंग इनेबल करें, और परमिशन्स को रिव्यू करें ताकि लीक हुई कीज़ का महत्व कम से कम हो।

टैग्स

#Security #DevOps #Git #SecretsManagement #CloudSecurity #IAM #KeyRotation #DevSecOps #ConfigManagement #InfrastructureAsCode

Free field guide

Incident Response: First Hour

A calm, evidence-preserving checklist for establishing control, bounding impact, communicating clearly, and containing an incident safely.