# सुरक्षित production access के लिए अलग SSH क्रेडेंशियल

एक ही SSH क्रेडेंशियल development, staging और production तक पहुंचता हो, तो छोटी-सी सुविधा व्यापक रिमोट अधिकार में बदल जाती है। इससे approvals भी दिखावटी हो जाते हैं: कोई व्यक्ति सामान्य दिखने वाले staging काम को मंजूरी दे सकता है, जबकि वही क्रेडेंशियल कुछ मिनट बाद production session खोल सकता है।

SSH क्रेडेंशियल को सिस्टम की श्रेणी और जोखिम के हिसाब से अलग करें। फिर इस विभाजन को क्लाइंट कॉन्फ़िगरेशन में स्पष्ट करें, सर्वर पर लागू करें और जिन रास्तों को अनुमति नहीं है, उनकी जांच भी उतनी ही गंभीरता से करें जितनी अनुमति वाले रास्तों की। मैंने टीमों को इसे access control कहते देखा है, जबकि उन्होंने `~/.ssh/config` में एक ही कुंजी के तीन नाम रखे होते हैं। यह सीमा नहीं है।

## एक क्रेडेंशियल एक विफलता क्षेत्र बनाता है

अलग-अलग वातावरणों में साझा क्रेडेंशियल रखने पर हर धारक को उन सभी वातावरणों के संयुक्त अधिकार मिल जाते हैं। अगर किसी इंजीनियर का workstation, कोई automated task या approval path इसका इस्तेमाल कर सकता है, तो उस एक रास्ते के compromise होने पर public key स्वीकार करने वाला सबसे ऊंचा वातावरण भी पहुंच में आ जाता है।

आम बचाव यह होता है कि वही लोग हर वातावरण का प्रशासन करते हैं। बात यह नहीं है। लोग एक जैसे हो सकते हैं, लेकिन परिस्थितियां अलग होती हैं। Development के काम में बिना समीक्षा वाली scripts, test data, अस्थायी मशीनें और खुले प्रयोग शामिल हो सकते हैं। Production के काम में स्वीकार्य प्रक्रियाओं का दायरा छोटा, समीक्षा अधिक सावधान और यह रिकॉर्ड स्पष्ट होना चाहिए कि किसने और क्यों कनेक्ट किया।

इसीलिए अलग host aliases वाला एक ही क्रेडेंशियल कुछ उपयोगी नहीं करता। ये entries व्यवस्थित दिखती हैं:

```sshconfig
Host dev-db
  HostName dev-db.internal

Host prod-db
  HostName prod-db.internal
```

लेकिन अगर दोनों hosts एक ही SSH public key स्वीकार करते हैं, तो कोई भी alias उसी private key से authenticate कर सकता है। Automation variable में टाइपो या कॉपी किया गया command बिना किसी नए authorization decision के सीमा पार कर सकता है।

अलग क्रेडेंशियल परिणाम बदलते हैं। चोरी हुआ development क्रेडेंशियल staging और production पर विफल होना चाहिए। Staging क्रेडेंशियल इस्तेमाल करने के लिए स्वीकृत process के पास ऐसा private material या signing capability नहीं होना चाहिए जिससे वह production पर authenticate कर सके। ये दो अलग controls हैं। पहला breach का दायरा सीमित करता है। दूसरा किसी वैध लेकिन जरूरत से ज्यादा अधिकार वाले process को गलत काम करने से रोकता है।

इसे password rotation न समझें। Rotation समय के साथ क्रेडेंशियल बदलता है। Segregation तय करता है कि क्रेडेंशियल काम ही कहां कर सकता है। आपको दोनों चाहिए, लेकिन rotation ऐसे क्रेडेंशियल को ठीक नहीं कर सकता जिसे जानबूझकर हर जगह स्वीकार किया गया हो।

## केवल वातावरण के नाम पर्याप्त सीमाएं नहीं हैं

Development, staging और production तभी उपयोगी labels हैं जब वे अलग trust decisions से जुड़े हों। `staging` नाम वाला host production जैसा data रख सकता है, असली email भेज सकता है, signing secret रख सकता है या live payment endpoint से जुड़ सकता है। दूसरी ओर, production monitoring host को staging database administrator से कम अधिकार की जरूरत हो सकती है।

