8 मिनट पढ़ें

Timing side-channel tests में denial को भी result मानें

Timing side-channel tests agents को success, denial, missing credentials या invalid credentials के ज़रिए vault state का अनुमान लगाने से रोकने में मदद करते हैं।

Timing side-channel tests में denial को भी result मानें

किसी एजेंट को खतरनाक बात जानने के लिए secret value की ज़रूरत नहीं होती। अगर वह किसी action gateway को बार-बार call कर सकता है और duration के आधार पर outcomes को अलग कर सकता है, तो वह जान सकता है कि vault locked है या नहीं, credential name मौजूद है या नहीं, request authorization से गुज़री या नहीं, या gateway किसी remote service तक पहुंचा या नहीं।

इतनी जानकारी उसके व्यवहार को बदलने के लिए काफी है। जिस coding agent को पता चल जाए कि कोई credential मौजूद है, वह उस service के access के लिए बार-बार पूछ सकता है। Compromised agent इस result का इस्तेमाल reconnaissance के लिए कर सकता है। एक call में leak मामूली लग सकता है। लेकिन जब caller inputs नियंत्रित करता हो, requests दोहराता हो और clock को सटीकता से माप सकता हो, तब यह उपयोगी बन जाता है।

MITRE इस class को CWE-208, Observable Timing Discrepancy के रूप में दर्ज करता है। इसका विवरण जानबूझकर व्यापक है: जब operations में दिखने लायक अलग-अलग समय लगता है, तो security-relevant internal state बाहर निकल सकती है। आम उदाहरण password checking है। Agent gateway में यही समस्या कुछ अलग रूप में आती है: caller पहले से developer workflow के भीतर होता है और बिना थके कई structured tool calls कर सकता है।

इसका समाधान हर action को बिल्कुल समान समय में पूरा कराना नहीं है। यह वादा आम तौर पर गलत होता है, खासकर तब जब HTTP request या SSH connection मशीन से बाहर जाती हो। काम अधिक सीमित और व्यावहारिक है: उन states को पहचानें जिन्हें agent अलग-अलग न पहचान सके, उनके local handling को comparable बनाएं और ऐसी differential test suite रखें जो नए fast paths पकड़ सके।

Vault state को ऐसा data मानें जिसे caller को infer नहीं करना चाहिए

Locked vault, missing credential, denied action और bad remote credential अलग-अलग operational conditions हैं। इसका मतलब यह नहीं कि agent को इनके बारे में अलग-अलग facts जानने चाहिए।

सबसे पहले लिखें कि हर caller को क्या जानने की अनुमति है। यह स्पष्ट लगता है, लेकिन teams अक्सर इसे छोड़ देती हैं और implementation order को disclosure policy तय करने देती हैं। Early vault lookup credential existence उजागर करता है। Early authorization check बताता है कि process के पास approved session है या नहीं। Immediate local error बताता है कि vault locked है। हर shortcut अपने आप में उचित हो सकता है। साथ मिलकर वे caller को state probe दे देते हैं।

Action gateway के लिए इन सवालों को अलग रखें:

  • क्या यह process किसी action के लिए request कर सकता है?
  • क्या vault अभी उसे execute करने के लिए उपलब्ध है?
  • क्या इस action के लिए credential mapping मौजूद है?
  • क्या remote service ने credential स्वीकार किया?
  • क्या caller इनमें से किसी answer को सीधे देख सकता है, या उसे केवल action result मिलता है?

मुख्य अंतर authorization state और credential state के बीच है। Authorization बताता है कि कोई particular agent run action invoke कर सकता है या नहीं। Credential state बताता है कि gateway के पास उस action को execute करने के लिए material है या नहीं। अगर आप इन्हें internally मिला देते हैं, तो timing result अनजाने में agent को बता सकता है कि credential मौजूद है, केवल इसलिए कि gateway ने approval के बाद उसके लिए check किया।

