# सुरक्षित apply के लिए AI agent infrastructure permissions

AI agents को ऐसी स्थायी permission नहीं मिलनी चाहिए जिसका अर्थ हो «infrastructure changes apply करो»। उन्हें सीमित और जल्दी समाप्त होने वाला authorization मिलना चाहिए, जो एक reviewed change को एक verified target account पर apply करने तक सीमित हो। साथ में recovery procedure भी हो, जिसे operator ने पढ़कर स्वीकार किया हो।

मैंने teams को Terraform plan को safety control और approval button को decision समझने की गलती करते देखा है। इनमें से कोई भी अकेले पर्याप्त नहीं है। किसी दूसरे account के विरुद्ध plan फिर से बनाया जा सकता है। बदले हुए commit के बाद भी approval जारी रह सकती है। Rollback note «revert» कह सकता है, जबकि बदलाव data मिटाता हो या ऐसी dependency बदलता हो जो अब मौजूद ही न हो।

सही सीमा इससे अधिक सख्त है: agent evidence तैयार करे, व्यक्ति उस evidence की समीक्षा करे और execution path तब आगे बढ़ने से इनकार कर दे जब evidence उस action का सही वर्णन न करे। यह पहली बार तक जरूरत से ज्यादा सावधानी जैसा लग सकता है, जब कोई assistant गलत cloud profile inherit कर ले, stale state snapshot पढ़े और पूरी तरह सही command को production पर चला दे।

## Permission job title से नहीं, action से जुड़ी होनी चाहिए

AI agent infrastructure permissions को किसी ठोस mutation की अनुमति देनी चाहिए, «deploy», «Terraform» या «production operations» जैसी category की नहीं। Broad categories सुविधाजनक लगती हैं क्योंकि लोग roles में सोचते हैं। Cloud APIs requests चलाती हैं, और हर request का target, parameters, identity और परिणाम होता है।

एक उपयोगी apply authorization कम से कम इन तथ्यों से जुड़ा होना चाहिए:

- Immutable source revision और वह configuration directory जिससे plan बनाया गया।
- Reviewed plan artifact या उसका SHA-256 digest।
- Execution credential द्वारा बताई गई target cloud account या tenant identity।
- Execution identity, role, subscription, project और जरूरत के अनुसार allowed region।
- Expiry और recovery reference, जो बताए कि apply रोकने या उलटने पर क्या होगा।

किसी बदलाव की *गणना* करने की permission और उसे *करने* की permission अलग हैं। Agent को repositories देखने, read-only APIs call करने, validation चलाने और plan प्रस्तावित करने दें। इन activities को चुपचाप production में mutation की अनुमति न समझें। Discovery access operational detail उजागर कर सकता है। Mutation access bill, availability और कभी-कभी incident के बाद उपलब्ध evidence को बदल देता है।

`InfrastructureDeployer` नाम का role approval object नहीं है। यह implementation detail है। अगर इसे पाने वाला process हर account में कभी भी कुछ भी apply कर सकता है, तो आपका approval process इस बात पर निर्भर है कि लोग इसे सही तरह इस्तेमाल करना याद रखें। Agents इतने तेज हैं कि यह memory test जल्दी incident बन सकता है।

## Reviewed plan वही exact artifact होना चाहिए जिसे apply किया जाए

Reviewed plan तभी उपयोगी है जब apply command उसी plan को consume करे। किसी के output को मंज़ूरी देने के बाद `terraform plan` फिर चलाना नया artifact बनाता है, भले files बदली हुई न दिखें।

Terraform के command documentation में यह अंतर साफ है। `terraform plan -out=FILE` ऐसा plan file लिखता है जिसे `terraform apply FILE` के लिए इस्तेमाल किया जाना है। इसके विपरीत, बिना saved plan के `terraform apply` confirmation मांगने से पहले नया plan बनाता है। Interactive human session के लिए दूसरा रूप ठीक है। उस agent workflow में यह गलत है जिसमें दावा किया जाता है कि proposed changes की human review हुई है।

Saved plan इस्तेमाल करें और उसे review के लिए JSON में render करें। एक न्यूनतम shell sequence ऐसा दिखता है:

```sh
set -euo pipefail

git rev-parse HEAD \u003e evidence/source-revision.txt
terraform init -lockfile=readonly
terraform plan -out=evidence/change.tfplan
terraform show -json evidence/change.tfplan \u003e evidence/change.json
shasum -a 256 evidence/change.tfplan \u003e evidence/change.tfplan.sha256
terraform providers lock -platform=darwin_arm64
```

Output digest का सरल रूप:

```text
f1f5f2...a94c  evidence/change.tfplan
```

Approval record में terminal का screenshot जोड़ने के बजाय पूरा digest copy करें। Execution से पहले apply runner उसे verify करे:

```sh
shasum -a 256 -c evidence/change.tfplan.sha256
terraform apply -input=false evidence/change.tfplan
```

इससे एक आम failure रुकता है: agent pull request खोलता है, plan बनाता है, approval comment पाता है, फिर latest main branch fetch करके fresh plan चलाता है। इन actions के बीच किसी colleague ने अलग change merge किया हो सकता है। बाद का plan deletion जोड़ सकता है, image version बदल सकता है या किसी दूसरे provider alias की ओर इशारा कर सकता है। Reviewer ने कल के proposed graph को मंज़ूर किया था, runner को अभी जो दिख रहा है उसे नहीं।

Binary Terraform plan में sensitive values हो सकती हैं। उसे tickets या chat में paste न करें। Provider schemas और values के आधार पर JSON representation भी sensitive material दिखा सकती है, इसलिए redaction केवल ऐसी review process से करें जिसे आप अच्छी तरह समझते हों। Redaction से resource addresses, actions, target identity या dependency changes नहीं हटने चाहिए। Approver को ठीक इन्हीं तथ्यों की जरूरत होती है।

Saved-plan pattern तब सबसे मजबूत होता है जब execution environment भी pinned हो। उसी provider lock file, Terraform version, variables, backend configuration और workspace selection का इस्तेमाल करें जिससे plan बनाया गया था। इनमें से कोई input बदल जाए तो plan फेंक दें और नया review package बनाएं। पुरानी approval बचाने की कोशिश sensible control को दिखावे में बदल देती है।

## Named target label से नहीं, credential से आना चाहिए

`prod` नाम का target लगभग कुछ साबित नहीं करता। Repositories directory names copy करती हैं। Workspaces अलग-अलग हो जाते हैं। Environment variables shells में रह जाती हैं। Agent production नाम वाले configuration को सही तरह follow कर सकता है, जबकि authentication sandbox के साथ हो, या इससे भी बुरा, inherited profile से चुने गए production account के साथ।

Execution identity से planning से पहले और apply से ठीक पहले cloud control plane से पूछें कि वह कौन है। Result को evidence package में रखें और approved target से compare करें।

AWS-based action में check इतना सीधा हो सकता है:

```sh
aws sts get-caller-identity --output json \u003e evidence/caller-identity.json
cat evidence/caller-identity.json
```

Result account और principal की पहचान करता है:

```json
{
  "UserId": "AROAXXXXX:apply-run",
  "Account": "123456789012",
  "Arn": "arn:aws:sts::123456789012:assumed-role/InfraApply/apply-run"
}
```

Google Cloud के लिए active account और project अलग-अलग दर्ज करें। Azure के लिए credential context से subscription ID और tenant ID दर्ज करें। Cloud account display name पर निर्भर न करें, क्योंकि लोग वही names दोबारा बना सकते हैं। Numeric या globally unique identifiers पढ़ने में कम सुविधाजनक हैं, लेकिन execution को ज्यादा सुरक्षित बनाते हैं।

Pre-apply check में वही credential path इस्तेमाल होना चाहिए जो apply में होगा। बात स्पष्ट लगती है, फिर भी wrappers अक्सर इसका उल्लंघन करते हैं। Planning script short-lived assumed role इस्तेमाल कर सकती है, जबकि बाद की command developer की default profile inherit कर लेती है। Remote runner को call करने वाला agent locally plan बना सकता है, लेकिन remotely ऐसी service identity के तहत apply कर सकता है जिसकी उसने जांच नहीं की।

Runner में machine-checkable target assertion रखें। यह उदाहरण unexpected AWS account को अस्वीकार करता है:

```sh
expected_account="123456789012"
actual_account="$(aws sts get-caller-identity --query Account --output text)"

if [ "$actual_account" != "$expected_account" ]; then
  printf 'refusing apply: expected account %s, got %s\\n' \
    "$expected_account" "$actual_account" \u003e\u00262
  exit 1
fi
```