SSH एक्सेस को hostname prefix से नहीं, session के प्रभाव से वर्गीकृत करें। मैं आम तौर पर चार सवालों से शुरुआत करता हूं:

- क्या यह account customer या regulated data पढ़ सकता है?
- क्या यह live service, deployment, firewall या DNS record बदल सकता है?
- क्या यह कोई दूसरा क्रेडेंशियल प्राप्त कर सकता है या किसी दूसरी service का रूप ले सकता है?
- क्या यह अधिक अधिकार वाले systems तक पहुंच बना सकता है?

अगर hosts के बीच उत्तर बदलता है, तो क्रेडेंशियल का दायरा भी बदलना चाहिए। इससे अक्सर परिचित तीन-environment model से अधिक उपयोगी groups मिलते हैं: application development, sensitive data वाले test systems, release hosts, production read-only diagnosis और production administration।

अलग Unix account भी इस design का हिस्सा होना चाहिए। `deploy` नाम का account release directory का owner हो सकता है और restricted command स्वीकार कर सकता है। `ops-read` नाम का account service units बदले बिना logs देख सकता है। `admin` account ऊंचे approval standard के तहत maintenance कर सकता है। अलग accounts सर्वर को permissions जोड़ने की जगह देते हैं और logs में स्पष्ट subject दिखाते हैं।

अलग account names देखकर एक साझा क्रेडेंशियल स्वीकार न करें। अगर अलग-अलग machines पर `dev`, `deploy` और `admin` के नीचे वही public key है, तो private key अब भी cross-environment क्रेडेंशियल है। अलग accounts और अलग क्रेडेंशियल समस्या के अलग हिस्से हल करते हैं।

## हर व्यक्ति और process को अपनी पहचान दें

हर human operator और हर automation process को अपने अनुमत environment class के भीतर अलग SSH identity चाहिए। Team-wide private key incident response को धीमा करती है, क्योंकि एक व्यक्ति का access रद्द करने के लिए सभी के लिए उसे बदलना पड़ता है। जब कई लोग एक ही account और public key से authenticate करते हैं, तो logs भी लगभग बेकार हो जाते हैं।

Human operator के लिए अनुमत scopes के अनुसार अलग private keys बनाएं। ऐसे नाम रखें जो scope बताएं, न कि `id_ed25519_new` या `server-key-final` जैसे अस्पष्ट नाम।

```sh
mkdir -p ~/.ssh/identities
chmod 700 ~/.ssh/identities

ssh-keygen -t ed25519 \\
  -f ~/.ssh/identities/id_ed25519_dev_alex \\
  -C dev-alex

ssh-keygen -t ed25519 \\
  -f ~/.ssh/identities/id_ed25519_stage_alex \\
  -C stage-alex

ssh-keygen -t ed25519 \\
  -f ~/.ssh/identities/id_ed25519_prod_alex \\
  -C prod-alex
```

Comment लोगों को public-key list देखने में मदद करता है, लेकिन वह किसी चीज़ को लागू नहीं करता। Server public key, account और authorization rules के आधार पर access तय करता है। Comments को operators के लिए labels मानें, security metadata नहीं।

Automation के साथ भी यही अनुशासन रखें। Release job को उस job और environment के लिए जारी किया गया क्रेडेंशियल इस्तेमाल करना चाहिए, न कि किसी engineer की production identity को secret store में कॉपी करना चाहिए। अगर कई jobs को access चाहिए, तो उन्हें अलग identities दें, जब तक उनका owner, target set और command authority एक जैसी न हो। Incident review में क्रेडेंशियल को एक सरल सवाल का जवाब देना चाहिए: इसका इस्तेमाल किस process ने किया?

Hardware-backed credentials private key file की चोरी को कठिन बना सकते हैं, लेकिन वे व्यापक authorization design को ठीक नहीं करते। सभी environments में स्वीकार किया गया hardware-backed क्रेडेंशियल अब भी सभी environments तक पहुंच देता है। पहले scope तय करें, फिर हर private key की सुरक्षा का तरीका चुनें।

## Client configuration को identity spillover रोकना चाहिए

