# Credential injection को request validation का पालन कैसे करना चाहिए

Credentials को outbound request pipeline के अंत में जोड़ना चाहिए, तब जब client तय कर चुका हो कि वह क्या भेजने को तैयार है। यदि कोई component वास्तविक destination और request shape को validate करने से पहले API key या SSH credential जोड़ देता है, तो security decision पहले ही लिया जा चुका है। उसके बाद होने वाली हर चीज केवल सफाई है।

Autonomous coding agents के साथ यह क्रम और भी महत्वपूर्ण हो जाता है। Agent कोई plausible request बना सकता है, API response से मिले link का अनुसरण कर सकता है, repository का कोई example दोबारा इस्तेमाल कर सकता है या परिणाम समझे बिना redirect स्वीकार कर सकता है। इसके लिए agent का malicious होना जरूरी नहीं है। इतना काफी है कि request path untrusted input को authenticated request की destination प्रभावित करने दे।

सरल नियम यह है: प्रस्तावित कार्रवाई को parse करें, पूरी कार्रवाई validate करें, उसे freeze करें, उससे मेल खाने वाला connection बनाएं और फिर आखिरी जिम्मेदार क्षण पर credential inject करें। Request बदल जाए तो authorization decision छोड़ दें और शुरुआत से फिर चलें।

## Credentials request validation को security boundary बनाते हैं

Credential injector HTTP client के ऊपर बना कोई सुविधा wrapper नहीं है। वह तय करता है कि कौन-सा remote party आपकी तरह कार्य करने का अधिकार पाएगा। इसलिए validation boundary में request object से कॉपी किया गया केवल hostname field शामिल नहीं होना चाहिए।

HTTP action के लिए कम से कम scheme, hostname, port, method, path, query rules, संबंधित headers और body validate करें। SSH के लिए host, port, host key trust decision, remote account, command, environment forwarding और file-transfer target validate करें। विवरण अलग हो सकते हैं, लेकिन क्रम वही रहता है।

Teams अक्सर दो अलग सवालों को मिला देती हैं:

- क्या यह request इच्छित service तक पहुंच सकती है?
- क्या इस exact request को authorize करने के लिए यह credential इस्तेमाल की जानी चाहिए?

सफल DNS lookup और valid TLS certificate पहले सवाल का केवल एक हिस्सा हल करते हैं। वे दूसरे का उत्तर नहीं देते। `https://api.example.com:8443` को भेजी गई request अपने-आप सामान्य HTTPS port को भेजी गई request के बराबर नहीं है। Bearer token वाली `POST /v1/refunds` उसी host पर पहुंचने वाली `GET /v1/me` का विकल्प नहीं है।

सबसे आम गलती एक व्यापक rule से शुरू होती है, जैसे «यह key api.example.com के लिए है», और फिर ऐसा client बनाया जाता है जो कोई भी URL स्वीकार करता है, header जोड़ता है और library से उसे भेजने को कहता है। इससे URL parsing, redirect handling, proxy behavior और agent-controlled headers को बहुत अधिक अधिकार मिल जाता है। Reviews भी भ्रामक हो जाती हैं। कोई व्यक्ति एक तरह से वर्णित request को approve कर सकता है, जबकि wire request कुछ और हो।

Request validator को इस पूरे अंतर पर authority रखनी चाहिए। उसे structured request पर स्पष्ट निर्णय लेना चाहिए, किसी string में familiar domain name खोजकर बाकी व्यवहार के ठीक रहने की उम्मीद नहीं करनी चाहिए।

## Destination को canonical origin में parse करें

Destination check को string prefixes के बजाय structured URL components की तुलना करनी चाहिए। HTTP origin की पहचान scheme, host और port से होती है। RFC 3986 authority portion को optional user information, host और optional port के रूप में परिभाषित करता है। RFC 9110 HTTP requests के लिए origin concept का उपयोग करता है। ये छोटी परिभाषाएं बड़े परिणाम देती हैं।

URL को वास्तविक URL parser से parse करें। ऐसे values अस्वीकार करें जिनकी integration को जरूरत नहीं है। Malformed input को अधिक permissive रूप में repair न करें। Helpful बनने की कोशिश करने वाला validator अक्सर दूसरा parser बना देता है, जिसका behavior HTTP client से अलग हो जाता है।

