# TLS सर्टिफिकेट रोटेशन के लिए दोतरफा प्रमाण जरूरी है

सर्टिफिकेट अथॉरिटी ठीक वही सर्टिफिकेट जारी कर सकती है जो AI एजेंट ने माँगा था, जबकि सेवा पुराना सर्टिफिकेट दिखाती रहे। मैंने ऐसे रोटेशन जॉब देखे हैं जिन्होंने डाउनलोड हुई PEM फाइल, अपडेट हुए सीक्रेट या सफल reload कमांड को जीत मान लिया, फिर सबसे खराब समय पर पता चला कि एक listener कभी बदला ही नहीं। **सफल issuance और सफल deployment दो अलग दावे हैं, इसलिए उनके प्रमाण भी अलग होने चाहिए।**

भरोसेमंद रोटेशन यह दर्ज करता है कि CA ने क्या जारी किया, उसी artifact को deploy करता है और नया TLS connection खोलकर देखता है कि client को वास्तव में क्या मिला। अंतिम तुलना में सर्टिफिकेट की स्थिर पहचान, अपेक्षित hostname और असली network path शामिल होने चाहिए। एजेंट जब तक तुलना के दोनों पक्ष नहीं दिखा सकता, बदलाव अभी जारी है।

## पूरा होने के लिए स्पष्ट प्रमाण अनुबंध चाहिए

रोटेशन तभी पूरा है जब जारी सर्टिफिकेट का रिकॉर्ड deployment scope के हर endpoint की reading से मेल खाए। एजेंट को credentials या commands देने से पहले यह नियम लिखें। वरना एजेंट उसी चीज को लक्ष्य बनाएगा जिसे उसका tool success बताता है, भले वह केवल file write हो और client को दिखने वाला बदलाव न हो।

Issuance रिकॉर्ड में order या request ID, माँगे गए DNS names, serial number, SHA-256 fingerprint, validity period, issuer और public key digest होना चाहिए। यह भी दर्ज हो कि पूरी chain और private key कहाँ रखी गई, लेकिन key को log में copy न करें। Fingerprint पूरे leaf certificate को पहचानता है; public-key digest बताता है कि दोबारा जारी सर्टिफिकेट ने key रखी या बदली।

Deployment रिकॉर्ड अलग सवालों के जवाब देता है: artifact किस target को मिला, कौन सी configuration उसे reference करती है, किस process ने reload स्वीकार किया और यह कब हुआ। Control-plane API का सफल response यहाँ दर्ज होगा, पर यह service का प्रमाण नहीं है। यह केवल बताता है कि बदलाव की कोशिश deployment system तक पहुँची।

Observation रिकॉर्ड deployment के बाद बनाए गए नए connection से आता है। इसमें माँगा गया hostname, resolve या force किया गया address, port, देखा गया serial और fingerprint, verification result, timestamp और verifier location चाहिए। Location जरूरी है, क्योंकि internal probe, external probe और corporate proxy के पीछे की probe अलग TLS termination points तक पहुँच सकती हैं।

Completion rule को मशीन से जाँचने योग्य रखें:

```text
complete = issuance.valid
        && deployment.accepted
        && every(expected_endpoint,
                 observation.chain_valid
                 && observation.name_valid
                 && observation.leaf_fingerprint == issuance.leaf_fingerprint)
```

इससे एक असहज स्थिति साफ दिखती है: सर्टिफिकेट मौजूद है और deployment स्वीकार हुआ, पर served fingerprint अभी अलग है। इसे `deployed_unverified` कहें, `complete` नहीं। सटीक state names dashboard या agent summary को दो अलग दावों को चुपचाप मिलाने से रोकते हैं।

## ACME issuance deployment साबित नहीं करता

ACME साबित करता है कि जरूरी authorization के बाद CA ने order स्वीकार करके सर्टिफिकेट जारी किया, लेकिन protocol यह साबित नहीं करता कि आपका application वही सर्टिफिकेट serve कर रहा है। RFC 8555 client के चार मुख्य कदम बताता है: order भेजना, identifiers पर control साबित करना, certificate signing request से order finalize करना, फिर issuance का इंतजार करके सर्टिफिकेट download करना। सीमा download पर खत्म हो जाती है।

