# Proxy environment variables: agent API traffic का audit

Proxy environment variables executable routing instructions होते हैं, harmless shell preferences नहीं। अगर कोई AI coding agent `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY` या `NO_PROXY` inherit करता है, तो internal API को direct call जैसा दिखने वाला request agent के कोई उपयोगी काम करने से पहले ही अलग network path ले सकता है।

मैंने teams को token scope और endpoint allowlists की समीक्षा में कई दिन लगाते देखा है, फिर पता चला कि agent runner ने developer shell से local debugging proxy inherit कर लिया था। Credentials valid थे, API client ठीक उसी तरह व्यवहार कर रहा था जैसा configure किया गया था, फिर भी traffic वहां जा रहा था जहां किसी ने इरादा नहीं किया था। Internal services का access देने से पहले process environment का audit करें।

## Proxy variables केवल connection settings नहीं, route बदलते हैं

Proxy variable cooperating client को बताता है कि request किसी intermediary को सौंपनी है। सामान्य HTTP में client आम तौर पर पूरी destination URL उस intermediary को भेजता है। HTTPS में client आम तौर पर proxy से target host के लिए `CONNECT` tunnel खोलने को कहता है, फिर उसी tunnel के भीतर TLS करता है।

यह अंतर महत्वपूर्ण है, क्योंकि proxy HTTPS को decrypt न कर पाए तब भी availability, destination control, DNS behavior और observability को प्रभावित कर सकता है। Proxy connection अस्वीकार कर सकता है, TCP layer पर उसे redirect कर सकता है, requested host और port record कर सकता है, या किसी service तक पहुंचने का agent के लिए एकमात्र रास्ता बन सकता है।

इन variables को agent की outbound authority का हिस्सा मानें:

- `HTTP_PROXY` और `http_proxy` आम तौर पर `http://` URLs को प्रभावित करते हैं।
- `HTTPS_PROXY` और `https_proxy` आम तौर पर `https://` URLs को प्रभावित करते हैं।
- `ALL_PROXY` और `all_proxy` इन्हें support करने वाले clients में fallback की तरह काम करते हैं।
- `NO_PROXY` और `no_proxy` आम तौर पर destinations को proxying से exempt करते हैं।

यहां «आम तौर पर» शब्द महत्वपूर्ण है। Environment variables एक convention हैं, कोई ऐसा network standard नहीं जिसे हर runtime एक ही तरह लागू करे। Agent command-line client चला सकता है, language HTTP library इस्तेमाल कर सकता है, package manager invoke कर सकता है या helper process शुरू कर सकता है। हर layer proxy के बारे में अलग निर्णय ले सकती है।

Variable unset होना direct route का प्रमाण भी नहीं है। Client config file पढ़ सकता है, system proxy setting इस्तेमाल कर सकता है, PAC file मान सकता है या local relay को सीधे call कर सकता है। यह लेख environment variables पर केंद्रित है, क्योंकि इन्हें inherit करना आसान है, भरे हुए process environment में इनका पता लगाना कठिन है और इन्हें अक्सर अस्थायी समझा जाता है, जबकि वे स्थायी बन चुके होते हैं।

## Launcher तय करता है कि agent क्या inherit करेगा

Agent को वही variables मिलते हैं जो उसके अपने process environment में मौजूद हों या parent ने उसे pass किए हों। जिस terminal में आपने `env` जांचा था, उसका उस process से कोई संबंध न हो सकता है जो वास्तव में agent चलाता है।

macOS पर यह गलती खास तौर पर आसानी से होती है। Interactive shell से शुरू हुआ process shell के exported variables inherit करता है। Finder से शुरू की गई graphical app या `launchd` के ज़रिए शुरू हुई service अलग inheritance path अपनाती है। IDE अपने integrated terminal को एक environment और extension host को दूसरे environment के साथ शुरू कर सकता है। कल शुरू किया गया background agent पुरानी proxy value बनाए रख सकता है, भले ही shell variable अब गायब हो चुका हो।

Settings बदलने से पहले execution chain map करें। चार सीधे सवाल पूछें:

1. Agent शुरू करने वाला process कौन-सा है?
2. क्या agent shells, package tools, test runners या remote helpers शुरू करता है?
3. इनमें से कौन-से processes HTTP calls करते हैं?
4. हर environment variable किस launch point से आता है?

जब तक आप parent process की पहचान करके उसी terminal से run दोहरा न सकें, «agent मेरे terminal में चलता है» को उत्तर न मानें। Agent editor, task runner या saved environment इस्तेमाल करने वाली automation service का child हो सकता है।

