# क्या credential placeholders अब भी operational details उजागर करते हैं?

Redacted credential देखने वाले किसी भी व्यक्ति को आपकी production layout की जानकारी दे सकती है। Teams अक्सर token को `***` से बदलकर संतुष्ट हो जाती हैं, लेकिन tenant subdomain, administrator role, region, account number, secret path और injection syntax वैसे ही छोड़ देती हैं। Token निजी रहा, operating model नहीं।

यह अंतर खास तौर पर तब महत्वपूर्ण होता है जब configurations, logs, prompts, tickets और agent transcripts credentials से कहीं आगे तक पहुँचते हों। किसी determined intruder को एक screenshot में सारे secrets नहीं चाहिए। उसे इतना सटीक विवरण चाहिए कि वह target चुन सके, workflow की नकल कर सके, विश्वसनीय support request लिख सके या एक foothold को उपयोगी map में बदल सके।

## अलग blast radius वाला metadata है placeholder

Credential value possession साबित करती है। आम तौर पर placeholder ऐसा नहीं करता। इसलिए दोनों तरह का data अलग है, लेकिन placeholder harmless नहीं हो जाता।

यह deployment fragment देखें:

```yaml
billing_export:
  url: https://acme-prod.eu.example.net/v2/exports
  authorization: Bearer ${ACME_PROD_EU_BILLING_ADMIN_TOKEN}
  tenant: northstar-retail
  credential_ref: vault://teams/finance/prod/billing-export-admin
```

यहाँ raw token नहीं है। फिर भी reader जान जाता है कि organization का Europe में production tenant है, वह export API चलाती है, finance credentials अलग रखती है, vault इस्तेमाल करती है और billing exports के लिए administrator-grade identity रखती है। `northstar-retail` किसी customer की पहचान हो सकता है। Hostname दूसरी services पर लागू naming convention दिखा सकता है। Vault path बताता है कि credential का मालिक संभवतः कौन-सा group है और किसी internal developer tool पर कब्ज़ा होने के बाद attacker कहाँ देख सकता है।

Security reviews अक्सर इसे binary सवाल तक सीमित कर देती हैं: «क्या इसमें secret है?» यह सवाल बहुत छोटा है। इसके बजाय दो सवाल पूछें:

1. क्या कोई इस value से authenticate कर सकता है या कोई action authorize कर सकता है?
2. क्या कोई इस value से हमारे operation को समझ, target, impersonate या correlate कर सकता है?

पहले जवाब से पता चलता है कि credential leak हुआ है या नहीं। दूसरे से पता चलता है कि operational metadata उजागर हुआ है या नहीं। दोनों के लिए controls चाहिए, लेकिन controls अलग होंगे। हर alias को password मानने से logs अनुपयोगी हो जाते हैं। हर alias को public मानने से reconnaissance material अनजाने में बाहर निकलता है।

AWS IAM documentation Amazon Resource Names के बारे में यह अंतर साफ़ बताती है। ARN partition, service, region, account ID, resource type और resource ID जैसे fields से resource की पहचान करता है। AWS कहता है कि ARN credentials नहीं हैं, और यह सही है। लेकिन वही documentation दिखाती है कि उनमें उपयोगी structural information क्यों हो सकती है। Resource reference cloud partition, regional placement, owning account, service और resource name या path बता सकता है। «Secret नहीं» का अर्थ «हर audience के लिए सुरक्षित» नहीं होता।

## Aliases अक्सर ownership और privilege बताते हैं

Aliases इसलिए बनाए जाते हैं ताकि लोग याद रख सकें कि credential क्या करता है। यही सुविधा context leak करती है।

`STRIPE_TOKEN` provider के अलावा बहुत कम बताता है। `PROD_US_CARD_REFUNDS_SUPERVISOR_TOKEN` बहुत कुछ बताता है। इससे production, geography, card payments, refunds, संभावित business function और elevated authority का संकेत मिलता है। Incident channel में label देख चुका attacker सही system को सही vocabulary से refer कर सकता है। इससे किसी technical exploit से पहले ही phishing, pretexting और social engineering बेहतर हो जाती है।