Sallyport का vault gate जानबूझकर absolute है: vault locked होने पर हर action deny होता है। यह स्पष्ट security boundary है, फिर भी इसे timing tests की ज़रूरत है, क्योंकि caller देख सकता है कि denial कैसे तैयार किया गया। लक्ष्य यह दिखावा करना नहीं है कि locked vault remote request पूरी कर सकता है। लक्ष्य यह सुनिश्चित करना है कि local denial handling ऐसा आसान और repeatable signature न बनाए, जो caller की ज़रूरत से अधिक जानकारी उजागर करे।

OWASP अपनी Authentication Cheat Sheet में भी यही बात कहता है। अगर एक failure path दूसरे से अधिक काम करता है, तो केवल generic error text enumeration leak बंद नहीं करता। Guidance authentication पर है, लेकिन engineering lesson यहां भी लागू होता है: अलग execution paths के ऊपर रखा uniform message भी elapsed time के ज़रिए leak करता है।

चार outcomes के लिए दो अलग timing contracts चाहिए

हर outcome को बराबर करने की कोशिश लोकप्रिय सलाह है, क्योंकि इसे कहना आसान है। लेकिन gateway के network calls करने पर यह गलत हो जाती है। आपको एक असंभव universal duration नहीं, दो timing contracts चाहिए।

पहला contract local outcomes के लिए है। ये वे states हैं जिनमें gateway request भेजने से पहले refuse करना चाहिए: vault locked है, session authorization नहीं है या deny है, action के लिए configured credential नहीं है, या per-call approval अस्वीकार कर दी गई है। जिन states से agent को समान मात्रा में information मिलनी चाहिए, उन्हें common local response envelope से चलाएं।

दूसरा contract dispatched outcomes के लिए है। Valid credential और invalid credential दोनों एक ही HTTP test server या SSH test host तक पहुंच सकते हैं। उनके total times में transport, connection reuse, server work और response delivery शामिल होते हैं। Public internet को constant-time नहीं बनाया जा सकता। आप यह सुनिश्चित कर सकते हैं कि gateway दोनों outcomes को inject, send, record और map करने के लिए comparable paths से गुज़ारे। फिर test के दौरान controlled server से remote हिस्सा stable रखें।

इससे एक उपयोगी matrix बनती है:

Outcomeक्या request gateway से बाहर जाती है?Timing test में किससे तुलना करनी चाहिए?
Vault lockedनहींअन्य local denials, जिन्हें अधिक state उजागर नहीं करनी चाहिए
Authorization deniedनहींअन्य local denials, human interaction से पहले मापे गए
Credential missingनहींVault-available local failure, disclosure policy के अनुसार समान response envelope के साथ
Invalid credentialहांउसी controlled upstream के विरुद्ध valid credential
Valid credentialहांInvalid credential और remote error variants

Missing credential की तुलना सीधे third-party API की successful call से न करें और यह कहकर failure घोषित न करें कि एक तेज़ है। यह test केवल साबित करता है कि मशीन से बाहर न जाने वाली request internet request से तेज़ है। यह बात आपको पहले से पता थी।

इसके बजाय boundaries को अलग-अलग test करें। Local caller के लिए उन local states को अलग करना कठिन होना चाहिए जिन्हें आप छिपाना चाहते हैं। Dispatched caller के लिए gateway overhead के आधार पर good test credential और bad test credential को अलग करना कठिन होना चाहिए। Test server समान delay के बाद जानबूझकर अलग status codes लौटा सकता है, ताकि semantic result अलग रहे और timing experiment उपयोगी बना रहे।

एक स्पष्ट सीमा है: अगर caller को detailed error मिलता है, जिसमें लिखा है "credential missing", तो उसे credential missing जानने के लिए timing की ज़रूरत नहीं है। Timing defenses उस API को नहीं बचा सकतीं जो secret state खुलकर report करती है। पहले तय करें कि error semantics की अनुमति क्या है।

जब callers failure दोहरा सकते हैं, fast failure oracle बन जाती है

Timing leak आम तौर पर किसी नाटकीय difference के रूप में नहीं आती। अधिकतर ऐसा होता है कि refactor के दौरान कोई sensible early return जोड़ दिया जाता है।

मान लें gateway का operation order ऐसा है:

  1. Agent की request parse करें।
  2. Vault index में named credential खोजें।
  3. Check करें कि agent process के पास session approval है या नहीं।
  4. Request बनाकर dispatch करें।