Parent process द्वारा डाला गया proxy हर child तक पहुंचता है, जब तक child उसे हटा न दे। इसी कारण shell में किया गया एक-line export package installation, source control helpers, cloud CLIs, browser automation और test fixtures की calls को चुपचाप बदल सकता है। प्रभावित request वह नहीं भी हो सकता है जिसके बारे में आपने agent शुरू करते समय सोचा था।

## Proxy variable semantics clients के बीच अलग होती हैं

`HTTP_PROXY`, `HTTPS_PROXY` और `NO_PROXY` की एक ही universal interpretation नहीं है। अगर security review में यह मान लिया जाए कि एक client का behavior दूसरे पर भी लागू होगा, तो review अधूरा है।

curl documentation एक महत्वपूर्ण exception बताती है जिसे कई लोग भूल जाते हैं: HTTP proxy configuration के लिए curl केवल lowercase `http_proxy` स्वीकार करता है। Documentation के अनुसार इससे CGI समस्या से बचाव होता है, जिसमें आने वाला `Proxy:` header `HTTP_PROXY` environment variable बन सकता है। curl कई दूसरे proxy variables के uppercase variants स्वीकार करता है, लेकिन HTTP का यह exception जानबूझकर रखा गया है।

Go `http.ProxyFromEnvironment` को ऐसे function के रूप में document करता है जो `HTTP_PROXY`, `HTTPS_PROXY` और `NO_PROXY`, साथ में lowercase alternatives, पढ़ता है। इसमें CGI protection भी है: जब CGI environment में `REQUEST_METHOD` मौजूद हो, तो Go `HTTP_PROXY` इस्तेमाल करने से मना कर देता है, क्योंकि request header ने इसे supply किया हो सकता है। इसका अर्थ यह नहीं कि Go process सुरक्षित है। `HTTPS_PROXY`, lowercase forms, explicit transport settings और non-CGI contexts की भी समीक्षा करनी होगी।

कई JavaScript applications तस्वीर को और जटिल बनाती हैं। Node.js runtime के built-in HTTP APIs ने ऐतिहासिक रूप से एक universal environment proxy policy लागू नहीं की है। Applications और उनकी dependencies अक्सर खुद proxy support जोड़ती हैं। एक command `HTTPS_PROXY` मान सकता है, उसी agent run का दूसरा command उसे अनदेखा कर सकता है और तीसरा custom option पढ़ सकता है।

इसे runtime folklore की spreadsheet से तय न करें। हर network-capable executable की पहचान करके उसका test करें। Executable version, invocation, target URL, relevant variables और यह दर्ज करें कि connection direct था या intended proxy के माध्यम से। परिणाम agent की deployment notes में रखें, क्योंकि dependency update behavior बदल सकता है।

एक उपयोगी अंतर अक्सर धुंधला हो जाता है: proxy awareness, proxy enforcement नहीं है। Variable मौजूद होने पर उसे मानने वाला client routed हो सकता है। Variable absent या malformed हो, `NO_PROXY` bypass करे या helper process उसे ignore करे, तो client direct connect कर सकता है। अगर direct egress रोकना है, तो network boundary पर enforcement करें, इस उम्मीद पर नहीं कि हर library environment variable पढ़ेगी।

## Internal names के लिए NO_PROXY की स्पष्ट जांच करें

`NO_PROXY` bypass list है और खराब bypass list internal traffic को proxy से भेज सकती है या उस traffic को direct कर सकती है जिसे आप inspect करना चाहते थे। किसी भी outcome को बिना जांच के सुरक्षित न मानें।

अधिकतर implementations comma-separated entries स्वीकार करती हैं। इसके आगे details अलग हो जाती हैं। Clients `registry.corp.example`, `.corp.example`, `corp.example`, `10.20.0.0/16`, `10.20.30.40`, `localhost` और `*` को अलग-अलग तरह से देख सकते हैं। एक client में काम करने वाला suffix match दूसरे में बहुत व्यापक हो सकता है या पूरी तरह विफल हो सकता है। Port-qualified entries भी एक जैसा व्यवहार नहीं करतीं।

जब तक test उनका अर्थ साबित न कर दे, broad entries से बचें। Bare domain suffix अनजाने hosts को exempt कर सकता है। Asterisk proxying को reviewer की अपेक्षा से कहीं अधिक व्यापक रूप से बंद कर सकता है। जहां CIDR support हो वहां यह उपयोगी है, लेकिन इसे portable assumption न मानें। Exact internal hostnames उबाऊ लगते हैं, और यहां उबाऊ होना उपयोगी है।