Typical API credential के लिए conservative destination rule इस तरह दिख सकता है:

```text
accepted scheme: https
accepted host: api.billing.example
accepted port: 443 only
accepted paths: /v1/invoices/* and /v1/customers/*
userinfo: forbidden
fragments: ignored before sending, rejected in proposed actions
IP literals: forbidden unless explicitly configured
```

Canonicalization में संयम रखें। तुलना से पहले DNS hostname को lowercase करें। Omitted HTTPS port और port 443 को एक ही effective port मानें। सुनिश्चित करें कि parser ने userinfo को host से अलग किया है। Dot segments को तभी normalize करें जब normalized path को भी validate करेंगे, और reserved characters को तब तक decode न करें जब तक आपको यह पता न हो कि client उनकी व्याख्या कैसे करेगा।

कई URLs बताते हैं कि prefix checks क्यों विफल होते हैं:

```text
https://api.billing.example.attacker.invalid/v1/invoices
https://api.billing.example@attacker.invalid/v1/invoices
https://api.billing.example:8443/v1/invoices
https://api.billing.example/v1/../admin/users
```

केवल शुरुआती अक्षर परिचित दिखते हैं। Authority या अंतिम path अलग हो सकता है। दूसरा URL खास तौर पर जांचने लायक है, क्योंकि `@` से पहले का text userinfo है, remote host नहीं। Browser इसे इस तरह दिखा सकता है कि जल्दी में review करने वाला व्यक्ति गलत हिस्से पर नजर डाल दे।

Internationalized domain names के साथ भी यही सावधानी रखें। तय करें कि integration fixed ASCII hostname स्वीकार करेगी या internationalized names का स्पष्ट set। एक documented rule के तहत convert और compare करें। एक जगह display form और दूसरी जगह wire form की तुलना न करें।

DNS आपका authorization database नहीं है। Origin स्वीकार करने के बाद connection के लिए DNS का उपयोग कर सकते हैं, लेकिन केवल इसलिए destination स्वीकार न करें कि वह अपेक्षित address पर resolve होता है। Shared hosting, load balancers, बदलते service addresses और DNS rebinding IP-based assumptions को कमजोर बनाते हैं। Private-network protections की जरूरत हो तो उन्हें origin allowlist के अतिरिक्त connection rule के रूप में लगाएं, उसके विकल्प के रूप में नहीं।

## Connection target और HTTP authority को साथ validate करें

URL, TLS server name और HTTP authority को एक ही approved destination बताना चाहिए। यदि वे अलग हैं, तो credential injector को रुक जाना चाहिए।

HTTP में authority एक से अधिक जगह दिखाई दे सकती है। HTTP/1.1 में `Host` header होता है। HTTP/2 और HTTP/3 में `:authority` pseudo-header का उपयोग होता है। HTTP proxy को absolute-form request target मिल सकता है, जिसमें दूसरी authority हो। RFC 9112 के अनुसार client को HTTP/1.1 में Host header भेजना चाहिए और missing, repeated या invalid Host fields को malformed माना जाता है। यह नियम इसलिए है क्योंकि authority के आधार पर routing कोई वैकल्पिक सजावट नहीं है।

Credential-aware client में सबसे सुरक्षित व्यवस्था यह है कि authority बनाना agent के नियंत्रण से बाहर रखा जाए। Trusted transport पहले से approved URL से `Host` या `:authority` बनाए। वह agent द्वारा दी गई दूसरी routing authority स्वीकार न करे। Agent द्वारा दिए गए `Connection`, `Proxy-Authorization`, `Transfer-Encoding`, `Content-Length` या `Expect` headers भी स्वीकार न करे, जब तक किसी सीमित integration को वास्तव में उनकी जरूरत न हो और implementation उन्हें जानबूझकर handle न करती हो।

इससे split-brain request से बचा जा सकता है। मान लें validator `https://api.billing.example/v1/invoices` को approve करता है और फिर agent के arbitrary headers merge कर देता है। यदि lower HTTP stack दिए गए `Host` value को मान ले, तो proxy, gateway या misconfigured server उस header के आधार पर request को route कर सकता है। Validator ने एक destination approve की, जबकि request दूसरी जगह पहुंच गई।