यह check human review की जगह नहीं लेता। यह एक पूरे वर्ग की गलतियों को किसी API call द्वारा infrastructure बदलने से पहले पकड़ता है। इसे provider configuration के साथ रखें, जिसमें provider support होने पर allowed account या subscription घोषित हो। Provider-level assertion और runner-level assertion स्वतंत्र रूप से fail हों, यही अपेक्षित है।

## State drift पुरानी approvals को असुरक्षित बना देता है

Plan किसी खास observed state के सापेक्ष desired change बताता है। वह यह वादा नहीं करता कि एक घंटे बाद भी वही state मौजूद होगी।

कोई दूसरा engineer deploy कर सकता है। Autoscaler resources जोड़ या हटा सकता है। Cloud service attachment rotate कर सकती है, node replace कर सकती है या asynchronous operation पूरा कर सकती है। Terraform refresh के दौरान इनमें से कुछ बदलाव पकड़ लेगा, लेकिन material difference मिलने पर सुरक्षित प्रतिक्रिया यह नहीं है कि पहले plan छोटा दिख रहा था इसलिए आगे बढ़ जाएं। नया artifact बनाएं और नया diff review करें।

Expiry इस समस्या का बड़ा हिस्सा संभालती है। Approval इतनी छोटी अवधि की रखें कि human को अब भी याद हो कि उसने इसे क्यों स्वीकार किया था। सही अवधि आपके release process पर निर्भर है, लेकिन default रूप से पूरे workday के बजाय एक तय execution window तक सीमित होनी चाहिए। Window बंद होने पर नया plan बनाएं, target verification दोहराएं और fresh approval लें।

Invalidation rule भी चाहिए। Review के बाद इनमें से कोई बदलाव हो तो plan अस्वीकार करें:

- Source revision, variable set, module reference या provider lock file बदल जाए।
- Workspace, backend, account, subscription, tenant, project या region approved evidence से अलग हो।
- Plan digest approval record से मेल न खाए।
- Relevant state lock, refresh या precondition ऐसा conflict बताए जो proposed action बदलता हो।

इस rule की जगह «pull request में कोई बदलाव नहीं» को इस्तेमाल न करें। External data sources, provider defaults, current state और credentials diff के बाहर होते हैं। Infrastructure work में source-only approval के लिए inputs बहुत ज्यादा हैं।

कुछ teams drift रोकने के लिए agent को तब तक automatic replan करने देती हैं जब तक plan clean न हो जाए। यह सलाह queue time घटाती है, इसलिए लोकप्रिय है। Consequential accounts के लिए यह गलत है। Automatic replanning reviewed update को unreviewed replacement बना सकती है। Read-only preview के लिए automatic replanning रखना चाहें तो रखें, लेकिन mutation से पहले फिर human review जरूरी हो।

## Rollback को recoverable state बतानी चाहिए

साफ rollback path बताता है कि operators service को acceptable condition में कैसे लौटाएंगे, कौन यह कर सकता है, data पर क्या जोखिम है और कब रुकना चाहिए। «Run Terraform destroy» और «revert the commit» आम तौर पर इस standard को पूरा नहीं करते।

Infrastructure changes की recovery classes अलग होती हैं। इन्हें एक जैसा मानना झूठा भरोसा पैदा करता है।

Security-group rule या load-balancer weight जैसा reversible configuration change known good revision से direct inverse apply की अनुमति दे सकता है। Instance group replacement से पहले reversal के लिए capacity checks जरूरी हो सकते हैं। Database migration data लिखने के बाद irreversible हो सकती है, इसलिए recovery path forward migration, verified backup से restore या new writes रोकने वाले feature flag का इस्तेमाल हो सकता है।

Rollback path operational language में लिखें। एक उपयोगी record इन सवालों के जवाब देता है:

1. कौन सी observable condition rollback का संकेत देती है, जैसे failed health checks, बढ़ती error rates या failed smoke test?
2. कौन सा exact revision, parameter set या command service को known good configuration में लौटाता है?
3. पहले कौन सी prerequisite मौजूद होनी चाहिए, जैसे backup restore point, spare capacity या approved maintenance window?
4. Agent session समाप्त होने या original approver के अनुपलब्ध होने पर action लेने का अधिकार किसके पास है?
5. क्या अपने-आप restore नहीं किया जा सकता, जैसे records, secrets, public addresses या manual cloud changes?