OpenSSH configuration से identities आजमाएगा और, जब तक उसे सीमित न किया जाए, SSH agent द्वारा दी गई identities भी आजमाएगा। यह सुविधा तब समस्या बनती है जब agent में production identity हो और staging के लिए बनाया गया connection उसी से सफल हो जाए।

OpenSSH की `ssh_config` manual में `IdentitiesOnly` को ऐसा control बताया गया है जो public-key authentication के लिए इस्तेमाल होने वाली identities को configured identity files और certificates तक सीमित करता है, भले ही agent में दूसरी identities हों। इसे हर scoped host alias के लिए सेट करें। हर alias को एक स्पष्ट identity file दें और agent द्वारा keys पेश किए जाने के क्रम पर निर्भर न रहें।

```sshconfig
Host dev-*
  User devops
  IdentityFile ~/.ssh/identities/id_ed25519_dev_alex
  IdentitiesOnly yes
  ForwardAgent no

Host stage-*
  User release
  IdentityFile ~/.ssh/identities/id_ed25519_stage_alex
  IdentitiesOnly yes
  ForwardAgent no

Host prod-*
  User admin
  IdentityFile ~/.ssh/identities/id_ed25519_prod_alex
  IdentitiesOnly yes
  ForwardAgent no
```

ऐसे aliases रखें जिनसे terminal history में environment को नज़रअंदाज़ करना कठिन हो। उदाहरण के लिए, development और production दोनों में समान नाम वाला API host हो सकता है, इसलिए `prod-api-01`, `api-01` से बेहतर है। Target को `server` जैसे सामान्य alias के पीछे न छिपाएं।

देखें कि OpenSSH आखिरकार कौन सी configuration इस्तेमाल करेगा। इससे wildcard collisions, included files और भूली हुई global setting सामने आती हैं।

```sh
ssh -G prod-api-01 | grep -E '^(hostname|user|identityfile|identitiesonly|forwardagent) '
```

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

```text
hostname prod-api-01.internal
user admin
identitiesonly yes
forwardagent no
identityfile ~/.ssh/identities/id_ed25519_prod_alex
```

आपकी machine पर path अलग तरह से expand हो सकता है। महत्वपूर्ण यह है कि production alias केवल production identity पर resolve हो और `identitiesonly` में `yes` हो।

एक आम समस्या तब आती है जब कोई सुविधा के लिए `ssh-add` चलाता है। Agent में अब कई identities होती हैं। `IdentitiesOnly yes` के बिना client उन्हें host के सामने तब तक आजमाता है जब तक कोई काम न कर जाए। Server अक्सर authentication attempts की संख्या सीमित करते हैं, इसलिए इससे उलझन भरी विफलताएं हो सकती हैं। इससे भी बुरा यह है कि व्यापक क्रेडेंशियल चुपचाप connection सफल करा सकता है और operator को पता भी नहीं चलता कि उसने गलत scope इस्तेमाल किया।

## Server authorization को भी यही विभाजन लागू करना चाहिए

अलग private keys तभी काम करती हैं जब हर server matching public key स्वीकार करे और बाकी को अस्वीकार करे। Development public key को development hosts पर, staging public key को staging hosts पर और production public key को केवल उन जगहों पर रखें जहां production access चाहिए।

यह नियम स्पष्ट लगता है, फिर भी urgent setup के दौरान खराब तरीका आम है: कोई व्यक्ति पूरी `authorized_keys` file नए host पर कॉपी कर देता है। उसमें अक्सर वर्षों पुरानी identities, पूर्व contractors, deployment keys और एक सामान्य administrator key होती है। नया production host ऐसे access decisions अपना लेता है जिनकी किसी ने समीक्षा नहीं की।

हर account की authorization list उसके काम के आधार पर बनाएं। Deployment account के लिए noninteractive transfer या deploy operation के अनुकूल OpenSSH restrictions इस्तेमाल करें। OpenSSH की `authorized_keys` manual में `restrict` option दिया गया है, जो port forwarding, agent forwarding, X11 forwarding और PTY allocation बंद कर देता है, जब तक कोई दूसरा option उन्हें अनुमति न दे। Restricted deployment entry ऐसी दिख सकती है:

```text
restrict,from="198.51.100.0/24" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... prod-release-job
```

