# AI agents और कई cloud accounts: हर action को target से बाँधें

AI एजेंट कई cloud accounts में तभी सुरक्षित रूप से काम कर सकते हैं, जब हर request में एक immutable account boundary स्पष्ट रूप से दी गई हो और executor हर mismatch को अस्वीकार करे। जो एजेंट «production में deploy करो» कह सकता है, लेकिन यह नहीं बता सकता कि उसके पीछे AWS account, Azure subscription या Google Cloud project कौन सा है, उसे अस्पष्ट authority दी गई है।

Teams अक्सर इसे IAM cleanup exercise की तरह देखते हैं। असल में यह execution design की समस्या है। IAM दो accounts को सही access दे सकता है, फिर भी एजेंट, उसका wrapper या shell profile गलत account चुन सकता है। ऐसा होने पर पूरी तरह valid credential गलत जगह पूरी तरह valid change कर देता है।

इसका समाधान किसी clever permissions model से कम आकर्षक है। पहले से executable targets तय करें, हर target को provider द्वारा दिए गए identifiers और dedicated execution identity से बाँधें, एजेंट से handle के ज़रिए target माँगें और state बदलने वाली call से ठीक पहले caller की जाँच करें। इंसानों के लिए समझने योग्य environment names उपयोगी हैं, लेकिन code कहाँ चलेगा, इसका फैसला वे नहीं करते।

## अस्पष्ट targets असली authority पैदा करते हैं

Environment label authority boundary नहीं होता। «Production» किसी व्यक्ति को बताता है कि टीम resources का इस्तेमाल कैसे करना चाहती है। यह API को नहीं बताता कि request किस AWS account, Azure subscription, Google Cloud project, tenant, region या assumed role को मिलनी चाहिए।

यह फर्क तब तक मामूली लगता है, जब तक किसी कंपनी में अलग-अलग organizations में `prod`, `production`, `prod-old` और `production-sandbox` नाम बिखरे न हों। मैंने migrations के दौरान copy किए गए account aliases, retired accounts की ओर इशारा करते stale shell profiles और ऐसी harmless दिखने वाली read operation देखी हैं जो उस account में पहुँच गई, जिसे incident responders सुरक्षित रखने की कोशिश कर रहे थे। Agents स्थिति को और कठिन बनाते हैं, क्योंकि वे natural-language labels को शाब्दिक रूप से लेते हैं और ambiguity पकड़ने वाले व्यक्ति से कहीं तेज़ी से कार्रवाई कर सकते हैं।

Execution से पहले target को इन सभी सवालों के जवाब देने चाहिए:

- Resource का owner कौन सा provider है?
- Call किस immutable account boundary को मिलेगी?
- Organization उस boundary को कौन सा environment देती है?
- वहाँ कौन सी execution identity कार्रवाई कर सकती है?
- कौन सी geographic या organizational सीमाएँ लागू हैं?

क्रम महत्वपूर्ण है। Account boundary environment label से पहले आती है। अगर request में `environment: production` है, लेकिन account ID या subscription ID नहीं है, तो वह अधूरी है। Agent से repository name, ticket title या उसकी मौजूदा terminal configuration देखकर missing detail का अनुमान लगाने को कहने के बजाय request अस्वीकार करें।

एक आम खराब सलाह कहती है कि account naming conventions इस समस्या को हल कर देती हैं। वे लोगों को सूची scan करने में मदद करती हैं, लेकिन control का काम नहीं करतीं। Names mutable strings हैं। Account ID, subscription ID, tenant ID, project number, cluster UID और role ARN provider द्वारा जारी references हैं, इसलिए identity के बारे में उनका दावा कहीं मजबूत होता है।

## Environment label को account नहीं चुनना चाहिए

Environment को execution के समय target resolve करने वाले input की तरह नहीं, बल्कि target record से जुड़ा controlled metadata मानें। इससे «यह production fix लागू करो» जैसी request live inventory में खोजकर किसी भी matching tag वाले account को चुनने से बचती है।

इस फर्क का व्यावहारिक असर है। आपके deployment catalog में `environment: production` वाले कई targets हो सकते हैं: payments, internal tools, regional services और acquisition के समय बने accounts। हर target अलग destination रहेगा। Agent को `aws-prod-payments` जैसे approved handle में से एक चुनना चाहिए, न कि `environment=production` जैसा broad selector भेजना चाहिए।

Actual boundary तय करने वाले provider identifiers इस्तेमाल करें:

| Provider | इससे bind करें | इस पर निर्भर न रहें |
| --- | --- | --- |
| AWS | Account ID, partition, role ARN, permitted region | Account alias, profile name, role display name |
| Azure | Tenant ID, subscription ID, ज़रूरत पड़ने पर resource group scope | Subscription display name, portal directory selection |
| Google Cloud | Project number और project ID, जहाँ प्रासंगिक हो वहाँ organization या folder | Project display name, active local configuration |

Google Cloud में project ID requests के लिए आम तौर पर पर्याप्त stable होता है, जबकि project number एक अतिरिक्त immutable check देता है। Azure में tenant और subscription दोनों चाहिए, क्योंकि subscription अकेले token जारी करने वाले identity context को नहीं बताता। AWS में account number अकेले यह नहीं बताता कि कार्रवाई कौन सा role इस्तेमाल करेगी। दोनों को bind करें।

इस जानकारी को prompt text में न छिपाएँ। Agent instruction में «production को कभी न छूना» लिख देने से वह credential नहीं रुकता जिसे कार्रवाई की अनुमति पहले से मिली है। Trusted executor के पास target record होना चाहिए और उसे तय करना चाहिए कि requested identity और destination उससे मेल खाते हैं या नहीं।

## Target registry में facts होने चाहिए, अनुमान नहीं

Executable cloud targets की छोटी और reviewed registry रखें। यह दूसरा IAM system नहीं है और इसे हर cloud permission दोहराने की कोशिश नहीं करनी चाहिए। Cloud IAM अब भी तय करता है कि कोई role API call कर सकता है या नहीं। Registry का सीमित सवाल है: इस target handle के साथ आने वाली request कहाँ जा सकती है?

यह उदाहरण fictional identifiers इस्तेमाल करता है, लेकिन इसकी संरचना जानबूझकर ऐसी रखी गई है:

```yaml
targets:
  aws-prod-payments:
    provider: aws
    environment: production
    account_id: "482901736154"
    partition: aws
    role_arn: "arn:aws:iam::482901736154:role/agent-payments-deploy"
    regions:
      - us-east-1
      - us-west-2

  azure-prod-fulfillment:
    provider: azure
    environment: production
    tenant_id: "2f34c630-1ce8-4ed3-a7ce-8a3286e799a1"
    subscription_id: "841742bf-9db5-4cf8-9f6b-f1778d5b7511"
    scopes:
      - "/subscriptions/841742bf-9db5-4cf8-9f6b-f1778d5b7511/resourceGroups/fulfillment-prod"

  gcp-prod-catalog:
    provider: gcp
    environment: production
    project_id: "catalog-prod-417"
    project_number: "548201736915"
    parent: "organizations/193847561029"
```

Registry को production configuration की तरह ownership दें। हर target के लिए accountable team, review path और account service से बाहर होने पर retirement date या status तय करें। वरना पुराने targets धीरे-धीरे उन जगहों का नक्शा बन जाते हैं जहाँ एजेंट अब भी पहुँच सकता है।

Free-form discovery से records बनाकर तुरंत execution की अनुमति न दें। Cloud inventory APIs उन accounts को खोजने में उपयोगी हैं जिन्हें owner चाहिए। वे authorization decisions नहीं हैं। Discovered account forensic copy, vendor-managed subscription, acquisition का बचा हुआ हिस्सा या ऐसा testing tenant हो सकता है जिसका production से confusing label मिलता हो।

Registry drift की एक सूक्ष्म समस्या भी रोकती है। कोई व्यक्ति Azure subscription या AWS role का नाम बदल सकता है, बिना immutable ID बदले। Readability के लिए display label बदल सकता है, जबकि binding वही रह सकती है। अगर immutable ID बदलती है, तो उसे review की ज़रूरत वाले नए target की तरह मानें, भले ही नाम वही रहे।

## Agent को handle माँगना चाहिए, destination बनाना नहीं

Agent को intent और target handle भेजना चाहिए। उसे command से copy किया गया role ARN, मनमाना cloud profile name या user-chosen subscription वाला shell command नहीं भेजना चाहिए। ये fields request के सबसे संवेदनशील हिस्से पर agent का नियंत्रण दे देती हैं।

Request इतनी सरल हो सकती है:

```json
{
  "request_id": "chg-8a31f6",
  "target": "aws-prod-payments",
  "operation": "aws.ec2.reboot_instances",
  "region": "us-east-1",
  "arguments": {
    "InstanceIds": ["i-0abc123def4567890"]
  },
  "reason": "Recover the failed checkout worker after approved release"
}
```

