# HTTP request signatures AI agent की API calls को कैसे बाँधती हैं

Bearer token रखने वाले AI agent को व्यावहारिक रूप से उतनी ही स्वतंत्रता मिलती है जितनी उस token को पढ़ सकने वाले किसी दूसरे process को। वह अभी permitted endpoint call कर सकता है, बाद में retry कर सकता है, code अनुमति दे तो token किसी दूसरे host को भेज सकता है और ऐसा request बना सकता है जिसका body run शुरू करने वाले user instruction से बहुत कम जुड़ा हो। Server को credential पर कब्ज़ा दिखता है, इसके अलावा बहुत कम जानकारी मिलती है।

HTTP request signatures authorization को किसी खास message से बाँधकर स्थिति बेहतर करती हैं। सही design signature को केवल `POST https://api.example.test/v1/releases/42` के लिए, agent द्वारा तैयार किए गए exact body के साथ, थोड़े समय तक और केवल एक signing identity के अंतर्गत valid बना सकता है। यह उपयोगी control है। यह authorization, approval या credential isolation का विकल्प नहीं है।

Teams इस विषय में दो विपरीत गलतियाँ करते हैं। कुछ signing को जटिल समझकर bearer tokens बनाए रखते हैं और बाद में पता चलता है कि agent broadly scoped token का इस्तेमाल हर उस जगह कर सकता है जहाँ outbound request भेज सकता है। दूसरे लोग HTTP library द्वारा भेजे गए हर header पर sign कर देते हैं और ऐसा verifier बनाते हैं जो सामान्य proxies, clock skew या library update से production में टूट जाता है। सही design उन fields को बाँधता है जो action का अर्थ या destination बदलते हैं, फिर freshness और verification को इतना सरल बनाता है कि उन्हें चलाना उबाऊ, स्थिर और भरोसेमंद रहे।

## Signatures message को सीमित करती हैं, जबकि bearer tokens केवल possession साबित करते हैं

Bearer token एक सवाल का जवाब देता है: क्या इस request के साथ ऐसा secret आया है जिसे अभी स्वीकार किया जाता है? सामान्यतः यह secret को request method, target, body या time से नहीं बाँधता। OAuth access tokens में scopes, audiences और expiration हो सकते हैं, जो मदद करते हैं, लेकिन holder expiry तक हर permitted scope का इस्तेमाल कर सकता है।

Request signature एक अधिक सीमित cryptographic सवाल का जवाब देती है: क्या इस signing key के holder ने request components के इस तय set को authorize किया? Server signed input दोबारा बनाता है, registered public key या shared secret से verify करता है, time limits जाँचता है और फिर सामान्य authorization लागू करता है। यह क्रम महत्वपूर्ण है। Signature verification message integrity और signer identity स्थापित करता है। Authorization तय करता है कि वह identity action कर सकती है या नहीं।

मान लें कि deployment service में release creation तक सीमित bearer token है। Agent पहले harmless staging release बनाता है। बाद में prompt injection उसी agent को production release बनाने का निर्देश देता है। अगर token का scope दोनों environments को cover करता है, तो दोनों requests पास हो जाएँगी। Token को signed request से बदलना अपने-आप authorization की इस गलती को ठीक नहीं करता। अगर signing identity production releases बना सकती है, तो वह production request पर sign कर सकती है।

Signatures ordinary bearer header की तुलना में service को ये protections देती हैं:

- Captured signed request जल्दी expire हो जाती है और हमेशा replay नहीं की जा सकती।
- Copied signature आमतौर पर `POST /v1/staging/releases` से `POST /v1/production/releases` पर नहीं ले जाई जा सकती।
- Body digest sign होने पर बदला हुआ JSON body verification में fail हो जाता है।
- Service signing credential को पहचान सकती है, बिना उसे reusable header value की तरह स्वीकार किए।
- Verifier ठीक-ठीक record कर सकता है कि signer ने किन fields को approve किया।