Example network को उस address range से बदलें जिसे आप वास्तव में नियंत्रित करते हैं। केवल strict दिखने के लिए `from=` न जोड़ें। अगर job बदलते addresses या hosted runner pool से आता है, तो गलत source restriction outage पैदा करेगी और दबाव में कोई व्यक्ति सारी restrictions हटाने को मजबूर हो सकता है।

Forced commands केवल सीमित और स्पष्ट automation के लिए इस्तेमाल करें। Forced command deployment credential को shell पाने से रोक सकता है, लेकिन यह maintenance contract भी बन जाता है। Command को input validate करना, paths सुरक्षित रूप से चुनना और request log करना चाहिए। Administrator account पर forced command लगाकर यह न मानें कि account सुरक्षित हो गया। लोगों को आखिरकार shell चाहिए होगी और वे कोई workaround ढूंढ लेंगे।

Human production administration के लिए जटिल `authorized_keys` options की तुलना में अलग account और अलग public key आम तौर पर अधिक स्पष्ट होते हैं। सामान्य host permissions से account सीमित करें, जहां लागू हो वहां उसकी sudo activity रिकॉर्ड करें और व्यक्ति को access की जरूरत न रहने पर public key हटा दें।

## SSH certificates तभी मदद करते हैं जब उनके claims सीमित रहें

OpenSSH certificates short-lived access जारी करना और operational रूप से रद्द करना आसान बना सकते हैं। Certificate authority किसी user की public key पर हस्ताक्षर करती है और servers हर individual public key रखने के बजाय authority पर भरोसा करते हैं। इससे बड़े fleets में updates का काम घट सकता है।

वे authorities को अलग रखने की जरूरत खत्म नहीं करते। Production principal वाला certificate केवल इसलिए development और staging access भी न दे कि एक operator तीनों environments में काम करता है। अलग certificates जारी करें, अलग principals इस्तेमाल करें या जहां administration और risk boundaries इसकी मांग करें वहां अलग certificate authorities रखें।

OpenSSH certificate protocol user certificates, principals, validity intervals और critical options में अंतर करता है। यह structure तभी उपयोगी है जब server principals जांचे और issuance rules सीमित रखे जाएं। हर account और हर host के लिए valid certificate private key को expiry date वाली व्यापक trusted bearer identity में बदल देता है।

छोटी certificate lifetimes खोए devices और नौकरी छोड़ चुके staff के मामले में मदद करती हैं, लेकिन active incident में revocation का विकल्प नहीं हैं। Compromised identity की acceptance रोकने या उसका authorization तुरंत हटाने का तरीका फिर भी चाहिए। Certificate जारी करने से पहले इस mechanism की योजना बनाएं और वास्तविक host पर इसकी जांच करें।

Certificates agent misuse भी नहीं रोकते। अगर automated process जब चाहे production certificate प्राप्त कर सकता है, तो वही issuance service production boundary है। उसकी सुरक्षा उसी सावधानी से करें जैसे production private key की करते।

## Agent forwarding ऐसी सीमा पार करता है जिसे आप देख नहीं सकते

SSH agent forwarding किसी remote host को आपके local agent से दूसरे hosts के लिए authentication challenges sign करने देता है। Remote machine को private key नहीं मिलती, लेकिन session खुला रहने तक remote account के तहत चलने वाला process forwarded agent का इस्तेमाल कर सकता है।

इससे production session के लिए forwarding खास तौर पर खतरनाक हो जाती है, जब connection पहले jump host पर पहुंचता है। Jump host compromise हो जाए या उस account के तहत कोई untrusted process चले, तो वह forwarded agent द्वारा दी गई हर identity से signatures मांग सकता है। इससे lateral access मिल सकता है जिसका आपकी मूल connection योजना में कहीं उल्लेख नहीं था।

Client configuration में इसे default रखें:

```sshconfig
Host *
  ForwardAgent no
```

इसके बाद केवल वहां एक स्पष्ट exception बनाएं जहां maintained workflow को सचमुच इसकी जरूरत हो। Exception जोड़ने से पहले पूछें कि क्या ProxyJump, dedicated bastion credential या local operation से इसकी जरूरत खत्म हो सकती है। ProxyJump SSH connection को intermediate host से होकर ले जाता है; यह आपके local agent को उस host के सामने उसी तरह उजागर नहीं करता।