Executor अपने पास मौजूद record से `aws-prod-payments` को resolve करता है। वह केवल सूचीबद्ध role assume करता है, `eu-west-1` को अस्वीकार करता है क्योंकि वह record में नहीं है और चुनी गई account identity के साथ request भेजता है। इस exchange के हिस्से के रूप में agent को reusable cloud credential कभी नहीं मिलता।

जिस failure को यह रोकता है, उसे पहचानना आसान है। Agent `--profile prod` के साथ command चलाता है, लेकिन developer का local `prod` profile shared services account की ओर इशारा कर रहा होता है। Command syntactically सही है, API उसे स्वीकार कर लेती है और team को गलती तब पता चलती है जब अपेक्षित payment worker अब भी चल रहा होता है। Agent के बाहर resolve होने वाला target handle और उसके बाद identity check, reboot request executor से बाहर जाने से पहले command रोक देते हैं।

«Flexibility» के लिए handle और caller-supplied destination दोनों स्वीकार न करें। इससे दो sources of truth बनते हैं। अगर request में `target: aws-prod-payments` और अलग role ARN है, तो executor को request अस्वीकार करनी चाहिए। उसे अधिक specific दिखने वाली field को चुनना नहीं चाहिए।

## Write से पहले live caller की पुष्टि करें

Fixed target record ज़रूरी है, लेकिन इससे यह साबित नहीं होता कि active credential वही है जिसे आपने चुना था। Tokens expire होते हैं, role assumptions fail over हो सकते हैं, local profiles subprocesses में leak हो सकते हैं और cloud SDKs अनपेक्षित credential provider chains का इस्तेमाल कर सकते हैं। State-changing call से ठीक पहले live identity जाँचें।

AWS के लिए AWS का documentation बताता है कि `GetCallerIdentity` calling identity का account, ARN और user ID लौटाता है। Documentation यह भी बताता है कि explicit deny होने पर भी call ये details लौटाती है। इसलिए यह अच्छा diagnostic और preflight primitive है। यह कोई अन्य permission नहीं देता और expected record से तुलना की जगह नहीं लेता।

Preflight command का output कुछ ऐसा होगा:

```bash
aws sts get-caller-identity --output json
```

```json
{
  "UserId": "AROAEXAMPLEID:agent-run-8a31f6",
  "Account": "482901736154",
  "Arn": "arn:aws:sts::482901736154:assumed-role/agent-payments-deploy/agent-run-8a31f6"
}
```

`Account` की तुलना target के `account_id` से करें। ARN parse करके assumed role की तुलना configured role से करें। «ARN में payments आता है» जैसी substring test न करें। Write call से पहले अलग partition, account या role को अस्वीकार करें।

यही तरीका बाकी providers पर भी लागू करें। Azure में active tenant और subscription पूछें, फिर दोनों की तुलना selected target से करें। Google Cloud में active project और authenticated principal पूछें, फिर modifying API call से पहले project को target record से validate करें। ये checks उसी process context में चलने चाहिए जो action भेजता है। एक terminal में check करके दूसरे में execution करना केवल मन को तसल्ली देता है।

Preflight checks की एक सीमा है: role सही हो सकता है, लेकिन उसे जरूरत से ज़्यादा permissions मिली हो सकती हैं। Assigned target के लिए cloud role को least privilege की ज़रूरत फिर भी है। Binding request को अनपेक्षित account में जाने से रोकती है। IAM वहाँ पहुँचने के बाद सही account identity क्या कर सकती है, इसकी सीमा तय करता है। दोनों controls चाहिए।

## Broad cross-account roles गलती को देर तक छिपाए रखते हैं

हर account में assume किए जा सकने वाले एक administrator role को लोग setup कम करने के लिए पसंद करते हैं। लेकिन इससे target selection एक high-risk, लगभग irreversible decision बन जाता है। Agent या executor गलत account चुने तो वही broad identity अक्सर गलती पूरी करने के लिए पर्याप्त access रखती है।

Account और purpose के आधार पर अलग execution roles रखें। Payments के लिए production deployment role को analytics, identity या disaster recovery accounts में trust path नहीं मिलना चाहिए। अगर agent को कई accounts में read access चाहिए, तो अलग read roles इस्तेमाल करें और हर call के लिए target binding को स्पष्ट रखें। Read access customer data, infrastructure topology और गलत जगह रखे credentials उजागर कर सकता है। केवल read-only कह देने से selection errors harmless नहीं हो जाते।