यही rule proxy configuration पर भी लागू होता है। Corporate proxy legitimate हो सकता है, लेकिन वह transport route है, credential के लिए नई authority नहीं। Proxy settings को agent के request data से बाहर रखें। Final destination को स्वतंत्र रूप से validate करें और proxy behavior को audit records में स्पष्ट रखें।

HTTPS के लिए TLS certificate verification अनिवार्य है, लेकिन certificate verification किसी भी credential के उपयोग की अनुमति नहीं है। Client को approved URL के hostname को verify करना चाहिए, जहां लागू हो server-name indication के लिए भी उसी hostname का उपयोग करना चाहिए और certificate mismatch अस्वीकार करना चाहिए। Agent को «skip verification» switch न दें। Temporary diagnostic shortcut अक्सर permanent escape hatch बन जाता है।

## Redirects नई requests हैं, continuation नहीं

Authenticated redirect नई destination वाली दूसरी request है। उसे transparent continuation मानना उस boundary से credentials बाहर जाने का रास्ता है जिसे आप लागू करना चाहते थे।

API clients के लिए सबसे सुरक्षित default यह है कि credential वाली request पर automatic redirect following बंद रहे। Redirect response trusted request layer को लौटाएं, `Location` value parse करें, URL rules के अनुसार उसे resolve करें और बनी हुई request को full validator से गुजारें। उसके बाद ही तय करें कि दूसरी request करनी है, और केवल उसी नई request के लिए validation के बाद credential inject करें।

Different origin पर redirect को original request का credential नहीं मिलना चाहिए। इसमें अलग scheme, hostname या effective port सभी शामिल हैं। Credentialed API call में HTTPS से HTTP redirect तुरंत विफल होना चाहिए। `api.example.com` से `login.example.com` redirect भी origin change है, भले दोनों नाम एक ही company के हों। Company ownership transport rule नहीं है।

HTTP status code risk बदलता है। RFC 9110 redirect behavior बताता है, जिसमें वे codes भी हैं जो request method और body को बनाए रखते हैं। RFC 9700, OAuth 2.0 Security Best Current Practice, चेतावनी देता है कि authorization servers को user credentials वाली संभावित request को redirect करते समय HTTP 307 का उपयोग नहीं करना चाहिए। कारण सीधा है: client नई location पर original method और body दोहरा सकता है।

इससे practical redirect policy बनती है:

1. Credentialed machine-to-machine calls के लिए default रूप से redirects अस्वीकार करें।
2. Integration को जरूरत हो तो केवल छोटे, documented set of redirects की अनुमति दें।
3. हर hop पर resolved destination, method, headers और body को फिर validate करें।
4. अगले hop पर विचार करने से पहले सभी credentials हटा दें।
5. Redirect limit कम रखें और हर decision log करें।

हर subdomain पर भरोसा करके समस्या हल न करें। `uploads.example.com` और `api.example.com` अलग teams द्वारा चलाए जा सकते हैं, अलग infrastructure इस्तेमाल कर सकते हैं या अलग attack paths खोल सकते हैं। Setup के समय सुविधाजनक लगा wildcard अक्सर अपनी मूल वजह खत्म होने के बाद भी बना रहता है।

Signed requests में भी एक संबंधित समस्या है। यदि API method, path, चुने हुए headers या body digest को sign करती है, तो redirect signature को आम तौर पर बनाए नहीं रख सकता। Re-signing तभी उचित है जब अगली request अपना validation पास कर चुकी हो। Signature केवल यह साबित करता है कि secret रखने वाले किसी व्यक्ति ने data sign किया। यह साबित नहीं करता कि data अब भी approved destination का वर्णन करता है।

## Filtering से पहले headers का ownership तय करें

जब आप तय कर लेते हैं कि हर header का मालिक कौन है, तो header filtering आसान हो जाती है। Request layer credentials और routing की मालिक होनी चाहिए। Agent केवल उन application headers का मालिक हो सकता है जिन्हें कोई specific integration अनुमति देती है।

Credential headers में `Authorization`, vendor-specific API key header, cookies और कभी-कभी signature header शामिल हैं। इन्हें validation के बाद inject करें। Agent से कोई credential न लें, भले agent कहे कि वह placeholder है। Placeholder accidental substitution logic को आमंत्रित करता है और गलत interface सिखाता है: agent action का प्रस्ताव देता है, trusted component authority उपलब्ध कराता है।