सबसे जोखिम वाले names में ये चार तरह की जानकारी मिलती हैं:

- Environment: `prod`, `staging`, `dr`, `sandbox`
- Authority: `admin`, `root`, `write`, `breakglass`
- Business function: `payroll`, `claims`, `refunds`, `identity`
- Tenant या owner: customer name, acquisition code, team name या account number

Label relationships भी दिखा सकता है। `SALESFORCE_TO_ERP_SYNC_PROD` से पता चलता है कि दो systems data exchange करते हैं। `PAYROLL_SFTP_VENDOR_A` external transfer path का संकेत देता है। `EMERGENCY_DB_RESTORE_KEY` ऐसे credential की पहचान करता है जिसे असली value तक पहुँचे बिना भी target करना worthwhile होगा।

हर credential को meaningless random name देना और समस्या खत्म मान लेना समाधान नहीं है। Operators को पता होना चाहिए कि वे किस चीज़ को approve, rotate और debug कर रहे हैं। सही तरीका audience के अनुसार human-facing name अलग रखना है।

Restricted credential registry में detailed record रखें। उसमें credential का owner, वह किस account तक पहुँचता है, क्या कर सकता है और क्यों मौजूद है, यह लिखा जा सकता है। CI output, agent prompts या approval cards जैसे broad surfaces में कम descriptive runtime alias रखें। उदाहरण:

```text
Restricted registry record
Owner: Revenue systems
Purpose: Submit production refund adjustments
Target: payments tenant northstar-retail in EU
Authority: write refund adjustments
Runtime alias: cred_4d91

Broad operational event
credential=cred_4d91 action=refund_adjustment outcome=denied
```

Runtime alias correlation के लिए पर्याप्त है। Responder `cred_4d91` से जुड़ी बार-बार होने वाली failures खोज सकता है, जबकि केवल registry access वाले लोग उसे पूरे business context से जोड़ सकते हैं।

चयन सोच-समझकर करें। Approval dialog को बताना पड़ सकता है कि action production refunds बदलेगा, क्योंकि human से consequence छिपाने पर approval का उद्देश्य ही खत्म हो जाता है। लेकिन निर्णय के लिए customer tenant, cloud account identifier, vault path या credential name दिखाना ज़रूरी नहीं है।

## Formats redaction rules की अपेक्षा से अधिक बताते हैं

Fixed format देखने वाले को बता सकता है कि value किस system ने बनाई, उसे कैसे validate करना है और दूसरी जगह किन fields को खोजना चाहिए।

इन references को देखें:

```text
arn:aws:iam::123456789012:role/ci-prod-deployer
projects/810245991002/secrets/payments-prod-api/versions/latest
https://tenant-44.api.vendor.example/v1/invoices
postgresql://reporting:${DB_PASSWORD}@db-prod-2.internal:5432/revenue
```

हर case में password गायब हो सकता है, लेकिन बची हुई syntax अलग-अलग बातें बताती है। ARN cloud partition, service, account structure और role name दिखाता है। Secret-manager reference project, secret purpose और versioning practice बताता है। API hostname tenant model दिखाता है। Database connection shape protocol, host naming scheme, port, database name और password injection point की पहचान कराती है।

RFC 3986 URI के मुख्य हिस्से, जैसे scheme, authority, host, port, path, query और fragment परिभाषित करता है। यह `user:password@host` वाले URI user information form को deprecated बताता है और applications को पहले colon के बाद के data को clear text में render न करने की चेतावनी देता है। व्यावहारिक सीख literal passwords से आगे जाती है: URI कई fields वाला container है और एक field mask करने से बाकी operational story मिटती नहीं।

Formats दो गलतियाँ बार-बार करवाते हैं।

पहली है partial masking। Log transformer `Authorization: Bearer` देखता है और अगला token बदल देता है, लेकिन पूरी signed URL print कर देता है, जिसके query parameters में `X-Amz-Credential`, access key identifier, date, region, service और scope शामिल होते हैं। Secret signature छिप सकती है, फिर भी request identity format और target उजागर करती है।