यह सीमा आसानी से छूट जाती है, क्योंकि कई ACME clients renewal के बाद deploy hook चलाते हैं। Hook CA transaction के बाहर होता है। बदला file path, पुराने secret वाला container, गलत process को reload, asynchronous update स्वीकार करने वाला remote API या unreachable node इसे विफल कर सकते हैं। इन सभी failures के बावजूद order पूरी तरह valid रह सकता है।

अंतिम ACME order object या बराबर CA response दर्ज करें। ACME order में `status: valid` और भरा हुआ certificate URL issuance का प्रमाण हैं। Downloaded certificate को parse करके identifiers और returned leaf fingerprint लें। नई file का मौजूद होना artifact की पहचान न मानें; temporary files, symlinks और बार-बार इस्तेमाल हुए names कमजोर प्रमाण हैं।

Certificate Transparency भी यह कड़ी पूरी नहीं करता। Log entry दिखा सकती है कि किसी name के लिए public certificate जारी हुआ। वह नहीं बताती कि load balancer, ingress controller, web server या CDN अब वही certificate दिखा रहा है। CT स्वतंत्र issuance evidence है, deployment monitor नहीं।

यह अंतर error handling बदलता है। Issuance failure का अर्थ है कि agent को अपेक्षित credential मिला ही नहीं। Deployment failure का अर्थ है कि उसे sensitive credential मिल गया, शायद वह storage में भी है, पर service उसे serve नहीं कर रही। दूसरे मामले में अक्सर cleanup, retry या rollback चाहिए और उसका alert अलग होना चाहिए।

## Listener तक पहुँचने से पहले artifact जाँचें

Deployment से पहले पुष्टि करें कि leaf certificate में माँगे गए names, अपेक्षित validity, सही issuer और private key से मेल खाती public key है। यह gate production को छुए बिना malformed bundle और गलत file पकड़ता है। यह live probe की जगह नहीं लेता।

RFC 9525 identity rule साफ करता है: clients स्वीकार्य reference identifiers अलग से बनाते हैं और फिर certificate के identifiers से तुलना करते हैं। सामान्य DNS services में जरूरी names `subjectAltName` extension में होते हैं। RFC domain जैसे Common Name पर fallback को साफ मना करता है। केवल `subject=CN=...` जाँचने वाला agent ऐसा certificate मंजूर कर सकता है जिसे modern clients को reject करना चाहिए।

Leaf artifact को असली output fields के साथ देखें:

```bash
openssl x509 -in leaf.pem -noout \
  -serial -fingerprint -sha256 -dates -issuer -subject \
  -ext subjectAltName
```

सामान्य output इस तरह दिखता है:

```text
serial=03A17C...
sha256 Fingerprint=6B:19:8A:...
notBefore=Jul 24 08:15:00 2026 GMT
notAfter=Oct 22 08:14:59 2026 GMT
issuer=C=US, O=Example CA, CN=Example Issuing CA
subject=CN=api.example.net
X509v3 Subject Alternative Name:
    DNS:api.example.net, DNS:www.example.net
```

अगर आपकी OpenSSL version support करती है तो `openssl x509 -checkhost api.example.net -noout` को machine gate बनाएँ। OpenSSL में `-checkhost` खास तौर पर certificate को host से मिलाने के लिए है। Exit status पढ़ें, friendly output text नहीं, क्योंकि वह versions के बीच बदल सकता है।

Private material दिखाए बिना public keys की तुलना करें। ये commands दोनों तरफ DER-encoded public key का hash बनाती हैं; समान lines बताती हैं कि certificate और private key एक pair हैं:

```bash
openssl x509 -in leaf.pem -pubkey -noout \
  | openssl pkey -pubin -outform DER \
  | openssl dgst -sha256

openssl pkey -in private-key.pem -pubout -outform DER \
  | openssl dgst -sha256
```

`private-key.pem` की सामग्री, command tracing या key वाली environment variable कभी agent context में न रखें। सीमित executor तुलना करे और digest तथा exit status लौटाए। Agent को action का result चाहिए, उसे करने में लगा secret नहीं।