Role assume करने के तरीके को सीमित करने के लिए cloud-native trust conditions इस्तेमाल करें। AWS role trust policies trusted principal को सीमित कर सकती हैं और जहाँ caller के लिए उपयुक्त हो वहाँ external ID अनिवार्य कर सकती हैं। Azure workload identities को federated credential claims और resource role assignments से सीमित किया जा सकता है। Google Cloud service account impersonation में access token mint करने वालों को सीमित किया जा सकता है। Mechanism अलग हैं, लेकिन design वही है: एक execution identity एक reviewed destination और purpose से जुड़ी हो।

Central broker identity को broad authority न समझें। Broker कई targets के requests coordinate कर सकता है, जबकि हर request target-specific identity हासिल करे। Universal administrator role की तुलना में setup अधिक होगा, लेकिन process, prompt या integration में गलती होने पर blast radius स्पष्ट रहेगा।

## Approval में वह destination दिखना चाहिए जिसे इंसान जाँच सके

अगर approval account boundary छिपा देती है, तो इंसान safe action approve नहीं कर सकता। «Production में checkout worker restart करो» reviewer से invisible resolution logic पर भरोसा करने को कहता है। Approval में target handle, environment label, immutable account identifier, active role या service identity, operation और API से प्रभावित होने वाला resource scope दिखना चाहिए।

AWS instance reboot के लिए उपयोगी approval ऐसी होगी:

```text
Target: aws-prod-payments
Environment: production
Account: 482901736154
Identity: agent-payments-deploy
Action: ec2:RebootInstances
Region: us-east-1
Resource: i-0abc123def4567890
Reason: Recover failed checkout worker after approved release
```

यह approval दिखावा नहीं है। Reviewers अक्सर अपने service का account number या target handle जानते हैं, जबकि agent का prose description विश्वसनीय लगते हुए भी गलत हो सकता है। Destination को action description से पहले और इतना स्पष्ट दिखाएँ कि उसे जल्दी scan किया जा सके। लोग command payload में छिपे subtle mismatch की तुलना में surprising account number अधिक आसानी से देखते हैं।

जब session कई production accounts में फैला हो, तब «इस session का सारा काम» approve न कराएँ। एक session की legitimate boundary हो सकती है, जैसे एक deployment target पर बार-बार changes करना, लेकिन वह चुपचाप बड़ी नहीं होनी चाहिए। Target handle बदलने पर, operation read से write होने पर या request reviewer द्वारा approved scope से अधिक sensitive होने पर fresh approval माँगें।

Sallyport का per-session authorization connecting process की पहचान करता है और इसकी per-call credential setting हर use पर approval माँग सकती है। इसका लाभ तभी है जब action request में ऐसा target हो जिसे reviewer पहचान सके और executor उसे पहले ही एक destination से bind कर चुका हो।

## Logs को intent, identity और provider evidence जोड़ना चाहिए

Cloud audit logs बताते हैं कि किस identity ने API call की, लेकिन वे आम तौर पर agent का instruction, target selection या reviewer का decision नहीं बताते। Agent-side records intent समझा सकते हैं, लेकिन यह साबित नहीं करते कि cloud को expected call मिली। दोनों records रखें और request ID तथा immutable target identifiers से उन्हें जोड़ें।

हर action के लिए execution से पहले और बाद में ये fields दर्ज करें:

- Request करने वाला agent process या session
- चुना गया target handle और उससे resolve हुए immutable identifiers
- Preflight के दौरान देखी गई execution identity
- Operation, resource scope, result और request ID
- Provider द्वारा दिया गया provider audit event reference

AWS CloudTrail, Azure Activity Log और Google Cloud Audit Logs provider-side activity capture करते हैं, बशर्ते इस्तेमाल की गई services और logging configuration उन्हें support करें। इन records को अपनी अलग security boundary में रखें। Agent activity log को provider evidence का विकल्प न मानें, क्योंकि compromised local process उस request के बारे में झूठ बोल सकता है जिसे उसने कभी पूरा नहीं किया।

Sallyport agent runs और individual calls को अलग journals में दर्ज करता है, जो encrypted, hash-chained audit log से project किए जाते हैं। इसका `sp audit verify` command ciphertext पर offline उस chain की पुष्टि कर सकता है। Incident के बाद local action records में बदलाव हुआ है या नहीं, यह जाँचने में इससे मदद मिलती है।