यह मत मानें कि forwarding सुरक्षित है क्योंकि private key laptop पर ही रहती है। कहीं और authenticate करने के लिए signing oracle पर्याप्त हो सकता है। Compromise के दौरान फर्क महत्वपूर्ण है: file की सुरक्षा और credential का इस्तेमाल कौन कर सकता है, इन दोनों को सीमित करना एक बात नहीं है।

## Approval scope को credential scope से मेल खाना चाहिए

जब कोई approval किसी नए process को SSH credential इस्तेमाल करने की अनुमति दे, तो उसमें credential का environment और अनुरोध करने वाला process स्पष्ट होना चाहिए। केवल `ssh command requested` लिखा prompt इंसान से बहुत कम जानकारी में बहुत कुछ समझने को कहता है।

यहीं teams अक्सर दो controls को मिला देती हैं। Credential scope बताता है कि identity कहां authenticate कर सकती है। Approval scope बताता है कि कौन सा running process उस identity का इस्तेमाल कर सकता है। आपको दोनों चाहिए। अलग production credentials development process को गलती से production तक पहुंचने से रोकते हैं; process approval किसी अज्ञात local process को उपलब्ध production credential इस्तेमाल करने से रोकता है।

Per-command approval अधिक सुरक्षित लग सकता है और असहज incident के बाद लोग अक्सर इसे मांगते हैं। Routine maintenance में यह आम तौर पर विफल होता है, क्योंकि बार-बार आने वाले prompts operators को बिना पढ़े approve करना सिखाते हैं। Per-use confirmation उन credentials के लिए रखें जिनका इस्तेमाल अपने-आप में human decision मांगता है, जैसे high-impact production administration identity। सामान्य काम के लिए ऐसा session authorization दें जो process समाप्त होते ही खत्म हो जाए, और server-side credential scope सीमित रखें।

Sallyport SSH credentials को अपने encrypted vault में रखता है और नए agent process के लिए authorization या चुने हुए credential के हर use पर approval मांग सकता है। यह अलग server authorization की जगह नहीं लेता, लेकिन credential agent को सौंपे बिना process boundary स्पष्ट करता है।

AI coding agent को interactive terminal से अधिक कड़े separation की जरूरत होती है, क्योंकि वह बहुत तेजी से कई commands चला सकता है और गलत instruction का पालन कर सकता है। Default रूप से उसे development access दें। अगर staging की जरूरत हो, तो staging-only identity और अलग approved run इस्तेमाल करें। Production access को named target और सीमित उद्देश्य वाली अलग operation मानें।

## विफलता अक्सर एक मामूली exception से शुरू होती है

एक ऐसी team पर विचार करें जिसके पास एक `ops` SSH key है और development, staging तथा production hosts उसे स्वीकार करते हैं। एक engineer production maintenance window के लिए यह key SSH agent में load करता है। बाद में local build helper logs लेने के लिए staging host से SSH connection खोलता है।

Helper में कोई explicit `IdentityFile` setting नहीं है और `IdentitiesOnly` भी अनुपस्थित है। OpenSSH agent से identities आजमाता है। Shared `ops` key सफल हो जाती है क्योंकि staging उसे स्वीकार करता है। अब helper के पास ऐसी identity से authenticated staging session है जो production पर भी काम करती है।

दूसरी गलती होती है। Staging host पर agent forwarding enabled है, क्योंकि किसी को पिछले महीने one-off connection के लिए इसकी जरूरत थी। उस host का कोई process forwarded agent के ज़रिए signatures मांग सकता है। वही `ops` identity लेकर वह production host तक पहुंच जाता है। मूल engineer ने production maintenance session को approve किया था, लेकिन असंबंधित helper और staging host को उसका अधिकार मिल गया।

इस क्रम में किसी exploit को leaked private key की जरूरत नहीं है। Design ने व्यापक identity की अनुमति दी, client ने उसे अपने-आप चुना और forwarding ने उसका दायरा बढ़ा दिया। Logs में पूरी प्रक्रिया valid authentication जैसी दिख सकती है। इसी कारण teams access model ठीक करने के बजाय इसे user error कह देती हैं।