दूसरी है structured reference को opaque string समझना। `vault://path/to/item#field` जैसे pattern में अलग-अलग हिस्से होते हैं और उनकी sensitivity भी अलग हो सकती है। अगर एक team field value हटाती है और दूसरी पूरी path print करती है, तो किसी ने audience rule परिभाषित नहीं किया है। केवल बिखरे हुए string substitutions किए गए हैं।

जहाँ tooling अनुमति दे, structured handling अपनाएँ। URI को fields में parse करें। Cloud resource identifier को उसके documented grammar से parse करें। हर component को classification दें। ऐसी एक regular expression पर निर्भर न रहें जो मानती हो कि हर sensitive string API key जैसी दिखती है।

## Tenant names और endpoints लोगों और systems की पहचान कर सकते हैं

Tenant labels को नज़रअंदाज़ करना आसान है, क्योंकि वे अक्सर सामान्य product URLs में दिखते हैं। उनका risk इस बात पर निर्भर करता है कि वे किससे जुड़े हैं।

Public hostname में public company name अपने आप में बहुत कम जानकारी जोड़ सकता है। वही name जब `prod`, privileged API route, internal host, support case या error message के साथ दिखे, तो उपयोगी correlation point बन जाता है। इससे पता चल सकता है कि कोई named customer खास product इस्तेमाल करता है, किसी region में है या उसके पास ऐसा integration है जो दूसरे customers के पास नहीं है।

Internal names और अधिक परेशानी पैदा करते हैं। Teams `payer-west`, `acquisition-cedar`, `health-data` या `gov-contracts` जैसे labels इसलिए इस्तेमाल करती हैं क्योंकि उनसे operations तेज़ होते हैं। लेकिन ये business activity, regulated workloads और organizational relationships भी उजागर करते हैं। `${ACQUISITION_CEDAR_SFTP_KEY}` जैसा placeholder किसी transaction की घोषणा से पहले ही उसका संकेत दे सकता है।

Endpoint structure पर भी यही बात लागू होती है। इन दो events की तुलना करें:

```text
request failed: credential=cred_4d91 target_class=payment_export status=403

request failed: POST https://northstar-retail.prod-payments.eu.internal/v3/refunds/export
credential=PROD_NORTHSTAR_REFUNDS_ADMIN status=403
```

पहला event तब भी actionable है जब वह restricted trace से जुड़ा हो। दूसरा एक compact account map है। इससे tenant, stage, domain layout, region, functional service, route, operation और privilege level का पता चलता है।

Reflex की तरह target की सारी जानकारी न हटाएँ। Service down होने पर operators `request failed` जैसे vague event की जाँच नहीं कर सकते। जहाँ broad visibility ज़रूरी हो, वहाँ exact identifiers को controlled classes से बदलें: `payment_export`, `customer_data_write`, `artifact_publish`, `repository_deploy`। Exact endpoint को restricted event record में रखें, जहाँ access का कारण हो।

यहीं कई teams classification गलत करती हैं। वे tenant name को ordinary text मानती हैं क्योंकि वह credential नहीं है। सही classification context पर निर्भर है। Private, access-controlled audit system में tenant name उचित हो सकता है। वही name किसी pull request comment में कॉपी किए गए agent transcript में अनुचित हो सकता है।

## Substitution markers trust path उजागर करते हैं

`${TOKEN}` जैसे marker का अर्थ missing value से आगे जाता है। यह बताता है कि कोई process बाद में value देगा। Spelling अक्सर यह भी बताती है कि कौन-सा process।

Developer को ये examples एक जैसे लग सकते हैं, लेकिन ये अलग trust boundaries दिखाते हैं:

```text
${GITHUB_ACTIONS_DEPLOY_TOKEN}
${{ secrets.DEPLOY_TOKEN }}
{{ vault "kv/prod/deploy" "token" }}
secretKeyRef: name: prod-deployer key: token
op://Infrastructure/Production Deploy/token
```