व्यावहारिक test एक investigation drill है। कोई approved change चुनें और engineer से बिना अनुमान लगाए चार सवालों के जवाब माँगें: किस agent process ने request की, उसने कौन सा target चुना, किस cloud identity ने उसे execute किया और कौन सा provider-side event उसकी पुष्टि करता है। अगर किसी भी जवाब के लिए तीन consoles के timestamps को हाथ से मिलाना पड़े, तो आपके records पर्याप्त मजबूत नहीं हैं।

## Wrong-account incident आम तौर पर API call से पहले शुरू होता है

दिखाई देने वाली failure अक्सर गलत account में हुआ production change होती है। उससे पहले की failure आम तौर पर uncontrolled resolution path होती है। Incident को केवल उस व्यक्ति की गलती न मानें जिसने «गलत profile इस्तेमाल की»। इसे binding defect मानें।

एक संभव sequence देखें। Repository में ऐसी script है जो `ENV=prod` स्वीकार करती है। उसका wrapper इसे `prod` नाम के AWS profile में बदलता है। Migration के दौरान एक developer ने उस profile को shared services account की ओर कर दिया, क्योंकि पुराने payments account तक direct access की अब ज़रूरत नहीं थी। बाद में agent को payment worker restart करने की request मिलती है। वह script खोजता है, `ENV=prod` set करता है और उसे चलाता है। Script का profile resolution shared services चुनता है। Team ने operational convenience के लिए role को broad EC2 permissions दे रखी हैं। Reboot गलत account में सफल हो जाता है।

Cloud API का कोई हिस्सा confused नहीं था। Script ने valid identity के साथ valid request की। Incident के बाद केवल agents को «account दोबारा जाँचने» को कहना फिर failure देगा, क्योंकि वही resolution path मौजूद रहेगा।

इस तरह की failure को इस क्रम में ठीक करें:

1. प्रभावित session या role path disable करें और agent तथा cloud audit records सुरक्षित रखें।
2. उस exact selector की पहचान करें जिसने गलत destination चुना, जैसे profile name, default subscription, environment tag या caller-supplied role ARN।
3. Selector को executor द्वारा resolve किए गए approved target handle से बदलें।
4. Live identity comparison जोड़ें, जो writes से पहले हर mismatch को अस्वीकार करे।
5. अगर broad role ने असंबंधित account actions की अनुमति दी थी, तो उसे अलग करें।

फिर rejection path को जानबूझकर test करें। Staging target को किसी दूसरे test account की credential की ओर point करें और पुष्टि करें कि modifying API call से पहले executor रुक जाता है। Teams अक्सर success paths test करती हैं, लेकिन यह कभी साबित नहीं करतीं कि account binding fail closed होती है।

## Rollout सबसे जोखिमपूर्ण writes से शुरू करना बेहतर होता है

खतरनाक actions पर explicit binding लगाने से पहले complete cloud inventory का इंतज़ार न करें। उन operations से शुरू करें जो production state बदल या उजागर कर सकते हैं: deployments, identity changes, network edits, data exports, secret rotation और destructive infrastructure commands। Read-only discovery registry बनाने में मदद कर सकती है, लेकिन नए मिले accounts को चुपचाप execution access नहीं देना चाहिए।

पहले उन accounts की सूची बनाएँ जिन्हें ये actions मिल सकती हैं और हर account को स्पष्ट environment label तथा owner दें। इसके बाद हर account-purpose pair के लिए target record बनाएँ। फिर ऐसा executor path तैयार करें जो handles resolve करे, target-specific credentials हासिल करे, live identity verify करे और action record लिखे। अंत में ambient profiles, default subscriptions और credential files तक agent की direct access हटा दें।

उन engineers की आपत्ति की अपेक्षा रखें जो terminal में एक variable से accounts बदलने के आदी हैं। यह आदत तेज़ है क्योंकि context व्यक्ति की memory में चला जाता है। Autonomous agent के पास वह memory नहीं होती और उसके actions review करने वाले लोगों के पास भी नहीं। Context को request, target registry और execution evidence में रखें।

अगर action चलने से पहले आप account number, execution identity और resource scope नहीं बता सकते, तो agent के पास सुरक्षित रूप से काम करने के लिए पर्याप्त जानकारी नहीं है। उससे missing facts इकट्ठा करने को कहें या action इंसान के पास रखें।