## सफल file write के बाद activation बाकी है

Deployment में दो operations हैं: नया material atomically रखना और TLS terminator से उसे load कराना। Agents अक्सर पहला करते हैं और मान लेते हैं कि दूसरा भी हो गया। लंबे समय तक चलने वाले servers parsed certificates memory में रखते हैं, इसलिए disk पर file बदलने से नए handshakes जरूरी नहीं बदलें।

Files को destination के पास stage करें, ownership और restrictive permissions लगाएँ, configuration validate करें, फिर rename करके जगह पर रखें। एक filesystem के भीतर rename अधलिखी PEM file को सामने आने से रोकता है। Live verification pass होने तक पिछली working files या versioned secret reference रखें; तुरंत cleanup सबसे तेज rollback मिटा देता है।

Activation terminator पर निर्भर है। nginx documentation के अनुसार HUP master को नई configuration validate करने, नए workers शुरू करने और पुराने workers को धीरे बंद करने देता है; apply विफल हो तो nginx पुरानी configuration पर चलता रहता है। यह availability के लिए अच्छा है, पर अगर agent केवल HUP भेजना दर्ज करे तो पूरा false positive बन जाता है। Apache graceful restart भी syntax जाँचता है और पुराने connections खत्म होने तक नई generation चलाता है। Managed load balancers और CDNs update स्वीकार करके उसे बाद में पूरा कर सकते हैं।

Activation command या API operation ID, exit status और target process identity दर्ज करें। फिर service-specific status या logs में acceptance देखें। Fixed sleep को proof न बनाएँ। 30-second pause कभी eventual consistency छिपाती है और कभी 29 seconds बर्बाद करती है; deadline तक documented state poll करना साफ है।

Activation failures को public verification retries से service पर load पड़ने से पहले workflow रोक देना चाहिए। Syntax validation fail हो, process identity अचानक बदले या control plane terminal error दे तो पुराना certificate बचाएँ और deployment failed दर्ज करें। Activation success के बाद live endpoint पुराना रहे तो bounded window में probe करते रहें, क्योंकि graceful replacement और distributed propagation में समय लगता है।

## Client को क्या मिलता है, उसके नाम समेत जाँचें

निर्णायक check नया TLS connection खोलता है, अपेक्षित Server Name Indication भेजता है, chain और hostname validate करता है और leaf certificate दर्ज करता है। Local file देखकर client की view नहीं मिलती। मौजूदा keep-alive connection reuse करना भी ठीक नहीं, क्योंकि TLS handshake पहले ही certificate चुन चुका है।

SNI और hostname verification के साथ OpenSSL चलाएँ:

```bash
openssl s_client \
  -connect api.example.net:443 \
  -servername api.example.net \
  -verify_hostname api.example.net \
  -verify_return_error \
  </dev/null 2>/dev/null \
| openssl x509 -noout -serial -fingerprint -sha256 -dates -issuer
```

`-servername` SNI control करता है, जो shared listeners पर virtual host चुनता है। `-verify_hostname` identity जाँचता है और `-verify_return_error` verification error पर command रोकता है। OpenSSL का `-showcerts` server की भेजी chain दिखाता है, लेकिन documentation बताती है कि यह server की list है, अपने आप verified chain नहीं।

Automation pass कराने के लिए `-k`, `--insecure` या वैसा flag न जोड़ें। curl manual कहता है कि सामान्य TLS request CA trust और hostname match दोनों जाँचती है। Insecure probe fingerprint confirm कर सकती है, पर वही broken chain या wrong name छोड़ सकती है जिससे users fail होंगे।

Fingerprint match भी अकेला काफी नहीं। Server अपेक्षित leaf के साथ incomplete intermediate chain दे सकता है, जिससे कुछ clients fail होंगे। Completion gate में valid trust path, valid name और expected leaf identity तीनों चाहिए। अगर revocation check या Certificate Transparency policy वास्तविक client profile का हिस्सा है तो वह profile भी चलाएँ; basic OpenSSL probe उसे cover नहीं करती।