हर architecture में इसे access tokens का replacement न कहें। कई systems दोनों का इस्तेमाल करते हैं। Access token delegated user या workload की पहचान कर सकता है, जबकि request signature individual message को agent-specific signing credential से बाँधती है। दूसरे systems में signed request caller को सीधे authenticate करती है और server signing identity से permissions निकालता है।

AI agents के लिए इसका व्यावहारिक अर्थ है कि signature action को एक concrete object बनाती है, जिसे inspect, approve और log किया जा सकता है। Bearer token अधिकतर ambient capability की तरह दिखता है। यह अंतर review संभव बनाता है, लेकिन तभी जब आपका tool boundary agent को signing secret निकालने से रोके।

## अपना canonical string बनाने के बजाय RFC 9421 इस्तेमाल करें

RFC 9421, HTTP Message Signatures, covered components घोषित करने और signature भेजने का structured तरीका बताता है। यह उस आम private format से बचाता है जिसमें एक पक्ष fields को newline characters से जोड़ता है, दूसरा URL को अलग तरह normalize करता है और verification fail होने पर दोनों cryptography को दोष देते हैं।

RFC दो ideas अलग करता है। `Signature-Input` label, covered components और `created`, `expires`, `nonce`, `alg` तथा `keyid` जैसे parameters घोषित करता है। `Signature` उसी label के नीचे cryptographic value रखती है। Verifier घोषित components और parameters से signature base बनाकर उसे verify करता है।

एक compact request ऐसी दिख सकती है:

```http
POST /v1/releases/42?environment=staging HTTP/1.1
Host: api.example.test
Content-Type: application/json
Content-Digest: sha-256=:rPMyV6WTE4Duf0JApE9tXvDYy9EzrgFQbq3e2XTCwbs=:
Signature-Input: sig1=("@method" "@authority" "@path" "@query" "content-digest" "date");created=1735689600;expires=1735689660;keyid="agent-release-17";alg="ed25519"
Signature: sig1=:BASE64_SIGNATURE_BYTES:
Date: Wed, 01 Jan 2025 00:00:00 GMT

{"version":"2025.01.01","notes":"staging validation"}
```

ऊपर का digest value केवल wire shape दिखाता है, example JSON का digest नहीं। Production client exact bytes से digest बनाएगा जिन्हें वह भेजने वाला है। अगर signing के बाद JSON को दूसरी बार serialize किया गया, तो failure लगभग तय है।

RFC 9421 जानबूझकर flexible है। यह intermediaries और अलग HTTP versions के लिए उपयोगी है, लेकिन इसका अर्थ है कि आपके API contract को exact profile बतानी होगी। Permitted algorithm, mandatory covered components, maximum signature lifetime, `keyid` format, accepted digest algorithm और nonce की आवश्यकता स्पष्ट करें। अगर contract केवल इतना कहता है कि requests signed होनी चाहिए, तो हर client author अलग assumptions बनाएगा।

जब service public keys register कर सकती हो, तब Ed25519 अच्छा default है। Server public verification key रखता है और उस public record के खोने से signing secret उजागर नहीं होता। HMAC signatures तब काम कर सकती हैं जब एक trusted component और API secret share करते हों, लेकिन secret दोनों पक्षों पर मौजूद होगा। Agent workflows में इससे reusable secret leak होने वाली जगहें बढ़ सकती हैं।

जब कोई protocol constraint मजबूर न करे, proprietary scheme से बचें। Proprietary formats में एक client raw URL, दूसरा decoded path और verifier host का अलग representation sign कर सकता है। RFC 9421 defined component identifiers और structured fields देता है। इन्हें इस्तेमाल करें और प्रकाशित profile के exact behavior का परीक्षण करें।

## Action को परिभाषित करने वाले method, destination और query को बाँधें

Agent को हर उस request field पर sign करना चाहिए जो request की दिशा या server operation बदलती है। अधिकांश API calls में उपयोगी न्यूनतम set `@method`, `@authority`, `@path` और `@query` है। Full target URI को एक component में cover करना हो तो `@target-uri` इस्तेमाल कर सकते हैं, लेकिन बिना स्पष्ट कारण दोनों formats को sign न करें।