उन named services की छोटी सूची से शुरू करें जिन्हें direct connect करना जरूरी है, जैसे internal source host, artifact registry और service discovery endpoint। Domain suffix तभी जोड़ें जब आप साबित कर चुके हों कि client उसे अपेक्षित तरीके से match करता है और उस suffix के नीचे हर host को वही route मिलना चाहिए।

Hostname matching और name resolution को भी अलग रखें। Client अक्सर connect करने से पहले तय करता है कि `NO_PROXY` लागू होता है या नहीं। सूची में hostname हो तो matching सफल हो सकती है, भले ही host ऐसे address पर resolve हो जो आपकी अपेक्षित range से बाहर हो। सूची में IP range हो तो client को निर्णय लेने से पहले name resolve करना पड़ सकता है। यह sequence implementation तय करती है।

Bypass test के लिए ऐसा destination चाहिए जिसे आप control करते हों और logs में पहचान सकें। Production API का इस्तेमाल करके 200 response से निष्कर्ष न निकालें। Internal test endpoint को remote address report करना चाहिए या अपने access log में request identifier लिखना चाहिए। फिर bypass entry के साथ और उसके बिना request की तुलना करें। आपको application output पर आधारित अनुमान नहीं, connection path का प्रमाण चाहिए।

## HTTPS content छिपाता है, लेकिन proxy को उपयोगी जानकारी मिलती रहती है

HTTPS `CONNECT` tunnel आम तौर पर conventional forward proxy से request headers और bodies को सुरक्षित रखता है। इससे proxy अप्रासंगिक नहीं हो जाता। Proxy `CONNECT` request में दिया host और port, connection timing, byte counts और अक्सर source address देखता है। Client और network के अनुसार संबंधित DNS traffic भी अतिरिक्त जानकारी दे सकता है।

अगर client ऐसी certificate authority पर भरोसा करता है जिसका इस्तेमाल proxy TLS interception के लिए करता है, तो proxy decrypted API credentials पढ़ सकता है। कुछ managed corporate networks और debugging setups में ऐसा होता है। Trusted local root certificate की मौजूदगी convenience setting नहीं, security boundary का निर्णय है। अगर agent process उस root पर भरोसा करता है, तो interception policy लागू होने वाले किसी भी host का traffic proxy operator inspect कर सकता है।

Plain HTTP इससे भी खराब है। Forward proxy को पूरी URL और request headers मिल सकते हैं, जिनमें bearer tokens या basic authentication शामिल हैं। «Network private है» कहकर authenticated internal APIs के लिए plaintext HTTP का इस्तेमाल agent को न करने दें। Proxy environment variables उन कई तरीकों में से एक हैं जिनसे private-network assumptions गलत साबित होती हैं।

एक कम स्पष्ट समस्या embedded credentials वाले proxy URL की है, जैसे `http://user:password@proxy.example:8080`। यह value diagnostic output, crash reports, shell history, process inspection या environment record करने वाले logs में दिख सकती है। Proxy authentication के लिए अपने environment के अनुरूप managed mechanism इस्तेमाल करें और proxy credentials को अलग secrets मानें।

अगर आप proxy operator, proxy listener address और TLS interception की संभावना की पहचान नहीं कर सकते, तो privileged agent traffic उसके माध्यम से न भेजें। यह अतिशंका नहीं है। Proxy automated process और sensitive service के बीच के path का हिस्सा बन चुका है।

## Secrets dump किए बिना running process का audit करें

ऐसी inventory से शुरुआत करें जो variable names और proxy endpoints दिखाए, लेकिन पूरा environment dump न करे। Agent शुरू करने वाले shell में चलाएं:

```sh
env | grep -Ei '(^|_)(http|https|all|no)_proxy='
```

Output का रूप ऐसा होना चाहिए:

```text
HTTPS_PROXY=http://127.0.0.1:8888
NO_PROXY=localhost,127.0.0.1,registry.corp.example
```

अगर proxy URL में user information हो, तो raw output को ticket में paste न करें। Credentials हटाकर scheme, host और port दर्ज करें। Loopback address अपने-आप सुरक्षित नहीं होता। Local proxies अक्सर legitimate debugging tools के होते हैं, लेकिन malware और unwanted software भी loopback पर listen कर सकते हैं। Listening port का मालिक कौन-सा process है, यह सत्यापित करें।

macOS पर listener देखें:

```sh
lsof -nP -iTCP:8888 -sTCP:LISTEN
```