Missing credential step two पर बाहर निकल जाता है। Existing credential वाला unapproved process step three तक जाता है। दोनों मामलों में external response एक जैसा हो सकता है: "action unavailable." फिर भी दूसरे path में vault-index hit, authorization lookup, audit preparation और शायद approval-card setup होता है। Caller हर input को कई बार चला सकता है और results को rank कर सकता है।

जब agent credential aliases चुन सकता है, leak और बढ़ जाती है। वह staging, production, deploy जैसे names या repository में मिले names की wordlist probe कर सकता है। उसे successful action की ज़रूरत नहीं है। उसे केवल fast और slow bucket चाहिए।

Defensive order आपकी disclosure policy पर निर्भर करता है, लेकिन सुरक्षित shape कुछ ऐसी दिखती है:

  1. Secret-dependent branches के बिना request validate करें।
  2. Absolute vault gate लागू करें।
  3. Process या session authorization लागू करें।
  4. Caller के उन controls से गुज़रने के बाद ही action और credential resolve करें, जिन्हें उस knowledge से पहले लागू होना चाहिए।
  5. जिन local failures को indistinguishable रखना है, उन्हें समान logging, error shaping और response completion work से गुज़ारें।

इसे unauthorized process के लिए secret work करने के निर्देश के रूप में न पढ़ें। आपको केवल समय बर्बाद करने के लिए credential decrypt या real authorization header तैयार नहीं करना चाहिए। उद्देश्य observable boundary पर state-dependent shortcuts से बचना है, denials को secret access में बदलना नहीं।

एक आम खराब patch है, हर denial से पहले sleep(100ms) करना। इससे demo graph सुंदर दिखता है, फिर तीन समस्याएं पैदा होती हैं। Scheduler noise और cache behavior के बाद duration अक्सर फिर अलग रहता है। Delay legitimate users पर बोझ डालता है। सबसे महत्वपूर्ण बात, अगर underlying paths अब भी अलग हैं, तो repeated caller random या fixed padding का average निकाल सकता है। Unequal work के ऊपर delay छिड़कने से बेहतर है कि आवश्यक work को बराबर किया जाए।

Timing वहीं मापें जहां agent उसे देखता है

Gateway के अंदर instrumentation diagnosis के लिए उपयोगी है, लेकिन यह primary security measurement नहीं है। Agent tool call भेजने और final result पाने के बीच का समय देखता है। आपका end-to-end differential test वहीं से शुरू और खत्म होना चाहिए।

एक dedicated test driver इस्तेमाल करें जो agent client की तरह व्यवहार करे। वह known process identity से शुरू हो, एक request भेजे, एक complete response का इंतजार करे, monotonic duration record करे और outcome label को measured request के बाहर store करे। Run के दौरान labels print न करें। Console output, tracing exporters और debug logging छोटे local paths को इतना प्रभावित कर सकते हैं कि जिस regression को आप ढूंढ रहे हैं वह छिप जाए।

एक practical sample record में एक से अधिक number चाहिए:

{
  "case": "vault_locked",
  "sequence": 184,
  "elapsed_us": 12746,
  "result_class": "local_denial",
  "connection_mode": "fresh",
  "run_id": "test-run-7"
}

Monotonic clock इस्तेमाल करें। Time synchronization चलने पर wall clocks बदल जाते हैं और subsecond comparisons के लिए खराब instruments हैं। Platform उपलब्ध कराए तो microseconds या nanoseconds record करें, फिर लोगों के पढ़ने के लिए milliseconds report करें। File में precision होने का मतलब measurement accurate होना नहीं है, लेकिन इससे analysis से पहले information खोती नहीं।

Samples लेने से पहले warm-up phase चलाएं। पहली calls app शुरू कर सकती हैं, code load कर सकती हैं, vault handle initialize कर सकती हैं, connection pool बना सकती हैं या cache भर सकती हैं। ये effects operationally वास्तविक हैं, फिर भी अक्सर उस steady-state difference को ढक देते हैं जिसे आप देखना चाहते हैं। अगर cold start agents को दिखाई देता है, तो उसे अलग test करें। केवल इसलिए inconvenient first-call behavior को चुपचाप न हटाएं कि charts बदसूरत दिखते हैं।