`@method` किसी `GET` के लिए बनी signature को `DELETE` के रूप में इस्तेमाल होने से रोकता है। यह स्पष्ट लगता है, फिर भी hand-built schemes इसे अक्सर छोड़ देती हैं क्योंकि engineer मान लेता है कि path operation बताने के लिए पर्याप्त है। REST APIs एक ही path को अलग methods के साथ reuse करती हैं। Method action बदलता है।

`@authority` host और port authority को बाँधता है। इससे एक API origin के लिए जारी signature किसी दूसरे origin पर valid नहीं होगी, भले वह दूसरा origin वही credential स्वीकार करता हो। Preview, staging और production hosts वाले organizations में यह खास तौर पर महत्वपूर्ण है। Staging के लिए बनी signing identity को agent या redirect के host बदलने से production authority नहीं मिलनी चाहिए।

`@path` और `@query` पर बराबर ध्यान दें। कई APIs query string में meaningful parameters रखती हैं:

```http
POST /v1/invoices/817/refund?amount=2500&currency=USD
```

अगर signature केवल path cover करती है, तो transit में request बदल सकने वाला attacker amount या currency बदल सकता है। Server query से `dry_run`, `environment`, `force`, `page_size`, `include_deleted` या tenant selector लेता हो, तो ये values action का हिस्सा हैं। `@query` sign करें।

RFC 9421 `@query-param` भी परिभाषित करता है, जो किसी खास named parameter को cover कर सकता है। ऐसे protocols में इसका उपयोग हो सकता है जहाँ कुछ query parameters security decision से स्पष्ट रूप से बाहर हों, जैसे tracing data। Agents द्वारा इस्तेमाल होने वाली internal API में पूरी query sign करना आमतौर पर कम चौंकाने वाला है। हर parameter approved request का हिस्सा बन जाता है और reviewers को exception list याद नहीं रखनी पड़ती।

URL normalization को हल्के में न लें। Verifier को RFC 9421 में बताए गए component semantics और आपकी चुनी हुई library का इस्तेमाल करना चाहिए। Percent escapes को हाथ से decode और re-encode न करें। Repeated query parameters को तब तक sort न करें जब तक selected component definition ऐसा न करती हो। Request target सुविधाजनक application object बनने से पहले wire पर bytes होता है।

Redirect पर स्पष्ट rule रखें: signed request को किसी अलग authority वाले redirect पर automatically carry न करें। Original authority को cover करने वाली signature नए host पर fail होनी चाहिए, और यही सही behavior है। Client redirect प्राप्त करे, explicit allowlist लागू करे, नया request बनाए और उस नए request पर sign करे। Mutating requests के लिए कई teams को redirects पूरी तरह reject करने चाहिए।

## Signed body के लिए JSON पर भरोसा नहीं, digest चाहिए

जब body result को प्रभावित करती हो, तब `content-digest` sign करें। इसमें लगभग हर JSON mutation request, multipart upload, form submission और bulk operation शामिल है। अलग media types में server उन्हीं bytes को अलग तरह parse करता हो, तो `content-type` sign करना भी उचित हो सकता है।

IETF RFC 9530 में `Content-Digest` परिभाषित करता है। यह Structured Fields syntax से HTTP message content का digest रखता है। Signature सीधे बहुत बड़े body को cover करने के बजाय digest header को cover करती है, जबकि recipient body digest खुद निकालकर signature स्वीकार करने से पहले उसकी तुलना करता है। इससे exact content का fixed-size representation मिलता है।

सुरक्षित send sequence सरल है और इसी क्रम में रहना चाहिए:

1. Final request object बनाएँ, जिसमें query parameters और interpretation को प्रभावित करने वाले headers शामिल हों।
2. Body को एक बार bytes में serialize करें और वही bytes transmission के लिए रखें।
3. उन bytes पर `Content-Digest` निकालें।
4. चुने गए components पर `Signature-Input` बनाएँ और उसके signature base पर sign करें।
5. बदले बिना वही request bytes और headers भेजें।