हर observation साफ process में चलाएँ या connection reuse बंद करें। Failure पर stderr दर्ज करें, पर agent context में जाने से पहले sensitive data हटाएँ। Failure category साफ रखें: connection, handshake, trust path, identity या fingerprint mismatch।

## हर TLS termination point अलग target है

Hostname deployment scope नहीं है। Scope उन सभी जगहों का समूह है जो उस hostname के लिए TLS terminate कर सकती हैं: load-balancer addresses, CDN points, ingress replicas, regional front doors, IPv4 और IPv6 paths, तथा clients के लिए reachable origin listeners। एक passing connection केवल एक route और एक समय साबित करता है।

Expected endpoint inventory infrastructure state से बनाएँ, verifier को संयोग से मिले DNS answer से नहीं। Dynamic DNS और anycast exhaustive public sampling कठिन बनाते हैं, इसलिए defend किया जा सकने वाला set तय करें: control plane में हर configured listener या certificate attachment, साथ में महत्वपूर्ण client regions की probes। Vendor edge fleet संभालता हो तो vendor deployment status जाँचें और एक से अधिक locations से external sample लें।

Address-specific tests के लिए curl का `--resolve` URL में IP डालने से सुरक्षित है, क्योंकि वह SNI और certificate verification के लिए original hostname रखता है:

```bash
curl --fail --silent --show-error \
  --resolve api.example.net:443:192.0.2.18 \
  --output /dev/null \
  https://api.example.net/health
```

हर known address के लिए request दोहराएँ, support हो तो brackets में IPv6 भी। उसी address के विरुद्ध OpenSSL fingerprint probe चलाएँ और `-servername api.example.net` बनाए रखें। Successful HTTP status TLS से अधिक जाँचता है, इसलिए cheap और non-mutating endpoint चुनें; certificate observation ही rotation का completion evidence रहता है।

Proxies को साफ दर्ज करें। Developer laptop की probe corporate TLS inspection certificate देख सकती है। Cluster के भीतर की probe public CDN bypass कर सकती है। Verifier location और network path दर्ज करें, और issuer या fingerprint से intended termination point न पहुँचने का पता चले तो observation reject करें।

Rolling change के समय old और new fingerprints का mix सामान्य temporary state है, majority के आधार पर success कहने का बहाना नहीं। Scope के हर endpoint को converge करना होगा, या failed endpoint को स्पष्ट रूप से service से हटाना होगा।

## Agent से तुलना योग्य records निकलवाएँ

AI agent को structured evidence देना चाहिए जिसे दूसरा program prose समझे बिना compare कर सके। “Renewal सफल है और site ठीक दिखती है” जैसे summaries target identity, timestamps और mismatches मिटा देते हैं। Human explanation रखें, पर state transitions typed fields पर निर्भर हों।

छोटा event pair ऐसा हो सकता है:

```json
{"type":"certificate.issued","rotation_id":"rot_7f2","order_id":"ord_91c","dns_names":["api.example.net"],"serial_hex":"03A17C","leaf_sha256":"6B:19:8A:...","spki_sha256":"9f4c...","not_before":"2026-07-24T08:15:00Z","not_after":"2026-10-22T08:14:59Z"}
{"type":"certificate.observed","rotation_id":"rot_7f2","host":"api.example.net","address":"192.0.2.18","port":443,"leaf_sha256":"6B:19:8A:...","chain_valid":true,"name_valid":true,"observed_at":"2026-07-24T08:19:22Z","vantage":"external-us-east"}
```

Issuance, deployment attempts, observations, retries, rollback और closure में एक `rotation_id` रखें। CA order ID और infrastructure operation ID अलग fields हों। उन्हें generic job ID में मिलाना incident reconstruction कठिन बनाता है।

Retries की अपनी semantics चाहिए। CA order या control plane attachment स्वीकार होने के बाद agent response खो सकता है। Blind repeat extra certificates बना सकता है, rate limits trigger कर सकता है या competing deployments शुरू कर सकता है। हर mutating call को rotation ID और phase से निकला idempotency token दें, और replacement से पहले remote operation query करें। दर्ज करें कि response नई action है या existing action का replay।