Cases का order randomize करें। अगर आप पहले 500 locked-vault calls और फिर 500 missing-credential calls चलाते हैं, तो thermal state, garbage collection, background activity और connection reuse confounders बन जाते हैं। Seeded shuffle से cases interleave करें, ताकि failures reproduce हो सकें।

Client protocol दोनों तरह के connections support करता हो तो fresh और reused connections को भी alternate करें। Warm connection पर गायब हो जाने वाला leak तब भी महत्वपूर्ण हो सकता है जब agent short-lived clients बनाता हो। केवल reuse में दिखाई देने वाला leak credential existence पर keyed cache उजागर कर सकता है।

ऐसा controlled upstream बनाएं जो semantics को delay से अलग रखे

कुंजी सौंपे बिना SSH चलाएं
इसका stateless sp-ssh helper SSH कार्रवाइयां चलाता है, जबकि SSH कुंजियां वॉल्ट में रहती हैं।

Invalid credentials वह test case है जिसे teams अक्सर गलत करती हैं। वे test harness को real service पर point करती हैं, जानबूझकर bad token भेजती हैं और successful call से तुलना करती हैं। Provider के rate limits, regional routing, TLS session resumption और abuse controls result का हिस्सा बन जाते हैं। यह gateway timing test नहीं है।

अपने नियंत्रण में एक छोटा fixture server बनाएं। वह उसी header shape से known test credential पढ़े जिसे आपका gateway inject करता है, fixed amount of work का इंतजार करे और good तथा bad credentials के लिए अलग response body और status लौटाए। Invalid path को shortcut नहीं करना चाहिए।

उदाहरण के लिए यह fixture contract पर्याप्त है:

Request header: Authorization: Bearer test-good
Response: 200 {"fixture":"accepted"}

Request header: Authorization: Bearer test-bad
Response: 401 {"fixture":"rejected"}

Both requests: wait until the same server-side target duration has elapsed

Target duration सामान्य local scheduling jitter से लंबी, लेकिन suite को तेज़ रखने के लिए पर्याप्त छोटी होनी चाहिए। अपने test machine पर measurements से इसे चुनें, blog post से कोई number copy न करें। महत्वपूर्ण यह है कि दोनों fixture branches semantic रूप से अलग होने से पहले समान parse, clock, wait और response path चलाएं।

HTTP के लिए gateway और client को isolate करना हो तो fixture loopback पर चलाएं। Realistic transport variation में detection देखना हो तो दूसरे job में controlled remote host पर चलाएं। Reports अलग रखें। Loopback result बताता है कि local implementation बदला है या नहीं। Remote result बताता है कि सामान्य network noise के बीच test sensitive रहता है या नहीं।

SSH के लिए test account और ऐसा command इस्तेमाल करें जो authentication के बाद known way में exit हो। Production bastion पर बार-बार fail करके test न करें। SSH servers failures को जानबूझकर धीमा कर सकते हैं, accounts lock कर सकते हैं या logging work जोड़ सकते हैं। ये sensible defenses हैं, लेकिन इससे measurement gateway के बजाय server के बारे में हो जाता है।

Sallyport bearer, basic या custom-header credential injection के साथ HTTP requests भेजता है और SSH के लिए bundled stateless sp-ssh helper इस्तेमाल करता है। ये अलग channels हैं और इनके fixtures भी अलग होने चाहिए। HTTP header path का even result किसी ऐसे SSH setup path के बारे में कुछ नहीं बताता जो keys resolve करता है, helper शुरू करता है और connection negotiate करता है।

Distributions की तुलना करें, फिर state classify करने की कोशिश करें

Averages timing leaks छिपा देते हैं। अगर 90 प्रतिशत calls 12 milliseconds में पूरी होती हैं और 10 प्रतिशत existing credential के लिए cache miss के कारण 80 milliseconds लेती हैं, तो average किसी दूसरे case के करीब लग सकता है, जबकि agent fast cluster का फायदा उठा सकता है।