आम failure cryptographic attack से अधिक साधारण होता है। Application digest निकालने के लिए object serialize करती है, उस पर sign करती है और फिर HTTP helper object को दोबारा serialize कर देता है। JSON member order, escaping, whitespace, numeric formatting या timestamp field बदल जाती है। Verifier सही तौर पर digest mismatch बताता है। Developers release निकालने के लिए body protection हटा देते हैं। यह गलत समाधान है।

Transport को byte buffer, stream या immutable request body दें। अगर streaming से transmission से पहले पूरा digest निकालना संभव न हो, तो उसके लिए बनाए गए protocol का इस्तेमाल करें और अच्छी तरह test करें। Streaming असुविधाजनक होने के कारण high-impact operation से body digest चुपचाप न हटाएँ।

Headers के लिए सीमित rule रखें। किसी header को तब sign करें जब recipient या intermediary उसका उपयोग request के security meaning को बदलने के लिए कर सकता हो। `content-type` इसका उदाहरण है। Server account चुनने के लिए tenant header इस्तेमाल करता हो, तो वह भी candidate है। Retries और duplicate effects महत्वपूर्ण हों, तो idempotency header sign करें। Diagnostic header आमतौर पर आवश्यक नहीं है।

`user-agent`, `accept`, trace IDs, connection headers और library द्वारा भेजे गए हर header को sign करने से clients brittle बनते हैं। Proxies सामान्य headers जोड़, मिला या बदल सकते हैं। HTTP में ऐसे वैध transformations होते हैं। Signature का उद्देश्य semantic बदलाव रोकना है, harmless transport variation को outage बनाना नहीं।

## Freshness windows drift सहें, लेकिन queued work reject करें

Time limits captured signatures को थोड़े समय तक ही उपयोगी बनाती हैं। लेकिन हर workstation, container और VM का समय पूरी तरह सही मानने से अनावश्यक incidents होते हैं। समाधान bounded acceptance rule और ठीक clock synchronization है, दो घंटे की grace period नहीं।

`Signature-Input` में `created` और `expires` इस्तेमाल करें। Interactive action calls में, जहाँ agent भेजने से ठीक पहले sign करता है, sixty-second lifetime अच्छी तरह काम करती है। Unreliable network या transient failure के बाद retry करने वाले workflow में कुछ minutes उचित हो सकते हैं। API को एक maximum lifetime document और enforce करनी चाहिए। Clients को मनमाना expiry चुनने न दें।

Verifier को तीन स्थितियाँ अलग-अलग जाँचनी चाहिए:

- `created` समय configured skew allowance से अधिक future में हो, तो request reject करें।
- `expires` समय बीत चुका हो, तो reject करें।
- `expires - created` API maximum से अधिक हो, तो request अभी expired न होने पर भी reject करें।

Server थोड़ा आगे या पीछे चलने वाली client clock स्वीकार कर सकता है, बिना stale work स्वीकार किए। उदाहरण के लिए service सीमित future skew और छोटी expiry interval दे सकती है। Exact values client कहाँ चलती हैं इस पर निर्भर हैं, लेकिन principle वही है: drift tolerance replay window नहीं है जिसे पूरी दोपहर खुला छोड़ दिया जाए।

HTTP `Date` header को अकेला freshness mechanism न बनाएँ। Compatibility और diagnostics के लिए इसे covered component बनाना उपयोगी हो सकता है, लेकिन `created` और `expires` सीधे signature parameters में रहते हैं और कम ambiguous होते हैं। दोनों sign करें, तो disagreement होने पर enforcement के लिए server किस value का उपयोग करेगा, यह स्पष्ट लिखें। Verifier को किसी भी value को स्वीकार करने देने से attacker को अनावश्यक लाभ मिलता है।