Split design इस chain को कई जगह तोड़ता है। Helper केवल staging credential इस्तेमाल करता है। Production उसे अस्वीकार करता है। Agent forwarding बंद रहती है। Production identity केवल स्पष्ट रूप से approved production process को उपलब्ध होती है। इनमें से कोई भी control मदद करता है; साथ मिलकर वे गलत connection को शुरुआत में ही विफल कर देते हैं।

## Rotation और emergency revocation के लिए अभ्यास किया हुआ क्रम चाहिए

Rotation तब काम करता है जब आप पुरानी identity हटाने से पहले replacement जोड़ते हैं, सही route की पुष्टि करते हैं और फिर पुरानी identity रद्द करते हैं। Production rotation तब विफल होती है जब कोई केवल अपने laptop से test करता है, जबकि असली deployer किसी दूसरे account, network या automation runner से connect करता है।

सामान्य rotation के लिए यह क्रम अपनाएं:

1. पुरानी identity के समान सीमित scope में replacement credential बनाएं।
2. Intended account और hosts में उसकी public key या certificate authorization जोड़ें।
3. वास्तविक process path से वास्तविक command test करें, जिसमें कोई jump host हो तो वह भी शामिल हो।
4. पुराना authorization हटाएं और पुष्टि करें कि पुराना credential अब विफल होता है।
5. Access record में replacement fingerprint, owner, scope और removal date दर्ज करें।

Break-glass path रखें, लेकिन उसे हर workstation पर कॉपी किया गया दूसरा स्थायी administrator credential न बनाएं। उसे अलग रखें, यह सीमित करें कि कौन उसे activate कर सकता है और नियंत्रित परिस्थितियों में उसकी जांच करें। जिस break-glass process का किसी ने अभ्यास नहीं किया, वह outage के दौरान घबराहट में अनुमान लगाने का अभ्यास बन जाता है।

Emergency revocation अलग है। अगर production credential के उजागर होने की संभावना हो, तो तुरंत उसकी public key हटाएं या उसके certificate को स्वीकार करना बंद करें, फिर उसे बदलें। Scheduled rotation window का इंतजार न करें, क्योंकि attacker आपके calendar का पालन नहीं करेगा। इसमें operational disruption का tradeoff है, इसलिए सीमित credentials उपयोगी हैं: production deployment identity रद्द करने से development work रुकना नहीं चाहिए।

## Denied access की जांच करें और evidence पढ़ें

Access separation तभी पूरा होता है जब गलत credential ऐसी तरह विफल हो जिसे आप समझा सकें। हर महत्वपूर्ण बदलाव के बाद जानबूझकर negative case test करें: development identity से production host पर जाएं और पुष्टि करें कि public-key authentication विफल होता है। फिर अपेक्षित credential test करें और connection record में account name और target देखें।

Testing के दौरान verbose client output इस्तेमाल करें, स्थायी आदत के रूप में नहीं:

```sh
ssh -vvv -o IdentitiesOnly=yes \\
  -i ~/.ssh/identities/id_ed25519_dev_alex \\
  admin@prod-api-01.internal
```

आपको client को development public key offer करते और server को उसे अस्वीकार करते देखना चाहिए। इस output को tickets में paste करने से पहले जांच लें, क्योंकि verbose SSH logs hostnames, usernames और authentication details उजागर कर सकते हैं।

Server logs से आपको यह पता चलना चाहिए कि किसने authenticate किया, किस account का इस्तेमाल किया, server ने कौन सा public-key fingerprint स्वीकार किया और connection कहां से शुरू हुआ। अगर कई लोग या processes एक identity साझा करते हैं, तो log बाद में वह missing attribution वापस नहीं ला सकता।

Boundary drift की समीक्षा करें: production account में जोड़ी गई development key, अब भी स्वीकार किया जा रहा पुराना deployment credential, सामान्य-purpose agent में load की गई production key या `IdentitiesOnly` को override करने वाला wildcard client rule। ये बदलाव अक्सर temporary fixes के रूप में आते हैं। Temporary SSH access उस emergency के बहुत बाद तक बचा रहता है जिसने उसे बनाया था।

शुरुआत production hosts पर स्वीकार की गई हर public key की inventory बनाकर करें और हर key को owner, process, purpose और scope के अनुसार label करें। जो entry इस चार-भाग वाले विवरण पर खरी नहीं उतरती, उसे authorized नहीं रहना चाहिए।