पहला environment-variable injection model और CI identity का संकेत देता है। दूसरा workflow secret context की पहचान कराता है। तीसरा template engine और vault path दिखाता है। चौथा namespace और key वाले orchestrator object की ओर इशारा करता है। पाँचवाँ बताता है कि किसी खास password manager की naming convention मौजूद है।

इन strings को देखने वाले attacker ने secret नहीं चुराया है। उसने यह सीख लिया है कि code execution, build-log role, repository access या support-channel foothold मिलने के बाद कहाँ ध्यान देना है। उसे पता हो सकता है कि environment variables, mounted files, secret store की API या local desktop session में खोज करनी है।

Marker यह भी दिखा सकता है कि substitution कब होती है। Source में committed reference CI के दौरान resolve हो सकती है। Generated file में reference deployment के दौरान resolve हो सकती है। Request template में placeholder runtime पर resolve हो सकता है। इन moments के controls और संभावित logs अलग होते हैं। अगर आप उन्हें document नहीं करते, तो failure आने पर लोग broad debug output जोड़ेंगे, और अक्सर तभी actual secret बाहर निकलता है।

एक उपयोगी inventory trust path को हर artifact में लिखे बिना track करती है। हर credential के लिए reference का source, उसे resolve करने वाला process, उसे consume करने वाला process और वे स्थान दर्ज करें जहाँ result log हो सकता है। इससे exposure को postmortem में खोजने के बजाय पहले से सोच-समझकर review किया जा सकता है।

## Masked log attacker को काम करने की योजना दे सकता है

अक्सर समस्या ऐसी debugging change से शुरू होती है जो उस समय उचित लगती थी।

कल्पना करें कि deployment job vendor API को call करती है। Token CI secret में रखा है। Intermittent authentication failures के बाद shell script command tracing चालू करती है। CI platform literal token को mask कर देता है, इसलिए team मानती है कि logs सुरक्षित हैं।

Trace यह बनाती है:

```text
+ API_BASE=https://tenant-44.eu.vendor.example
+ TOKEN=***
+ curl -X POST https://tenant-44.eu.vendor.example/v1/admin/export \
  -H 'Authorization: Bearer ***' \
  -H 'X-Account: 784221' \
  -H 'X-Client-Name: finance-nightly-export'
< HTTP/2 403
< x-request-id: 81b5b8e1
< x-region: eu-central
```

कोई masked bearer token का दोबारा इस्तेमाल नहीं कर सकता। लेकिन logs तक पहुँच रखने वाला व्यक्ति अब vendor, tenant pattern, administrative endpoint, account number, workload name, region और अनुमानित schedule जानता है। वह उसी organization में `finance-nightly-export` खोज सकता है, account owner को विश्वसनीय request से target कर सकता है या किसी दूसरे credential मिलने पर endpoint details का इस्तेमाल कर सकता है।

सामान्य प्रतिक्रिया होती है, «हम और चीज़ें mask करेंगे।» इससे मदद मिलती है, लेकिन design failure छूट जाता है। Job ने broadly retained log में पूरी request plan print कर दी। Redactor यह नहीं जान सकता कि `tenant-44`, `784221` या `finance-nightly-export` आपके business के लिए महत्वपूर्ण हैं। वह केवल उन strings से match कर सकता है जिन्हें आपने उसे बताया है।

GitHub की security documentation इससे जुड़ी चेतावनी देती है: secret redaction काफी हद तक exact matches पर निर्भर करती है, और JSON, XML या YAML जैसे structured data में reliable masking कम संभव होती है। वह JWT जैसे generated sensitive values को भी masking के लिए register करने की सलाह देती है, जब वे किसी दूसरे secret से बने हों। यह अच्छी सलाह है, लेकिन backstop भर है। सुरक्षित debugging contract यह है कि terminal के लिए बनी shell trace के बजाय लोगों के लिए बनाया गया request summary emit किया जाए।

Trace को bounded event से बदलें:

```text
outbound_call
operation=finance_export
credential=cred_4d91
target_class=vendor_admin_api
method=POST
result=403
request_id=81b5b8e1
```