Queued agent tasks एक छिपी design error दिखाते हैं। मान लें agent 09:00 पर signed requests बनाता है, human approval 09:20 तक रुकती है और worker approval के बाद पुराना request भेजता है। Service को उसे reject करना चाहिए। Approval के बाद नया signing event होना चाहिए, क्योंकि approved action का current time और current destination meaningful होना चाहिए।

Retryable operations के लिए header या signed body field में idempotency identifier रखें और उसे signature से cover करें। Client हर retry के लिए नई signature बना सकता है, जबकि server logical operation पहचानकर duplicate side effects रोकता है। Expired signed request को दोबारा भेजना retry strategy नहीं है।

## Nonces replay तभी रोकते हैं जब server उन्हें याद रखता है

Short expiry replay की अवधि सीमित करती है, लेकिन captured request को उस अवधि में बार-बार replay करने से नहीं रोकती। इसका महत्व endpoint पर निर्भर है। Harmless read replay करने का प्रभाव कम हो सकता है। Money transfer, account deletion या infrastructure change replay करना गंभीर हो सकता है।

Nonce इस risk को तब कम करता है जब server हर signing identity के लिए उसे single use मानता है। Client unpredictable value बनाता है, उसे signature parameters या covered header में रखता है और server signature expire होने तक successful use record करता है। उसी signer और nonce वाला दूसरा request signature valid होने पर भी fail हो जाता है।

यहीं teams अक्सर गलती करती हैं। Server nonce retain नहीं करता, तो वह केवल एक अतिरिक्त random string है। वह uniqueness साबित नहीं करता। Shared cache या database table में atomic create operation चाहिए ताकि concurrent replays दोनों verification पार न कर जाएँ।

जहाँ replay का नुकसान operational cost के योग्य हो, nonce store इस्तेमाल करें। उसकी retention period, size limits, failure behavior और partitioning तय करनी होगी। Accepted nonce को तब तक रखें जब तक server request स्वीकार कर सकता है। Records को केवल nonce से नहीं, signer identity और nonce से scope करें, क्योंकि अलग signing identities का समान value बनना अपने-आप security impact नहीं है।

हर low-risk, high-volume call के लिए केवल इसलिए nonce mandatory न करें कि यह सुरक्षित सुनाई देता है। इससे nonce store outage harmless reads के लिए भी API outage बन सकती है। Practical profile irreversible mutations के लिए nonce माँग सकती है और बाकी जगह short expiry तथा idempotency controls पर निर्भर कर सकती है। यह rule endpoint by endpoint लिखें।

Nonce idempotency का विकल्प भी नहीं है। Nonce कहता है कि यह signed message एक बार स्वीकार होनी चाहिए। Idempotency identifier कहता है कि अलग-अलग signed retry attempts एक intended business operation हैं। दोनों अलग failures को हल करते हैं।

## Application code request देखने से पहले verification fail closed होनी चाहिए

API gateway या application entry point को route handler action parameters parse करने, job शुरू करने या downstream services से संपर्क करने से पहले request verify करनी चाहिए। Verification से पहले body पढ़कर काम करने वाला handler signature की मूल security property पहले ही छोड़ चुका है।

Verifier का क्रम predictable होना चाहिए:

1. `Signature-Input` और `Signature` को Structured Fields की तरह parse करें और malformed syntax तथा duplicate ambiguity reject करें।
2. Allowed signature label चुनें और unknown algorithms, missing mandatory components या prohibited component combinations reject करें।
3. `keyid` को active signing identity से resolve करें और verification material प्राप्त करें।
4. RFC 9421 के अनुसार received request का इस्तेमाल करते हुए signature base दोबारा बनाएँ, reconstructed application URL का नहीं।
5. Cryptographic signature, body digest, time bounds, जहाँ आवश्यक हो nonce state और उसके बाद authorization जाँचें।

Logs में cryptographic failure और authorization failure अलग रखें। Public responses सरल हो सकती हैं। Callers के लिए stable error code के साथ `401` या `403` पर्याप्त है। Internally दर्ज करें कि request unknown `keyid`, expired signature, invalid digest, mismatched authority, reused nonce या insufficient permission के कारण reject हुई।