हर case के लिए samples का पूरा set रखें। कम से कम median, lower और upper percentiles, minimum, maximum और sample count report करें। Histogram बनाना अक्सर table से अधिक informative होता है, क्योंकि वह तुरंत दो clusters दिखा देता है।

फिर test को adversarial बनाएं। एक deliberately simple classifier को केवल elapsed duration दें और उससे hidden label का अनुमान लगाने को कहें। Threshold classifier से शुरू करें। वह एक cutoff चुनता है, जैसे "X microseconds से कम का मतलब missing credential है", और उस data पर accuracy report करता है जिसका इस्तेमाल cutoff चुनने में नहीं हुआ। अगर one-threshold classifier naive baseline से लगातार काफी बेहतर प्रदर्शन करता है, तो आपके पास जांचने लायक observable signal है।

एक छोटी Python analysis script इस regression को दिखा सकती है, बिना यह दावा किए कि वह cryptographic constant time साबित करती है:

from statistics import median

samples = {
    "vault_locked": [...],
    "credential_missing": [...],
}

for name, values in samples.items():
    ordered = sorted(values)
    p10 = ordered[int(len(ordered) * 0.10)]
    p90 = ordered[int(len(ordered) * 0.90)]
    print(name, {"n": len(values), "p10": p10,
                 "median": median(values), "p90": p90})

best = None
all_values = sorted(set(samples["vault_locked"] + samples["credential_missing"]))
for cutoff in all_values:
    correct = 0
    total = 0
    for label, values in samples.items():
        for value in values:
            guess = "vault_locked" if value <= cutoff else "credential_missing"
            correct += (guess == label)
            total += 1
    score = correct / total
    if best is None or score > best[0]:
        best = (score, cutoff)

print({"best_training_accuracy": best[0], "cutoff_us": best[1]})

Cutoff चुनने से पहले samples को training और holdout groups में बांटें। वरना script noise पर overfit होकर खुद को बधाई देगी। Richer classifier जोड़ें तो उसे secondary diagnostic रखें। Complicated model ऐसे छोटे patterns खोज सकता है जिनका practical agent इस्तेमाल नहीं कर सकता, जबकि plain threshold उन embarrassing leaks को दिखाता है जिन्हें engineers वास्तव में introduce करते हैं।

Universal pass condition जैसे "सभी medians पांच milliseconds के भीतर होने चाहिए" न लगाएं। अलग machines और test setups पर इस threshold का कोई अर्थ नहीं है। अपने controlled environment में recorded baseline इस्तेमाल करें, देखें कि distributions अपेक्षित रूप से overlap करती हैं या नहीं और तब fail करें जब change उन states के बीच stable separability बनाए जिन्हें आप छिपाना चाहते थे।

Constant-time comparison इस समस्या के छोटे हिस्से को हल करता है

Audit trail को offline verify करें
sp audit verify से Sallyport की एन्क्रिप्टेड audit chain को वॉल्ट कुंजी के बिना offline verify करें।

"Timing attack" सुनते ही developers अक्सर constant-time equality function की ओर जाते हैं। Equal-length secrets, signatures, MACs और tokens की तुलना करते समय यह function महत्वपूर्ण है। लेकिन यह action gateway के पूरे request path को constant-time नहीं बनाता।

Go का crypto/subtle package समान contents वाली byte slices के लिए ConstantTimeCompare देता है। जब secret comparison को data-independent behavior चाहिए, तब यह सही तरह का primitive है। लेकिन यह उस branch को बराबर नहीं कर सकता जो vault खोलने से पहले return कर देती है, approval card render करती है या network connection बनाती है।

Sensitive, fixed-format values की तुलना करते समय constant-time comparison इस्तेमाल करें। फिर आसपास के control flow की समीक्षा करें। Missing credential के लिए तुरंत return करने वाले path के अंदर साफ comparison होने पर भी credential presence का oracle बना रहता है।