Recovery path incident से पहले test होना चाहिए, उस समय लिखे गए optimistic sentence के रूप में नहीं। अगर team किसी change को reversible कहती है, तो representative environment में reversal चलाएं और उसे सफल बनाने वाली conditions दर्ज करें। Providers deleted resource name सुरक्षित रख सकते हैं, quotas recreation रोक सकते हैं और dependent services पुराना endpoint cache कर सकती हैं। ये बातें दबाव के समय सामने आती हैं।

Destructive changes के लिए अलग decision लें। Plan review के बाद resource delete करना उसे update करने के बराबर नहीं है। Agent को deletion addresses, replacement actions, retention settings और backup evidence ऐसे रूप में दिखाने चाहिए जो सैकड़ों harmless updates के बीच गायब न हो सकें। अगर change में database, object store, identity binding, network boundary या DNS zone शामिल है, तो recovery owner से plan पढ़वाएं।

## Apply runner को ambiguity अस्वीकार करनी चाहिए

Mutation करने वाला runner approval facts को खुद enforce करे। «go ahead» कहने वाला chat message मिलने पर bot के पास confirmed plan और casual instruction में अंतर करने का भरोसेमंद तरीका नहीं होता।

Structured approval record इस्तेमाल करें। यह signed deployment system, protected repository record या किसी अन्य controlled store में रह सकता है। Storage choice से ज्यादा जरूरी fields और verification हैं। यह illustrative JSON उसका रूप दिखाता है:

```json
{
  "change_id": "infra-2025-041",
  "source_revision": "4ad7d2f",
  "plan_sha256": "f1f5f2...a94c",
  "target": {
    "cloud": "aws",
    "account_id": "123456789012",
    "region": "us-east-1",
    "workspace": "production"
  },
  "approved_by": "operator-id",
  "expires_at": "2025-04-18T15:30:00Z",
  "rollback_ref": "runbook: payments-api capacity revert"
}
```

Agent यह request तैयार कर सकता है, लेकिन `approved_by` नहीं लिखना चाहिए और `expires_at` बढ़ाना नहीं चाहिए। व्यक्ति को rendered change दिखने के बाद approval service इन facts को जोड़े। Apply runner record पढ़े, plan digest फिर से निकाले, source revision और target identity जांचे, फिर पहला write request भेजने से पहले authorization को consumed mark करे।

Approval consume करना जरूरी है। इसके बिना environment बदलने के बाद agent approved action को फिर चला सकता है। Failed apply की भी स्पष्ट status होनी चाहिए। केवल command जारी हो जाने से उसे complete न मानें। दर्ज करें कि Terraform ने success लौटाया या नहीं, cloud API operation अभी pending है या नहीं और operator ने resulting state स्वीकार की या नहीं।

Agent की write surface सीमित रखें। Deployment APIs के लिए उसे HTTP calls या controlled runner तक SSH access की जरूरत हो सकती है, लेकिन उसे context में reusable cloud secret कभी न दें। Sallyport API और SSH credentials को अपने encrypted vault में रखता है, requested action करता है और result agent को लौटाता है। इससे credential copying का जोखिम घटता है, लेकिन अस्पष्ट apply request सुरक्षित नहीं हो जाती।

## Per-call approval खतरनाक सीमा के आसपास होनी चाहिए

Infrastructure work में per-call approval का स्थान है, लेकिन यह artifact review की जगह नहीं ले सकती। अगर agent हर cloud API request पर permission मांगे, तो operators aggregate result समझे बिना लंबी sequence मंज़ूर करने लगेंगे। यह approval fatigue है और लोगों को एकमात्र control पर बिना सोचे click करना सिखाती है।

Human intervention वहीं रखें जहां वह meaningful decision लेती है: target से जुड़े plan को approve करना और bounded apply run की अनुमति देना। Unusual blast radius वाले actions के लिए individual confirmations रखें, जैसे secret rotation, protected object deletion, break-glass access या expected runner contract से बाहर की command।