Signature bytes को harmless debugging material की तरह log न करें। Public-key signatures HMAC credentials की तरह secret नहीं होतीं, लेकिन complete request logs में authorization headers, personal data और bodies हो सकते हैं। Request identifier, signer identity, covered component names, retention policy अनुमति दे तो digest value और decision log करें। Raw capture को स्पष्ट incident procedure तक सीमित रखें।

Test vectors prose से अधिक महत्वपूर्ण हैं। RFC 9421 examples देता है, लेकिन आपकी API profile को अपने fixtures चाहिए। ऐसे requests रखें जिन्हें verify होना चाहिए और ऐसे mutations भी जो fail हों: बदला method, बदली query, body का बदला byte, expired signature, future `created`, गलत authority, बदला `keyid` और repeated nonce। हर supported client implementation में इन्हें चलाएँ।

Signature verifier को ambiguity reject करनी चाहिए, भले permissive parser sender का intent समझने का अनुमान लगा सके। Duplicate headers, inconsistent component serialization और unsupported algorithms protocol errors हैं। Agent को server का helpful होना नहीं, exact होना चाहिए।

## Signing material को agent context से बाहर रखें

AI coding agent को private signing key या HMAC secret देने से signing का बड़ा उद्देश्य खत्म हो जाता है। Key tool output, shell history, temporary files, error reports या ऐसे prompt में दिखाई दे सकती है जो agent को environment print करने को कहे। अच्छी तरह व्यवहार करने वाले agent के पास भी reusable credential के लिए बहुत बड़ा indirect surface area होता है।

इसके बजाय narrow action boundary दें। Agent method, permitted destination, headers और body किसी trusted local या remote component को देता है। वह component allowed target validate करता है, workflow में ज़रूरत हो तो approval लेता है, covered component list बनाता है, भेजने से ठीक पहले sign करता है और response लौटाता है। Agent को plaintext secret या ऐसा fake placeholder भी नहीं मिलता जिसे वह गलती से forward कर सके।

यह boundary authority review को भी concrete बनाती है। Signing identity को service, environment, route family और action class तक सीमित किया जा सकता है। अगर agent को केवल staging release खोलना है, तो उसे billing adjustments या production deletion calls sign करने वाला credential न दें। Signature verification के बाद इन limits को लागू करना server authorization की जिम्मेदारी है।

Sallyport HTTP actions के लिए यही separation अपनाता है: app API credentials को अपने encrypted vault में रखता है और HTTP call खुद करता है, इसलिए MCP-capable agent को plaintext credential के बजाय result मिलता है।

Action gateway को request-signature standard न समझें। RFC 9421 दो HTTP parties को selected message components authenticate करने का तरीका बताता है। Action gateway तय करता है कि signing material कहाँ रहेगा, human approval कब दिखेगा और agent run के आसपास कौन-सा audit record बनेगा। दोनों में से किसी एक का अकेले उपयोग किया जा सकता है, लेकिन consequential APIs पर autonomous tools काम करें तो दोनों का संयोजन उपयोगी है।

अगर local signer पर निर्भर हैं, तो उसके local interface को authorization boundary मानें। जहाँ संभव हो requests को calling process से बाँधें, arbitrary destinations reject करें और सुनिश्चित करें कि एक agent process दूसरे process के approved session का चुपचाप उपयोग न कर सके। ऐसा local service जो किसी भी local program द्वारा भेजे गए किसी भी URL पर sign कर दे, उसने bearer capability को केवल socket के पीछे रखा है।

## Approval और signatures अलग सवालों के जवाब हैं

Human approval दर्ज करता है कि किसी व्यक्ति ने agent action की किसी खास class को अनुमति दी। Request signature दर्ज करती है कि signing identity ने defined HTTP message को authorize किया। जब तक design इन्हें स्पष्ट रूप से नहीं बाँधता, कोई record दूसरे को साबित नहीं करता।