Freshness का साफ rule भी चाहिए। Deployment से एक घंटा पहले pass हुई probe resulting state साबित नहीं करती, भले पिछली कोशिश में same fingerprint मिला हो। `observed_at` accepted activation के बाद होना चाहिए और closure पर maximum observation age तय हो। Trusted workflow clock या verifier timestamp लें, model-generated prose का समय नहीं।

Certificate identity और service identity अलग fields में रखें। Fingerprint पूछता है “क्या यह issued leaf है?”, hostname check पूछता है “क्या leaf requested service के लिए valid है?”, chain result पूछता है “क्या verifier acceptable trust path बना सकता है?” इन्हें `tls_ok` में मिलाने से evidence गायब होने के बाद test दोहराना पड़ता है।

Endpoint inventory की revision भी रखें। Rotation के बीच infrastructure listener जोड़ दे तो closure नई revision अपनाकर उसकी observation माँगे, या approved पुरानी revision से बँधकर follow-up बनाए। Moving list को चुपचाप पढ़ने से race बनती है। Closure result के साथ revision रखें ताकि reviewer जान सके कि “हर endpoint” का मतलब क्या था।

Evidence collection repeat करने में safe हो। Read-only routes, short connection timeouts और bounded concurrency रखें। Cache गर्म या session बदलने वाला health URL खराब probe है; TLS handshake HTTP request से पहले होता है, इसलिए minimal request या direct handshake काफी है। हजारों addresses हों तो target के हिसाब से schedule करें और केवल failures retry करें।

अंत में observation और interpretation अलग करें। Probe handshake से मिले bytes और verifier result report करे; comparator तय करे कि वह current rotation को satisfy करता है या नहीं। Comparator bug ठीक करके stored evidence replay किया जा सकता है, production को छुए बिना, और agent mismatch को reassuring summary में नहीं बदल सकता।

Comparator accepted deployment से पहले की observations, unexpected hostname या address और दूसरी rotation के evidence को reject करे। Display strings के बजाय normalized binary fingerprints compare करे, क्योंकि colons और letter case बदलते हैं। Original display value operators के लिए रखें।

Agent को evidence fields छोड़ने न दें। Workflow में schema तय करें और required evidence न हो तो fail closed करें। Signed events provenance मजबूत करते हैं, पर कमजोर statement नहीं सुधारते। पूरी तरह signed “command exited zero” भी नहीं बताता कि client को कौन सा certificate मिला।

Failed observations भी evidence के रूप में रखें। Wrong fingerprint, expired certificate या name mismatch बताता है कि job खुला क्यों रहा और slow propagation को bad attachment से अलग करता है। Failure को eventual success से overwrite करने पर audit trail outage window नहीं समझा पाता।

## आम failure split deployment है

यह चुपचाप शुरू होता है। Agent `api.example.net` के लिए नया certificate लेता है, ACME order valid दर्ज करता है, `api-tls` secret update करता है और orchestration API से success पाता है। फिर secret metadata में नया resource version देखकर ticket बंद कर देता है।

Public hostname दो load balancer addresses पर resolve होता है। एक controller production namespace के `api-tls` को देखता है और नया certificate load करता है। दूसरा listener legacy namespace के same-name secret को reference करता है। कोई API call fail नहीं हुई, क्योंकि agent ने असली object update किया, बस hostname control करने वाला हर object नहीं।

अधिकतर users पहले address पर जाकर नया certificate देखते हैं। छोटा traffic path अभी पुराना leaf serve करता है। Expiry पास आते ही failures intermittent लगते हैं और retry उन्हें ठीक करता दिखता है, क्योंकि DNS या load balancer अगला connection कहीं और भेज देता है। Operators cache को दोष देते हैं, जबकि TLS हर नए handshake में certificate चुनता है।

दोतरफा proof split को तुरंत दिखाता है। Issuance record में fingerprint `6B:19:8A:...` है। दो addresses की observations यह value और `41:D0:72:...` लौटाती हैं। Rotation `deployed_unverified` रहती है और mismatching observation ठीक किए जाने वाले address का नाम देती है।