इसीलिए पूरी समस्या को "constant time" कहना भी ठीक नहीं है। HTTP और SSH calls करने वाले desktop gateway के लिए end-to-end constant time न achievable है, न आवश्यक। Requirement अधिक सीमित है: sensitive local states caller के लिए आसानी से classify किया जा सकने वाला timing signal न बनाएं।

MITRE के CWE-208 examples में password checks के दौरान early exits और existing तथा nonexistent accounts के लिए अलग work शामिल हैं। Pattern वही रहता है, भले ही password comparison बिल्कुल न हो। Observable difference किसी एक unsafe equality operator से नहीं, decision path से आता है।

Approval flows के लिए measurement boundary स्पष्ट रखें

Per-session approval और per-call approval timeline में इंसान को शामिल करते हैं। Whole-call duration में card notice करने, process identity पढ़ने, निर्णय लेने, Touch ID से authenticate करने और click करने का समय शामिल होगा। यह duration vault state से असंबंधित कारणों से बदलता रहता है।

इसे padding से छिपाने की कोशिश न करें। Interaction खराब होगा और लोग clock पर व्यवहार करने लगेंगे, ऐसा फिर भी नहीं होगा।

इसके बजाय flow को automatic और human-controlled portions में बांटें। Automatic portion agent के call भेजने से शुरू होता है और तब खत्म होता है जब gateway बिना prompt के denial दे देता है या approval request दिखा देता है। States के बीच इस portion को मापें। Human-controlled portion presentation से शुरू होकर approval, rejection, timeout या process exit पर खत्म होता है। Operations के लिए इसे log करें, लेकिन timing side-channel equivalence target के रूप में इस्तेमाल न करें।

आपको ऐसा test mode भी चाहिए जो dispatched calls के samples लेने से पहले stable approval state स्थापित करे। वरना आपका "valid credential" distribution एक बार approval card शामिल करेगा और session के बाकी हिस्से में उसे skip करेगा। इससे पहला sample बड़ा outlier बन जाएगा और अधिक subtle differences छिप जाएंगी।

एक अच्छी suite में इन सवालों के लिए अलग cases होते हैं:

  • क्या कोई approval-dependent credential lookup होने से पहले locked vault deny कर देता है?
  • क्या unapproved process को इस बात की परवाह किए बिना समान pre-prompt treatment मिलता है कि action के लिए configured credential है या नहीं?
  • Session approve होने के बाद, क्या valid और invalid test credentials controlled upstream तक comparable gateway paths लेते हैं?
  • क्या per-call approval rejection prompt से पहले extra credential-dependent work उजागर करती है?

Sallyport approval card में नए agent process की पहचान उसकी code-signing authority से करता है और उसका per-session authorization केवल उस process के चलने तक रहता है। First-call behavior test करते समय timing suite को जानबूझकर fresh agent processes बनाने चाहिए। Approved session test करते समय एक known process को alive रखें। इन modes को मिलाने से result की व्याख्या असंभव हो जाती है।

Audit work को secret-dependent fast path न बनने दें

संदिग्ध एजेंट रन रद्द करें
Sessions journal एजेंट रन को ट्रैक करता है और आपको चल रहे session को तुरंत revoke करने देता है।

Audit logging अक्सर आखिरी timing leak पैदा करता है, क्योंकि इसे security boundary का हिस्सा नहीं बल्कि bookkeeping माना जाता है। Denied request केवल terse event record कर सकती है। Successful request detailed record allocate कर सकती है, उसे chain में hash कर सकती है और encrypted storage में लिख सकती है। अगर success पहले से observable है तो यह difference उचित हो सकता है। लेकिन जब दो local denials hidden state की अलग मात्रा उजागर करें, तब यह खतरनाक है।

तय करें कि हर outcome कौन-से fields सुरक्षित रूप से record कर सकता है, फिर equivalent local failures से equivalent audit work कराएं। आपको fictional credentials लिखने या dummy requests भेजने की ज़रूरत नहीं है। लेकिन अगर agent को locked vault और missing credential में अंतर नहीं जानना चाहिए, तो ऐसे branch से बचें जिसमें "missing credential" journal को bypass करता है और "locked vault" भारी lookup और record write करता है।