High-impact calls में approval view में वे fields दिखाएँ जिन्हें signature cover करेगी: method, authority, path, महत्वपूर्ण query parameters, body digest या readable body summary, signing identity और expiry। अगर user `POST /v1/releases/42?environment=staging` approve करता है, तो signer बाद में unsigned query parameter के ज़रिए production substitute न कर सके।

केवल opaque body digest करने से human review कठिन हो सकता है। Cryptographic digest byte identity साबित करता है, लेकिन व्यक्ति को लगभग कुछ नहीं बताता। दोनों artifacts रखें: review के लिए canonical request representation और integrity के लिए digest। Review view उसी exact immutable request object से बने जिसे signer भेजेगा, किसी अलग rendered plan से नहीं।

Short agent run में कई low-impact calls हों, तो session approval उचित हो सकता है। Deletion, external publication, financial changes या ऐसे operation के लिए per-call approval बेहतर है जिसे attacker routine traffic में छिपा सकता है। हर read पर approval न माँगें। लोग click through करेंगे और meaningful decision के बिना approval fatigue पैदा होगी।

Audit record में signer identity, covered components, signature lifetime, authorization decision, approval reference अगर मौजूद हो, response status और request identifier रखें। Readable audit trail operator को incident के बाद सीधा सवाल हल करने में मदद करता है: agent ने क्या भेजा, किस authority के तहत भेजा और server ने उसे स्वीकार किया या नहीं?

## जिन failures की rehearsal ज़रूरी है, वे अधिकतर सामान्य engineering failures हैं

सबसे खतरनाक implementation bugs टूटी हुई elliptic curves नहीं हैं। वे unsigned fields, mismatched canonicalization, stale work और agents की पहुँच वाली जगहों पर रखे secrets हैं।

एक failure तब होता है जब team `@method`, `@path` और `date` sign करती है, लेकिन `@query` छोड़ देती है। Release API सामान्य उपयोग में `?environment=staging` स्वीकार करती है। बाद में maintenance change उसी endpoint में `?environment=production` जोड़ देता है। Proxy bug या hostile local component signing के बाद parameter बदल देता है। Signature verify हो जाती है, handler production देखता है और audit record गलत ढंग से कहता है कि agent ने valid signed request भेजी। Signature ने वही किया जो component list ने कहा था। Component list अधूरी थी।

दूसरा failure तब होता है जब clock-related tickets घटाने के लिए developers ten-minute signatures स्वीकार करते हैं। Agent delete request sign करता है, complete headers debug log में लिखता है और developer log को issue में copy कर देता है। उस issue तक पहुँच रखने वाला व्यक्ति दिन के अधिकांश समय request replay कर सकता है। Short expiry मूल leak को खत्म नहीं करती, लेकिन उसकी उपयोगिता बहुत घटाती है। Deletion के लिए nonce requirement first acceptance के बाद बची replay window भी हटा देती है।

तीसरा failure shared HMAC credentials के साथ होता है। Provisioning को अतिरिक्त काम समझकर कई agents एक ही secret इस्तेमाल करते हैं। Destructive call मिलने पर audit team shared integration पहचान सकती है, लेकिन agent run, user approval या origin process नहीं। अलग authority boundaries को अलग signing identities दें। Attribution incident response का हिस्सा है, कोई वैकल्पिक reporting सुविधा नहीं।

एक mutating endpoint से शुरू करें और library चुनने से पहले profile लिखें। उसकी allowed authority, mandatory components, body digest rule, signature duration, skew allowance, replay rule, signing algorithm और authorization mapping स्पष्ट करें। फिर हर covered field को बदलने वाले negative tests बनाएँ। अगर meaningful request field बदलकर भी test verify हो जाए, तो profile ship न करें।

Signed request को सही कारण से reject करना आसान होना चाहिए। यह standard design को narrow authority, short-lived messages, immutable bodies और agent action के बाद क्या हुआ दिखाने वाले logs की ओर ले जाता है।