Exact request केवल restricted diagnostic record में रखें, अगर vendor को support के लिए इसकी ज़रूरत हो। उस record के लिए कम retention period रखें। उसे issue, chat thread या agent task में paste न करें।

## केवल resolved secret नहीं, reference को classify करें

व्यावहारिक policy को दो labels से अधिक चाहिए। «Secret» और «not secret» data के आसपास मौजूद अलग-अलग exposure levels को नज़रअंदाज़ कर देते हैं और गलत tradeoffs करवाते हैं।

Code review के दौरान लागू की जा सकने वाली छोटी classification scheme रखें:

| Class | Examples | Broad logs and prompts | Restricted operational records |
| --- | --- | --- | --- |
| Credential value | tokens, private keys, passwords, signed request signatures | Never | Only when unavoidable, encrypted and tightly retained |
| Direct identifier | tenant names, account IDs, exact hostnames, vault paths | Usually remove or replace | Permit when needed for investigation |
| Structural metadata | provider, environment, service class, credential injection model | Permit only when the audience needs it | Permit |
| Operational label | opaque alias, action class, outcome, correlation token | Permit | Permit |

यह table compliance standard नहीं है। आपके business को customer identifiers के लिए अधिक कड़ा rule या locked incident system के भीतर अधिक ढीला rule चाहिए हो सकता है। बात यह है कि error handler text emit करने से पहले किसी को निर्णय लेना होगा।

OWASP की Logging Cheat Sheet logs के लिए यही सामान्य रुख अपनाती है। वह कहती है कि access tokens, passwords, database connection strings, encryption keys और commercially sensitive information को आम तौर पर remove, mask, sanitize, hash या encrypt करना चाहिए। वह file paths और internal network names को भी ऐसे data के रूप में बताती है जिन्हें विशेष treatment की ज़रूरत हो सकती है। Credential placeholders अक्सर इसी category में आते हैं। उनकी value अनुपस्थित है, लेकिन आसपास का path और name अब भी sensitive हो सकता है।

हर structural field को prohibited न मानें। अगर हर event से system और action context हट जाएगा, तो responders screenshots और ad hoc debug flags से logging policy को bypass करेंगे। अच्छे event में इतना context हो कि वे जान सकें: किसने action करने की कोशिश की, किस approved capability का इस्तेमाल हुआ, किस class के target तक पहुँचा और क्या हुआ। वे वे विवरण छोड़ दें जो केवल approved investigation access वाले व्यक्ति के लिए उपयोगी हैं।

## References को सबसे कम trusted audience के लिए बनाएँ

सबसे तेज़ सुधार यह तय करना है कि reference कहाँ दिखाई देगा, फिर तय करना है कि उसका नाम क्या होना चाहिए। Private vault interface में काम करने वाला credential name build log या agent approval card के लिए गलत हो सकता है।

चार surfaces से शुरुआत करें: source control, runtime configuration, user-visible approval और audit records। हर surface के लिए सबसे कम trusted legitimate reader पहचानें। वह हर repository contributor, CI log viewer, support engineer, automated agent या छोटा incident group हो सकता है। फिर उस surface को उसके काम के लिए आवश्यक न्यूनतम information दें।

एक उपयोगी convention के तीन हिस्से हैं:

```yaml
# Broadly visible configuration
export_job:
  action: finance_export
  credential_alias: cred_4d91
  target_class: vendor_admin_api

# Restricted credential registry
cred_4d91:
  owner: revenue-systems
  approved_action: finance_export
  exact_target: https://tenant-44.eu.vendor.example/v1/admin/export
  secret_reference: restricted-store-record
```

Configuration readable रहती है। Reviewer देख सकता है कि job vendor administrative API के ज़रिए finance data export करती है। Exact tenant, endpoint और secret-store reference registry में रहते हैं, जहाँ उन्हें होना चाहिए।

यह convention दूसरी failure भी रोकती है: copied endpoints की तुलना में aliases कम बदलते हैं। Tenant migrate होने या provider का hostname बदलने पर restricted mapping update करें और वही action-level interface बनाए रखें। Calling job को infrastructure की हर detail जानने की ज़रूरत नहीं।