“Browser में certificate देख लें” automation के लिए कमजोर सलाह है। Browser connections reuse कर सकता है, selected address छिपा सकता है, अलग trust store लगा सकता है या inspection के पीछे हो सकता है। Incident में independent spot check के लिए ठीक है, पर completion तय नहीं करना चाहिए। Address-pinned और hostname-verified probes repeatable evidence देती हैं।

Legacy attachment ठीक करने के बाद दोनों addresses को fresh connections से फिर probe करें। पहला mismatch, corrective deployment event और passing observations रखें। यह history साबित करती है कि क्या बदला और workflow आखिर क्यों बंद हुआ।

## Privileged actions को सीमित authority चाहिए

Certificate rotation agent को CA APIs, secret stores और production reload paths तक पहुँचाती है, इसलिए executor raw credentials के बजाय narrow actions दे। “यह CSR भेजें”, “fingerprint X artifact को listener Y से जोड़ें” या “address A से host H probe करें” उपयोगी सीमाएँ हैं। Model को reusable API token देने से risk बढ़ता है, reasoning नहीं सुधरती।

हर action result में remote operation ID और evidence fields हों, credentials और private-key bytes नहीं। Issuance, deployment, verification और rollback की authority अलग रखें। Certificate माँगने की अनुमति से उसे हर जगह attach करने की अनुमति अपने आप नहीं मिलनी चाहिए।

Sallyport API और SSH credentials को encrypted vault में रख सकता है, जबकि agent app के जरिए HTTP और SSH actions करता है, इसलिए credentials agent context में नहीं आते। उसके Activity और Sessions journals write-blind encrypted, hash-chained audit log से बनते हैं। वे issuance, deployment और verification calls का attribution देते हैं, लेकिन certificate observations की जगह नहीं लेते।

जहाँ impact बढ़े वहाँ human approval रखें। पहले से तय hostname और listener का routine renewal session authorization में हो सकता है, जबकि नया name, key change, wildcard या rollback per-call approval माँगता है। Approval displayed target और artifact fingerprint से बँधी हो; “certificate update allow करें” गलत listener पकड़ने के लिए बहुत vague है।

Verifier को deployer जितना ध्यान से audit करें। अगर वही unrestricted agent endpoint inventory बदल सकता है, deployment कर सकता है और अपने incomplete sample को पर्याप्त मान सकता है तो evidence contract केवल दिखावा है। Expected targets controlled source से निकालें और closure check missing observations reject करे।

## Convergence पर ही बंद करें और rollback तैयार रखें

Closure action immutable issuance, deployment और observation events पर deterministic comparison चलाए। Agent से न पूछे कि rotation “पूरी लगती है” या नहीं। जब सभी expected endpoints valid, name-matched chain से issued leaf दिखाएँ, exact predicate result दर्ज करके rotation बंद करें।

Propagation के लिए deadlines रखें, उसे छिपाएँ नहीं। Allowed window में केवल non-converged endpoints retry करें और bounded backoff रखें। Deadline पर mismatching targets के साथ rotation fail करें। Rollback validity और service health पर निर्भर है: काफी lifetime वाला old certificate अस्थायी रूप से सुरक्षित हो सकता है, expired या revoked old certificate forward repair माँगता है।

Rollback पर भी वही proof burden है। Previous artifact को फिर attach करना deployment attempt है; recovery कहने से पहले workflow को previous fingerprint live देखना होगा। Incident में private key compromised हुई हो तो compromised certificate पर लौटना recovery नहीं है; fresh key से issue करें और incident plan के अनुसार revoke करें।

Connection draining और rollback policy cleanup की अनुमति दें तब तक दोनों certificates रखें। Graceful reload पुराने workers को established connections serve करने दे सकता है, पर नई probes को new generation तक पहुँचना चाहिए। Secret system के controlled path से old private material delete करें और cleanup को post-completion action दर्ज करें, new certificate serve होने की शर्त नहीं।

पहला बदलाव छोटा पर सख्त है: “certificate downloaded” या “secret updated” को terminal success state से हटाएँ। एक तरफ issued fingerprint और दूसरी तरफ पूरे endpoint inventory से fresh, hostname-verified fingerprints माँगें। Agent हर कदम कर सकता है, लेकिन केवल matching evidence ही rotation को complete कह सकता है।