सामान्य result में command और process ID दिखते हैं। अगर expected process port का मालिक नहीं है, तो यहीं रुककर जांच करें। केवल इसलिए credentials किसी listener को न भेजें कि address `127.0.0.1` से शुरू होता है।

इसके बाद वास्तविक agent process की जांच करें। macOS पर `ps` process environment दिखा सकता है, लेकिन इससे असंबंधित secrets भी सामने आ सकते हैं। Access को machine owner या administrator तक सीमित रखें, केवल आवश्यक जानकारी लें और result को chat या shared log में paste न करें।

```sh
ps eww -p "$AGENT_PID" | tr ' ' '\n' | grep -Ei '(^|_)(http|https|all|no)_proxy='
```

`AGENT_PID` में चल रहे agent का process ID रखें। अगर proxy credentials मौजूद हैं, तो यह command उन्हें फिर भी दिखा सकती है। इसे trusted terminal पर चलाएं और evidence सुरक्षित करने से पहले redact करें। अगर output आपके shell inventory से अलग है, तो parent process ने variables inject या remove किए हैं।

`launchd` से शुरू होने वाले processes के लिए terminal पर निर्भर रहने के बजाय job definition और launcher देखें। `launchctl getenv HTTPS_PROXY` current launchd domain में variable दिखा सकता है, लेकिन वहां उसका न होना किसी खास job को निर्दोष साबित नहीं करता। Job अपना environment define कर सकती है और wrapper script agent शुरू करने से ठीक पहले variables export कर सकती है।

## Harmless request से route साबित करें

Configuration review बताती है कि क्या होना चाहिए। Controlled request बताती है कि वास्तव में क्या हुआ। दोनों आवश्यक हैं।

ऐसा non-sensitive endpoint बनाएं या इस्तेमाल करें जो peer address और request path log करे। फिर verbose connection output के साथ request करें। curl उपयोगी है, क्योंकि यह दिखाता है कि proxy से connection हुआ या नहीं और `CONNECT` request भेजी गई या नहीं।

```sh
HTTPS_PROXY=http://127.0.0.1:8888 \
NO_PROXY= \
curl -v --connect-timeout 5 https://probe.corp.example/agent-proxy-check
```

जब curl HTTPS के लिए proxy इस्तेमाल करता है, तो verbose output में आम तौर पर इस तरह की lines दिखती हैं:

```text
* Uses proxy env variable HTTPS_PROXY == 'http://127.0.0.1:8888'
* Establish HTTP proxy tunnel to probe.corp.example:443
> CONNECT probe.corp.example:443 HTTP/1.1
```

अब जानबूझकर direct comparison चलाएं:

```sh
HTTPS_PROXY=http://127.0.0.1:8888 \
NO_PROXY=probe.corp.example \
curl -v --connect-timeout 5 https://probe.corp.example/agent-proxy-check
```

Direct run में proxy को `CONNECT` request भेजने के बजाय target से connection दिखना चाहिए। Probe के server logs में भी यही परिणाम confirm करें। अगर curl कहता है कि उसने proxy bypass किया, लेकिन server को unexpected source दिखता है या request विफल होती है, तो DNS, routing और किसी transparent network proxy की अलग से जांच करें।

यह curl को साबित करता है, आपके agent को नहीं। Agent के exact execution route से test दोहराएं। अगर वह script invoke करता है, तो वही script चलाएं। अगर dependency के माध्यम से API call करता है, तो उसी configuration से temporary probe URL जोड़ें। अगर helper process शुरू करता है, तो helper के route evidence को collect करें। किसी अलग client का test केवल संकेत है।

इस काम के लिए public «what is my IP» service का इस्तेमाल न करें। इससे internal routing review अनावश्यक external disclosure में बदल जाता है और यह नहीं बता सकता कि कौन-सी internal proxy policy लागू हुई।

## Permanent shell exports से बेहतर है clean launch environment

Corporate proxy exports को universal shell profile में न रखें और फिर autonomous tools से safe exceptions की उम्मीद न करें। Global exports लोकप्रिय हैं क्योंकि वे blocked command को एक बार चला देते हैं। वे हर उस child process तक भी फैलते हैं जिसके बारे में आप बाद में भूल जाते हैं।

Agent के लिए explicit launcher इस्तेमाल करें। Known environment से शुरू करें, run के लिए आवश्यक variables ही pass करें और launch command या wrapper में proxy use स्पष्ट रखें। Unix shell में `env -i` inherited variables साफ करता है, इसलिए program के लिए जरूरी basics फिर से देने होंगे:

```sh
env -i \
PATH="$PATH" \
HOME="$HOME" \
LANG="${LANG:-en_US.UTF-8}" \
NO_PROXY="localhost,127.0.0.1,registry.corp.example" \
agent-command
```

इस example में जानबूझकर proxy set नहीं किया गया है। Agent को proxy चाहिए तो उसके owner की पहचान और behavior का test करने के बाद launcher में proxy variable जोड़ें। Shell profile से proxy value उठाकर script में डालने से पहले जांचें कि उसमें credentials तो नहीं हैं या वह किसी पुराने local service की ओर तो नहीं जाती।

Clean environment से वे tools टूट सकते हैं जो certificate locations, cloud profiles, SSH agent sockets या package caches जैसे variables पर निर्भर थे। यह टूटना उपयोगी जानकारी है। Agent को एक-एक करके केवल आवश्यक variables वापस दें और हर variable की वजह document करें। Agent launcher इतना सीमित होना चाहिए कि कोई दूसरा engineer उसे पढ़कर समझ सके कि requests कहां जाएंगी।

Network controls को इसका साथ देना चाहिए। अगर agent को कुछ ही internal services तक पहुंचना है, तो अपने environment के अनुसार firewall rules, enforced policy वाला egress proxy या dedicated network segment इस्तेमाल करें। Environment variables cooperative clients के लिए route चुनते हैं। वे compromised process या noncompliant library को direct socket खोलने से नहीं रोकते।

## Route चुनने वाले process से credentials दूर रखें

Proxy hygiene accidental rerouting घटाती है, लेकिन इससे autonomous agent को API tokens देना समझदारी नहीं बन जाता। अगर agent environment में bearer token है, तो उस environment तक पहुंच रखने वाला हर process secret की exposure path का हिस्सा बन जाता है।

Sallyport अलग boundary इस्तेमाल करता है: agent अपने MCP shim के माध्यम से HTTP या SSH action का अनुरोध करता है, जबकि credentials app के encrypted vault में रहते हैं और app action execute करती है। इससे agent process में proxy-variable leak होने पर exposure सीमित रहता है, क्योंकि agent को API या SSH credential plaintext में कभी मिलता ही नहीं।

इस boundary को बढ़ा-चढ़ाकर न बताएं। Credential gateway agent द्वारा चलाए जाने वाले हर command के लिए safe proxy behavior अपने-आप तय नहीं करता और harmful destination को harmless नहीं बना सकता। आपको अब भी अनुमत destinations और actions नियंत्रित करने होंगे, network call करने वाले application process की समीक्षा करनी होगी और request path का evidence रखना होगा।

उपयोगी separation secret custody और network routing के बीच है। Secret custody बताती है कि credential कौन पढ़ सकता है। Network routing बताती है कि request किस intermediary को संभालनी है। Teams अक्सर एक समस्या हल करके मान लेती हैं कि दोनों हल हो गईं। ऐसा नहीं है।

## बिना कारण proxy use को contained incident मानें

अगर privileged agent ने किसी अज्ञात proxy के ज़रिए requests की हैं, तो उसी दूषित environment के भीतर जांच शुरू करने से पहले run रोकें। Agent process ID, parent process, proxy address, प्रभावित destination names और time window दर्ज करें। Incident process के तहत relevant agent और proxy logs सुरक्षित रखें।

फिर variable को उसके source पर हटाएं। Current terminal में उसे delete करने से केवल उस terminal के future children ठीक होंगे। Shell profiles, IDE task settings, launch agents, CI configuration, wrapper scripts और environment settings लिखने वाले configuration management की जांच करें। Launch point ठीक करने के बाद प्रभावित process restart करें।

Protocol के आधार पर credentials का आकलन करें। अगर प्रभावित traffic authentication वाले plaintext HTTP का था, तो exposed credential rotate करें। अगर HTTPS proxy के माध्यम से गया था, तो पता लगाएं कि endpoint ने normal TLS validate किया था या नहीं और agent interception certificate पर भरोसा करता था या नहीं। यह न मानें कि HTTPS होने से review की जरूरत नहीं है, और जब तक वही injection path मौजूद हो तब तक बिना सोचे credentials rotate न करें।

अंत में agent start होने पर preflight check जोड़ें। Unexpected proxy variable मिलने पर run fail करें या explicit review मांगें। Check में variable name और sanitized endpoint दिखना चाहिए, उसे उस job के approved route से compare करना चाहिए और यह record छोड़ना चाहिए कि preflight चला था। पहला unexplained proxy warning है। दूसरा deployment defect है जिसे आपने बनाए रखने का चुनाव किया।