Shared repository में configuration पहुँचने से पहले एक छोटा scanner obvious cases पकड़ सकता है। यह example उन aliases और references को flag करता है जिनमें environment, privilege या tenant terms हों। यह जानबूझकर simple है। इसका काम review शुरू करना है, human judgment के बिना release रोकना नहीं।

```python
import re
from pathlib import Path

pattern = re.compile(
    r"(?i)(prod|staging|admin|root|breakglass|tenant|customer|"
    r"account|vault://|secretkeyref|secrets\.)"
)

for path in Path(".").rglob("*"):
    if path.is_file() and path.suffix in {".yml", ".yaml", ".json", ".env", ".txt"}:
        for number, line in enumerate(path.read_text(errors="ignore").splitlines(), 1):
            if pattern.search(line):
                print(f"REVIEW {path}:{number}: {line.strip()}")
```

उपयोगी output ऐसा दिख सकता है:

```text
REVIEW deploy.yaml:7: credential_alias: PROD_NORTHSTAR_REFUNDS_ADMIN
REVIEW deploy.yaml:11: secret_reference: vault://finance/prod/northstar/refunds
```

Reviewer को पूछना चाहिए कि क्या term का उस file में होना ज़रूरी है और क्या file के readers को इसकी ज़रूरत है। हर word को mechanically बदलने से traceability खत्म होती है। Sensitive detail को restricted mapping में ले जाना आम तौर पर बेहतर repair है।

## Agents को credential anatomy नहीं, action context चाहिए

Autonomous coding agents इस समस्या को और गंभीर बनाते हैं, क्योंकि वे configuration पढ़ते हैं और बड़े पैमाने पर transcripts बनाते हैं। अगर agent repository पढ़ सकता है, तो उसके prompt context में aliases, secret references, endpoint templates और failed command output आ सकते हैं। भले agent को token न मिले, उसे उन credentials की operating manual मिल सकती है जिन्हें वह पढ़ नहीं सकता।

Agent को सबसे छोटी उपयोगी action vocabulary दें। उसे `vendor_admin_api` target class के विरुद्ध `finance_export` request करने की ज़रूरत हो सकती है। उसे vault path, tenant ID, authorization header format या वह exact environment variable शायद ही चाहिए जो secret resolve करेगा। अगर ये fields उसकी पहुँच में नहीं हैं, तो वह उन्हें patch description, terminal transcript या external tool call में दोहरा नहीं सकता।

इससे human approval भी बेहतर होता है। व्यक्ति consequence के आधार पर action approve करता है: «approved vendor API को finance export भेजें।» Interface में `vault://teams/finance/prod/...` या customer-specific hostname दिखने से security decision बेहतर नहीं होता। ये details approver के लिए noise और बाद में record देखने वाले के लिए information बनती हैं।

Sallyport इसी separation को अपनाता है। API और SSH credentials उसके encrypted vault में रहते हैं और action execute किया जाता है, credentials agent को नहीं दिए जाते। उसके session और activity records agent run और individual calls दिखा सकते हैं, बिना secret values agent को उपलब्ध कराए। यह boundary उपयोगी है, लेकिन आपके चुने हुए action names, endpoints और aliases को भी इसी metadata review की ज़रूरत होगी।

इन artifacts को जाँचने के लिए token leak का इंतज़ार न करें। एक representative CI log, agent transcript, approval prompt, configuration file और support ticket लें। उन्हें ऐसे पढ़ें जैसे broad project access वाला contractor पढ़ेगा। हर उस field को circle करें जो tenant, privileged role, secret store, cloud account या network target की पहचान करती है। फिर तय करें कि कौन-से fields task में मदद करते हैं और कौन-से केवल ऐसी कहानी बताते हैं जिसे आपके systems को publish करने की ज़रूरत नहीं थी।

Credential value सुरक्षा की पहली चीज़ है। उसके आसपास का map अगली चीज़ है जिसे बाँटना बंद करना चाहिए।