Sallyport का per-session authorization यह तय कर सकता है कि कोई specific agent process अपने current run के दौरान action channel इस्तेमाल कर सकता है। Per-call keys sensitive credentials के लिए अलग confirmation मांग सकती हैं। यह साफ credential boundary है। फिर भी deployment workflow को तय करना होगा कि कौन सी call approved apply मानी जाएगी और किन credentials पर per-call friction चाहिए।

Human को raw provider traffic पढ़े बिना decision लेने के लिए पर्याप्त evidence दिखना चाहिए। Action के अनुसार grouped resource addresses, replacements और deletions अलग-अलग, target identity, source revision, digest, expiry और rollback reference दिखाएं। जरूरत पड़ने पर full plan उपलब्ध कराएं। सौ updates के नीचे destructive change छिपाना presentation failure है, operator failure नहीं।

## Failed apply के लिए successful apply से अलग decision चाहिए

Terraform कई resources बदलने के बाद failure लौटा सकता है। Cloud control planes request स्वीकार करके उसे बाद में भी पूरा कर सकते हैं। हर nonzero exit status को «कुछ नहीं हुआ» मानना automated operations की खतरनाक आदतों में से एक है।

Apply fail होने पर automatic retries रोक दें। Runner output, state lock information, target identity और failed operation में पूरे हुए resources का subset सुरक्षित रखें। फिर response चुनने से पहले actual environment की जांच करें। Blind retry partial failure बढ़ा सकती है, जबकि तत्काल rollback उस intermediate resource को हटा सकता है जिसे provider अभी बना रहा हो।

इस decision sequence का इस्तेमाल करें:

1. Current cloud identity confirm करें और failed operation में नामित हर resource का actual status लें।
2. तय करें कि desired state को पूरा करना सुरक्षित है, reverse करना सुरक्षित है या repair plan चाहिए।
3. Current state से fresh plan बनाएं और operator से इसे नए change की तरह review करवाएं।
4. Original approval के साथ incident decision दर्ज करें, जिसमें Terraform से represent न होने वाले manual actions भी हों।

यहीं audit records उपयोगी साबित होते हैं। Source revision, plan digest, approval identity, target evidence, command transcript, resulting state और follow-up decision को साथ रखें। Tamper-evident event trail chat threads में बंटे screenshots से बेहतर है, क्योंकि responders को sequence समझनी होती है, memory से intent का अनुमान नहीं लगाना।

यह वादा न करें कि automation हर failed apply को undo कर देगी। कुछ changes के लिए ऐसा human चाहिए जो service dependency, data durability और customer impact समझता हो। Agent तेजी से evidence जुटा सकता है। Pipeline को green result चाहिए इसलिए उसे recovery operation गढ़ने की अनुमति नहीं होनी चाहिए।

## First production rollout जानबूझकर नीरस रखें

पहला agent-mediated production apply छोटा, reversible और observable होना चाहिए। ऐसी known configuration adjustment चुनें जिसकी recovery procedure पहले से test हो चुकी हो। Migration, networking redesign या कई consumers को छूने वाली secret rotation से शुरुआत न करें।

सामान्य conditions में पूरा workflow चलाएं: evidence package बनाएं, exact account verify करें, rendered plan review करें, digest approve करें, saved artifact apply करें, result जांचें और authorization consume करें। फिर controlled failure drill करें। Approval expire करें, source revision बदलें या runner को nonapproved account की ओर point करें और पुष्टि करें कि runner action से इनकार करता है।

ये refusal tests successful happy-path deployment से अधिक महत्वपूर्ण हैं। Account, plan और state संयोग से मिल रहे हों तो हर tool disciplined दिखता है। Control तब साबित होता है जब rushed operator, stale artifact या confused agent गलत काम करने को कहे और वह रुक जाए।

First rollout धीमा लगे तो permission model को व्यापक न बनाएं। देखें review time कहां जा रहा है। अगर लोग account identifiers compare करने में समय लगाते हैं, evidence display सुधारें। Plans में बहुत unrelated churn हो तो module ownership या state boundaries ठीक करें। Rollback notes कमजोर हों तो service teams से उन्हें लिखवाएं और test करवाएं। Broad standing access awkward release process का इलाज नहीं है, वह केवल कमजोरी को तब तक छिपाता है जब तक कोई agent उस तक नहीं पहुंच जाता।