Routing और framing headers में `Host`, `Content-Length`, `Transfer-Encoding`, `Connection`, `Upgrade` और HTTP/2 pseudo-headers आते हैं। इन्हें transport library से बनवाएं। User input को इन पर override न करने दें।

Application headers की अनुमति दी जा सकती है, लेकिन schema के रूप में। मान लें API customer identifier, idempotency key और content type स्वीकार करती है। उन्हीं names की अनुमति दें, उनकी values validate करें और बाकी सब अस्वीकार करें। Arbitrary header map pass through न करें, सिर्फ इसलिए कि अधिकतर calls harmless headers इस्तेमाल करती हैं। Rare header ही ordinary request को proxy instruction, cache variant, alternate identity या debugging path में बदल सकता है।

Logs में `Authorization` को विशेष handling चाहिए। Log करें कि injector ने `billing-prod-readwrite` credential reference इस्तेमाल किया, उसकी value या encoded form नहीं। Generic logger के capture करने के बाद header redact करना भरोसेमंद नहीं है। किसी component के request serialize करने से पहले structured fields से safe event बनाएं।

Custom header credentials bearer tokens से कम sensitive नहीं हैं, सिर्फ इसलिए कि उनका नाम `X-Api-Key` है। यदि receiving service value को authority मानती है, तो जिसे भी वह value मिलती है वह उसे replay कर सकता है। अलग header names interoperability और logging habits बदलते हैं, value को कहां भेजना सुरक्षित है इसकी जरूरत नहीं।

## Method, path और body मिलकर action को परिभाषित करते हैं

जब एक credential data पढ़ सकती है, बदल सकती है या money movement शुरू कर सकती है, तो host allowlist बहुत व्यापक है। Permission decision में request shape भी शामिल होनी चाहिए।

Method से शुरुआत करें। Integration को जिन methods की जरूरत है, उन्हीं की अनुमति दें और बाकी अस्वीकार करें। `POST` को अपने-आप dangerous और `GET` को safe न मानें। कई APIs state-changing operations को GET endpoints के पीछे रखती हैं, और GET query parameters या logs के जरिए private information लीक कर सकती है। फिर भी method rules जरूरी हैं, क्योंकि वे policy review को ठोस बनाते हैं।

फिर path को vague prefix के बजाय route templates के विरुद्ध validate करें। `/v1/projects/{project_id}/deployments` जैसा route template segments की संख्या, identifiers में allowed characters और यह enforce कर सकता है कि agent assigned scope से बाहर कोई project चुन सके या नहीं। यदि endpoint account चुनने के लिए query parameter इस्तेमाल करता है, तो उस parameter को भी validate करें। सही hostname होने से `/v1/accounts/other-team/export` स्वीकार्य नहीं हो जाता।

Body frozen request का हिस्सा होनी चाहिए। यदि validator JSON object approve करता है और कोई दूसरी layer उसे serialize या mutate कर देती है, तो संभव है कि machine से निकले bytes authorize ही न हुए हों। Duplicate JSON keys, form encoding, multipart boundaries, floating-point conversion और fields जोड़ने वाले middleware में यह समस्या दिखाई देती है।

एक practical design validator से immutable execution plan बनवाता है:

```json
{
  "method": "POST",
  "url": "https://api.billing.example/v1/invoices/inv_123/cancel",
  "headers": {
    "content-type": "application/json",
    "idempotency-key": "job-7f3c"
  },
  "body_sha256": "4d94c2...",
  "credential_ref": "billing-cancel"
}
```

Transport को plan और prepared body bytes मिलें। Authenticated request खोलने से पहले वह body digest की पुष्टि करे। URL से routing headers बनाए, `credential_ref` से secret जोड़े और ठीक उन्हीं bytes को भेजे। Digest अलग हो तो यह अनुमान लगाने के बजाय operation विफल हो कि किस stage ने request बदली।

इस approach से human approval भी बेहतर होता है। Approval card में plain-language action के साथ canonical origin, method, route, चुना हुआ account identifier और amount या resource name दिखाया जा सकता है। Raw JSON blob approve करने को न कहें, जिसमें dangerous field अंत के पास छिपी हो।