Audit verification को request path से बाहर रखें। Verification operator action है, जिसका उद्देश्य और timing profile अलग है। Sallyport की audit chain को ciphertext पर offline sp audit verify से, vault key के बिना verify किया जा सकता है। यह design verification को secret read पर निर्भर होने से रोकता है, लेकिन logging के आसपास request-time behavior test करने की ज़रूरत खत्म नहीं करता।

Request parsing, authorization, vault gating, credential resolution, audit append, dispatch और response mapping के आसपास internal spans जोड़ें। इन spans को agent के सामने expose न करें। जब end-to-end test separation खोजे, तो cases के aggregate span durations की तुलना करके पता लगाएं कि नया divergence किस stage में आया।

Timing regression दिखाई देने के बाद ही detailed tracing जोड़ना गलती है। Instrumentation जल्दी जोड़ें, उसे test या local diagnostics setting के पीछे रखें और सुनिश्चित करें कि normal request path ऐसे synchronous logs emit न करे जिनकी cost credential या outcome पर निर्भर हो।

Differential tests को branches जोड़ने वाले code के पास रखें

Timing suite authorization tests के साथ उसी change review का हिस्सा होनी चाहिए। जिन branches में regression की सबसे अधिक संभावना होती है, वे सामान्य maintenance changes होते हैं: missing-configuration shortcut, credential aliases का cache, नया audit field, बेहतर error message या ऐसा refactor जो vault lookup को process approval से पहले ले आए।

Vault access, authorization, action resolution, error mapping, transport setup या audit writes को प्रभावित करने वाले हर change पर compact local suite चलाएं। इसमें loopback fixtures और moderate sample count हो सकता है। Releases से पहले quiet controlled environment में longer randomized suite चलाएं, और cold तथा warm modes को अलग record करें।

Test output ऐसा हो जिस पर reviewer कार्रवाई कर सके। यह unexplained aggregate score वाले green check से बेहतर है:

case pair: vault_locked vs credential_missing
samples: 400 per case, randomized order
median: 12.7 ms vs 13.1 ms
p10-p90: 11.8-14.0 ms vs 11.9-14.3 ms
holdout threshold accuracy: 51.4%
result: within baseline

और generic performance failure के नीचे समस्या छिपाने से यह बेहतर है:

case pair: vault_locked vs credential_missing
samples: 400 per case, randomized order
median: 4.2 ms vs 19.6 ms
p10-p90: 3.9-4.7 ms vs 18.2-22.1 ms
holdout threshold accuracy: 99.1%
result: investigate credential lookup before authorization

दूसरी report यह दावा नहीं करती कि busy workstation पर attacker को हमेशा 99.1 प्रतिशत accuracy मिलेगी। वह engineer को बताती है कि local code ने साफ और repeatable separation बना दी है। यह change को रोकने के लिए काफी है, जब तक branch order या response envelope ठीक न हो जाए।

Arbitrary delay से result न छिपाएं। Secret-dependent work को सही gate के पीछे ले जाएं, अनावश्यक state-specific work हटाएं और agent की boundary से फिर test करें। उपयोगी outcome perfectly flat graph नहीं है। उपयोगी outcome ऐसा agent है जो stopwatch को vault के पीछे मौजूद चीज़ों की inventory में न बदल सके।

सामान्य प्रश्न

क्या locked vault और missing credential को एक ही error लौटाना चाहिए?

इन दोनों को अलग-अलग states की तरह test करें, भले ही user-facing response जानबूझकर एक जैसा रखा गया हो। Locked vault बताता है कि gateway कोई भी कार्रवाई नहीं कर सकता। Missing credential बताता है कि चुनी गई कार्रवाई configured नहीं है। Invalid credential बताता है कि request remote service तक पहुंची और वहीं असफल हुई। अगर इन paths का local runtime बहुत अलग है, तो एजेंट फिर भी उन्हें अलग पहचान सकता है।

जब approval prompt में इंसान को click करना हो, तो timing कैसे test करें?

Human approval में लगने वाला समय उपयोगी timing target नहीं है, क्योंकि वह व्यक्ति पर निर्भर करता है। Approval card दिखने से पहले के automatic हिस्से को मापें, फिर stable test authorization के साथ approved path को अलग test करें। User के reaction time को security padding न मानें।