## General policy language से छोटा validator अधिक सुरक्षित है

आम instinct एक broad rules engine बनाने का होता है: arbitrary conditions, regular expressions, variables, exceptions और emergency bypass। यह flexible लगता है, जब तक किसी को यह तय न करना पड़े कि credential proxy header और agent द्वारा assembled JSON body वाली redirect target तक पहुंच सकती है या नहीं।

अधिकतर credential injection के लिए छोटा model पर्याप्त है। हर credential का स्पष्ट channel और compact request contract होना चाहिए। HTTP के लिए contract accepted origins, methods, routes, permitted headers, redirect behavior और body constraints बताए। SSH के लिए hosts, users, host key expectations, permitted command forms और transfer constraints बताए।

Compact configuration इस तरह दिख सकती है:

```yaml
credential: billing-cancel
channel: https
origins:
  - https://api.billing.example:443
methods: [POST]
routes:
  - /v1/invoices/{invoice_id}/cancel
headers:
  content-type: application/json
  idempotency-key: generated
redirects: deny
body:
  required_fields: [reason]
  allowed_fields: [reason]
```

यह fragment complete security system नहीं है। यह एक महत्वपूर्ण constraint दिखाता है: credential action के narrow shape से बंधी है। अगली integration को `GET /v1/invoices/{invoice_id}` चाहिए तो अलग route दें और संभव हो तो अलग read-only credential भी दें। Cancellation credential को चुपचाप general account key न बनाएं।

Regular expressions पर संदेह रखें। Carefully defined grammar वाले एक field के लिए वे उपयोगी हो सकते हैं, लेकिन URLs, JSON, shell commands या HTTP headers को parse करने का विकल्प नहीं हैं। Path को restrict करने वाली expression decoding, normalization या downstream router के उसी bytes को अलग तरह से interpret करने पर विफल हो सकती है।

Sallyport agent actions के लिए जानबूझकर छोटा रास्ता अपनाता है: secrets encrypted vault में रखता है और agent को secrets दिखाए बिना HTTP या SSH actions चलाता है। यह separation तभी उपयोगी है जब action gateway vault से credential इस्तेमाल करने को कहने से पहले action validate करे।

## Validation को transport तक handoff में सुरक्षित रखें

Perfect validator भी बेकार है यदि बाद की कोई layer destination बदल सकती है। Boundary में ऐसा handoff होना चाहिए जो approved चीजों को सुरक्षित रखे।

Mutable request object को validate करके उसी object को ऐसे middleware को न दें जो URLs rewrite कर सके, headers merge कर सके, cookies जोड़ सके, redirects follow कर सके या agent-controlled environment variables से proxy चुन सके। नए immutable plan में validate करें। Transport को उतना ही कम expressive input दें जितना संभव हो।

Execution order निश्चित और नीरस होना चाहिए:

1. Agent के proposed action को typed fields में parse करें।
2. Canonical destination और allowed request shape validate करें।
3. Approved payload को एक बार serialize करके उसका digest record करें।
4. Approved scheme, host और port का उपयोग करके connection बनाएं।
5. Transmission से ठीक पहले trusted transport में credential inject करें।

Retry code आसान बनाने के लिए पहले credential inject न करें। Retry एक और transmission है और उसे वही destination तथा request checks चाहिए। जब कुछ material नहीं बदला हो, तो approved immutable plan दोबारा इस्तेमाल किया जा सकता है। Retry host, route, proxy mode, method, body या authentication scheme बदले तो वह नया action है।

Connection reuse तभी सुरक्षित है जब HTTP library authority boundaries बनाए रखे। Pooled connection को एक request का authorization metadata अगली request में नहीं जाने देना चाहिए। यह स्पष्ट लगता है, लेकिन shared mutable header maps और poorly scoped interceptors इस तरह के bug का आम स्रोत हैं।

SSH में equivalent failure यह है कि hostname validate किया जाए, लेकिन approval के बाद command wrapper को अलग `ProxyCommand`, agent socket, destination jump host या remote command pass करने दिया जाए। Trust decision को पूरी route और execution request से bind होना चाहिए, केवल agent को दिखाई देने वाले पहले hostname से नहीं।