क्या timing tests के लिए average response time की तुलना काफी है?

नहीं। केवल average duration की तुलना करने वाला test multimodal behavior, cache effects और noisy average के भीतर छिपे short fast-fail path को नहीं पकड़ पाएगा। हर sample record करें, percentiles की तुलना करें और एक simple classifier आजमाएं, जो elapsed time से state का अनुमान लगाए।

Real API को hit किए बिना invalid credentials कैसे test करें?

एक controlled test server इस्तेमाल करें, जो एक known-good और एक known-bad test credential को पहचाने, दोनों के लिए समान fixed interval तक इंतजार करे और फिर अलग status codes लौटाए। इससे unpredictable third-party API को gateway behavior के साथ मिलाए बिना measurement हो जाता है। Production provider पर high-volume timing probes कभी न चलाएं।

क्या random delay जोड़ने से timing side channel ठीक हो जाता है?

नहीं। Random jitter छोटे sample में साफ signal को देखना कठिन बना सकता है, लेकिन repeated measurements से उसका औसत निकाला जा सकता है। इससे सामान्य उपयोग धीमा होता है और timing behavior एक probability problem बन जाता है। इसके बजाय comparable paths पर समान आवश्यक काम करें।

Authorization outcomes के बीच कितना timing difference सुरक्षित है?

उपयोगी लक्ष्य यह है कि जिस point पर आप माप रहे हैं, वहां classifier उन states को भरोसेमंद ढंग से अलग न कर सके जिन्हें private रहना चाहिए। कोई universal millisecond budget नहीं है, क्योंकि local process, loopback server और internet API में अलग-अलग noise होता है। Baseline रखें और तब test fail करें जब code change ऐसी stable separation बनाए जो पहले मौजूद नहीं थी।

क्या network errors को missing credentials के साथ group करना चाहिए?

Transport failures को अपनी category में रखें। DNS समस्या, refused connection और remote timeout network conditions उजागर कर सकते हैं, लेकिन वे यह ज़रूरी नहीं बताते कि vault entry मौजूद है या नहीं। Unrelated failures को इतना flatten न करें कि operators broken connectivity की वजह न खोज सकें।

Agent gateway में timing कहां से मापनी चाहिए?

Agent की observable boundary से test करें: जब वह MCP request लिखता है और जब उसे final result या error मिलता है। साथ ही vault lookup, authorization और dispatch के आसपास छोटे tests जोड़ें, ताकि failing differential test यह बता सके कि regression किस stage में आया। एक end-to-end stopwatch leaks खोजता है, internal spans उनका कारण बताते हैं।

क्या timing tests agent की broad access होने पर secrets की रक्षा कर सकते हैं?

Tests accidental disclosure कम कर सकते हैं, लेकिन ऐसी बात नहीं छिपा सकते जिसे agent को जानने की स्पष्ट अनुमति है। अगर agent credential names list कर सकता है, status screens देख सकता है या अलग-अलग detailed errors पा सकता है, तो timing मुख्य समस्या नहीं रह जाती। पहले अनावश्यक state disclosure हटाएं, फिर बाकी paths को duration के आधार पर classify करना कठिन बनाएं।

Timing side-channel tests कितनी बार चलाने चाहिए?

Timing suite को one-time audit नहीं, regression test मानें। Authorization, vault lookup, error mapping या request dispatch को छूने वाले हर change पर इसका छोटा version चलाएं और releases से पहले controlled environment में बड़ा randomized sample चलाएं। Timing leaks अक्सर तब लौटते हैं जब कोई seemingly harmless early return जोड़ देता है।

Sallyport

Sallyport आपके AI एजेंट के लिए API कॉल और SSH कमांड चलाता है। कुंजियाँ आपके Mac पर एक लोकल वॉल्ट में रहती हैं; आप हर रन को स्वीकृत करते हैं और हर क्रिया एक सीलबंद जर्नल में दर्ज होती है।

© 2026 Sallyport · Apache-2.0 के तहत ओपन सोर्स · Oleg Sotnikov