## उन failures को test करें जिन्हें सामान्य integration tests छोड़ देते हैं

Credential injector के tests यह साबित करें कि वह suspicious input को अस्वीकार करता है। Happy-path tests बताते हैं कि API call काम करती है। Refusal tests बताते हैं कि library upgrade या agent feature के बाद भी design वही अर्थ रखता है या नहीं।

Proposed actions और expected decisions की table बनाएं। कम से कम ये cases शामिल करें:

- Exact approved HTTPS origin और route, जो सफल हो।
- `api.billing.example.attacker.invalid` जैसा hostname suffix, जो विफल हो।
- `@` से पहले userinfo वाला URL, जो विफल हो।
- Unexpected port वाला valid host, जो विफल हो।
- Different origin पर redirect, जो credential भेजे बिना विफल हो।
- Unexpected `Host`, `Authorization` या proxy header, जो विफल हो।
- Approval के बाद बदली हुई body, जो digest check विफल करे।

ऐसा local test server इस्तेमाल करें जो प्राप्त हुए हर request header को record करे। यह mocked request object जांचने से अधिक convincing है। Test assert करे कि unapproved redirect target के server ने कोई API key, bearer token, cookies या signature header नहीं देखा। उन redirect response codes को भी test करें जो body बनाए रखते हैं और जिन्हें libraries अक्सर GET में बदल देती हैं, क्योंकि library defaults अलग होते हैं।

Parser disagreement भी test करें। Validator और production HTTP client को समान unusual URLs दें, जिनमें percent encoding, empty ports, duplicate slashes, dot segments, supported होने पर IPv6 literals और supported होने पर internationalized names शामिल हों। यदि authority या path पर दोनों असहमत हों, तो उस category को तब तक reject करें जब तक behavior consistent न हो।

Audit records में network call से पहले validator का decision और उसके बाद transport result capture होना चाहिए। Useful record में requested credential reference, approved canonical origin और route, redirect आया या नहीं और request deny होने का कारण शामिल हो। इसमें secret material कभी न हो। यदि आप यह reconstruct नहीं कर सकते कि outbound credential क्यों इस्तेमाल हुई, तो incident review के लिए आपके पास पर्याप्त evidence नहीं है।

## Approval तभी उपयोगी है जब request concrete हो

Human approval prompt agent को गलत समय पर credential इस्तेमाल करने से रोक सकता है, लेकिन prompt को ऐसी request बतानी चाहिए जिसे system पहले ही validate कर चुका हो। पहले approval मांगना और बाद में parse करना व्यक्ति को weak URL parser बना देता है।

Origin, action, method, route और महत्वपूर्ण business fields दिखाएं। Payment call के लिए recipient, currency और amount दिखाएं। Source control के लिए repository, branch और operation दिखाएं। Infrastructure API के लिए account, region, resource और destructive effect दिखाएं। Raw secrets और unbounded request bodies को prompt से बाहर रखें।

Material harm कर सकने वाली credentials के लिए per-call approval उचित है। Short lifetime और recognizable process identity वाले session में बार-बार होने वाली low-risk calls के लिए session approval काम कर सकता है। इनमें से कोई भी request validation का विकल्प नहीं है। User किसी trusted coding process को approve कर सकता है, लेकिन इससे उस process द्वारा बनाए गए हर URL को वही credential नहीं मिल जाती।

Sallyport का per-session authorization और optional per-call key approvals इसी boundary के बाद उपयोगी हैं: app व्यक्ति से किसी known agent process या particular credential use को authorize करने के लिए कह सकता है, जबकि trusted action path secret को अपने पास रखता है और action record करता है। Approval concrete, validated execution plan को cover करना चाहिए, agent के intent के informal description को नहीं।

पहला बदलाव आम तौर पर कोई बड़ा policy project नहीं होता। Authenticated calls के लिए automatic redirects बंद करें। Agent-owned routing और credential headers अस्वीकार करें। Destination को canonical origin में parse करें। फिर किसी secret के request में प्रवेश करने से पहले method, route, headers और body को bind करें। यह क्रम उन leaks की पूरी family को रोकता है जिन्हें सावधानी से किया गया secret storage भी बाद में ठीक नहीं कर सकता।
