WisarWisar
Dasturlash kitobi/10-QISM — DevOps38 daqiqa

10.11-bob: Environment va secrets boshqaruvi

10-QISM — DevOps va Deploy · 11-mavzu


1. Kirish va motivatsiya

10-QISM bo'ylab ilovani serverga chiqardik 10.1-bob, Nginx ortiga qo'ydik 10.2-bob, Docker'ga o'radik (10.3-10.4), CI/CD bilan avtomatik deploy qildik 10.5-bob, bulutga joyladik 10.6-bob, domen va SSL ulab production'ga oldik 10.7-bob, Kubernetes'da masshtabladik 10.8-bob, monitoring qo'ydik 10.9-bob va Terraform bilan infratuzilmani kod qildik 10.10-bob. Hammasini bog'lab turgan bitta yashirin ip bor edi, lekin biz unga to'xtalmadik: sozlama va maxfiy ma'lumotlar — DB paroli, JWT secret, API kalitlari, TLS kalit. Bu — 10-QISM'ning yakuniy mavzusi va eng nozik nuqtasi.

Asosiy haqiqat shu: kod hamma joyda bir xil, sozlama esa har joyda boshqacha. Sizning NestJS ilovang lokal kompyuteringda ham, staging serverda ham, production'da ham aynan bir xil kod. Lekin u ulanadigan ma'lumotlar bazasi, parol, port, tashqi servis kaliti — har muhitda butunlay boshqacha. Lokalda localhost:5432, parolsiz test DB; production'da haqiqiy RDS endpoint, kuchli parol. Bularni kodga yozib qo'ysangiz — ikki falokat birga keladi: (1) bir muhit uchun yozilgan qiymat boshqasini buzadi (test parol production'ga ketadi); (2) eng yomoni — maxfiy ma'lumot Git'ga, undan GitHub'ga chiqib ketadi va butun internet uni ko'radi. GitHub'da har kuni minglab API kalit, parol "sirib" qoladi (leak) — botlar ularni daqiqalar ichida topib, hisobingni o'g'irlaydi yoki bulutda mayning qiladi (sizning hisobingga ming dollar hisob keladi).

Bu bob: config nima va secret nima (farqi), 12-factor config tamoyili (sozlama kodda emas, environment'da), environment variable (process.env — 5.8 bilan), .env fayl va dotenv (lokal — lekin .gitignore!), nega secret'ni kodga/git'ga yozmaslik (leak, tarix abadiy qoladi), muhit ajratish (dev/staging/prod), secret turlari (DB credential, API key, JWT secret, TLS key), saqlash yechimlari (.env lokal; CI secrets — GitHub Actions; cloud — AWS Secrets Manager/SSM, HashiCorp Vault), secret rotation (almashtirish), encryption at rest/in transit, least privilege, secret injection (runtime'da env — Docker/K8s Secret — 10.8), git'dan secret tozalash va secret scanning (gitleaks).

O'xshatish: Ikki narsani bir-biridan ajrat. Birinchisi — secret (maxfiy): bu uyingning kaliti yoki seyf shifri. Siz uni uy devoriga bo'r bilan yozib qo'ymaysiz — buni har o'tkinchi o'qiydi. Kodga parol yozish — aynan shu: devorga shifr yozish, keyin uyni internetga ko'rsatish. Kalit alohida, maxfiy joyda turadi (cho'ntak, seyf, kalit menejeri). Ikkinchisi — environment (muhit): bir xil dazmol turli kuchlanishda ishlaydi — 220V (production) yoki 110V (test). Dazmol (kod) bir xil, lekin kuchlanish (sozlama) rozetkadan keladi — dazmol ichiga payvandlangan emas. Agar 110V ni dazmol ichiga zo'rlab payvandlasangiz, uni 220V mamlakatda ishlatib bo'lmaydi (kod muhitga "yopishib" qoladi). Shuning uchun sozlamani tashqaridan, rozetkadan (environment'dan) olamiz — shunda bir xil kod har joyda ishlaydi.

Nega muhim?

  • Xavfsizlik — leak bo'lgan bitta kalit = buzilgan butun tizim (eng keng intsident sababi).
  • Portativlik — bir xil kod dev/staging/prod'da hech o'zgarmay ishlaydi (12-factor).
  • Jamoa — yangi dasturchi .env.example ko'rib, daqiqada ishga tushadi (sirlarni so'rab yurmasdan).
  • Intervyu/ish — "secret'larni qanday boshqarasiz, leak bo'lsa nima qilasiz?" — senior savoli.

2. Nazariya — chuqur tushuntirish

2.1. Config nima, secret nima va farqi

text
  CONFIG (sozlama) — kod o'rniga deploy'dan deploy'ga O'ZGARADIGAN qiymatlar:
   port, log darajasi, DB host, feature flag, tashqi servis URL'i

  SECRET (maxfiy) — config'ning bir turi, lekin OCHIB BO'LMASLIGI shart:
   DB parol, JWT secret, API kalit, TLS private key, OAuth client secret

  ┌──────────────┬─────────────────────┬──────────────────────────┐
  │              │ Oddiy config        │ Secret (maxfiy)          │
  ├──────────────┼─────────────────────┼──────────────────────────┤
  │ Misol        │ PORT=3000           │ DB_PASSWORD=Xk9#...      │
  │ Ko'rinsa     │ zarar yo'q          │ FALOKAT (tizim buziladi) │
  │ Saqlash      │ .env / config       │ secrets manager / vault  │
  │ Git'ga       │ ba'zan mumkin       │ HECH QACHON              │
  │ Log'da       │ ko'rinishi mumkin   │ HECH QACHON (mask)       │
  └──────────────┴─────────────────────┴──────────────────────────┘

   HAMMA secret — config; lekin har config — secret EMAS.
     Shubha bo'lsa  secret deb hisobla (ehtiyot shart).

Config (sozlama) — koddan ajralib, deploy'dan deploy'ga o'zgaradigan har qanday qiymat: port, log darajasi, DB host, feature flag, tashqi servis manzili. Secret (maxfiy ma'lumot) — config'ning maxsus, eng nozik turi: ochib qo'yilsa falokat keltiradigan qiymat — DB paroli, JWT secret, API kaliti, TLS private key, OAuth client secret. Farqi oqibatda: oddiy config ko'rinib qolsa (PORT=3000) — zarar yo'q; secret ko'rinsa (DB_PASSWORD=...) — tizim buziladi. Qoida: har secret — config, lekin har config — secret emas. Ishonchsiz bo'lsangiz, qiymatni secret deb hisobla (ehtiyot shart har doim foydali). Bu bob ikkalasini ham qamraydi, lekin asosiy e'tibor — secret'larni xavfsiz boshqarish.

2.2. 12-factor config: sozlama kodda emas, environment'da

text
  12-FACTOR APP (12factor.net) — bulutga mos ilova qurish 12 tamoyili.
  III-tamoyil — CONFIG: "Config'ni ENVIRONMENT'da sakla, kodda EMAS".

  ASOSIY MEZON (the litmus test):
  "Kodni shu daqiqada OCHIQ KODLI (open source) qilib bo'ladimi —
   birorta ham maxfiy ma'lumot OCHILMASdan?"
    HA bo'lsa: config to'g'ri ajratilgan 
    YO'Q bo'lsa: kodda secret bor — tuzating 

  NEGA ENVIRONMENT VARIABLE (config fayl emas):
   Tasodifan Git'ga commit bo'lib KETMAYDI (.env gitignore'da)
   Til/OS'dan mustaqil standart (Node, Python, Go — hammasi o'qiydi)
   Bir joyda emas, tarqoq fayllarda chalkashmaydi

   ANTI-PATTERN: config'ni MUHIT NOMI bo'yicha guruhlash
     (config.dev.js, config.prod.js, config.joes-staging.js ...)
      muhit ko'paygach "kombinatoriy portlash" (boshqarib bo'lmaydi)

12-factor app — bulutga mos, masshtablanadigan ilova qurishning 12 tamoyili (sanoat standarti, 2025-2026'da ham asos). Uning III-tamoyili — Config: "Config'ni environment'da sakla, kodda emas". Sababi 12-factor o'zi aytadi: "config deploy'dan deploy'ga keskin o'zgaradi, kod esa o'zgarmaydi". Eng yaxshi mezon (litmus test): "Kodni shu daqiqada ochiq kodli (open source) qila olasizmi — birorta maxfiy ma'lumot ochilmasdan?" Agar ha — config to'g'ri ajratilgan; agar yo'q — kodda secret bor, tuzatish kerak. Nega config fayl emas, balki environment variable: (1) tasodifan Git'ga commit bo'lib ketmaydi; (2) til va OS'dan mustaqil standart (har til o'qiydi); (3) tarqoq, har xil formatli fayllarda chalkashmaydi. 12-factor alohida ogohlantiradigan anti-pattern: config'ni muhit nomi bo'yicha guruhlash (config.dev, config.prod, config.joes-staging...) — muhit ko'paygach "kombinatoriy portlash" (combinatorial explosion) bo'ladi, deploy'larni boshqarish mo'rt (brittle) holatga keladi. Har bir o'zgaruvchi mustaqil boshqarilsin.

2.3. Environment variable nima (process.env)

text
  ENVIRONMENT VARIABLE — operatsion tizim jarayonga beradigan "kalit=qiymat":
   kod ulardan O'QIYDI, lekin ularni o'z ichida SAQLAMAYDI

  TERMINALDA (lokal sinash):
  $ export DB_HOST=localhost           muhit o'zgaruvchisi o'rnatamiz (Linux/mac)
  $ DB_HOST=localhost node app.js      faqat shu buyruq uchun
  PS> $env:DB_HOST="localhost"         (Windows PowerShell)

  NODE.JS'DA O'QISH 5.8-bob:
  const host = process.env.DB_HOST;    har doim STRING (yoki undefined)
  const port = Number(process.env.PORT) || 3000;   songa o'girish kerak

   process.env qiymatlari DOIM string: PORT="3000" (raqam emas!)
      Number(), JSON.parse() bilan to'g'ri turga o'gir (2.7 validatsiya)
   Frontend'da process.env YO'Q (brauzer) — bu faqat backend/Node uchun

Environment variable (muhit o'zgaruvchisi) — operatsion tizim har bir jarayonga (process) beradigan KALIT=qiymat juftliklari. Ilova ulardan o'qiydi, lekin ularni o'z koditida saqlamaydi — bu config'ni tashqaridan olishning standart mexanizmi. Terminalda o'rnatish: Linux/mac'da export DB_HOST=localhost (yoki bitta buyruq oldidan DB_HOST=localhost node app.js), Windows PowerShell'da $env:DB_HOST="localhost". Node.js'da o'qish — process.env orqali (5.8: 2.1): process.env.DB_HOST. Eng keng adashish: process.env qiymatlari har doim stringprocess.env.PORT "3000" (matn), raqam emas; shuning uchun Number(process.env.PORT), boolean uchun esa === "true" tekshirish kerak (2.7 validatsiya bu ishni avtomatlashtiradi). Ikkinchi muhim nuqta: process.env faqat Node.js/backendda bor — brauzerda (frontend) yo'q (shuning uchun frontend'ga secret yuborib bo'lmaydi, 2.6).

2.4. .env fayl va dotenv (lokal qulaylik)

text
  MUAMMO: har ishga tushirishda 10 ta "export VAR=..." yozish — og'ir va xatoga moyil.
  YECHIM: .env fayl — barcha o'zgaruvchilar bitta faylda (faqat LOKAL/dev uchun).

  .env FAYL FORMATI (loyiha ildizida):
  ┌──────────────────────────────────────────┐
  │ # izoh (# bilan boshlanadi)              │
  │ NODE_ENV=development                      │
  │ PORT=3000                                 │
  │ DATABASE_URL=postgres://user:pass@host/db │
  │ JWT_SECRET="uzun tasodifiy maxfiy qiymat" │   bo'sh joy bo'lsa qo'shtirnoq
  │ PRIVATE_KEY="line1\nline2"                │   multiline (\n)
  └──────────────────────────────────────────┘

  YUKLASH (Node.js, 5.8):
  import 'dotenv/config';             eng tepada (boshqa importdan OLDIN)
  // endi process.env.PORT ishlaydi

   .env HECH QACHON Git'ga TUSHMASLIGI kerak  .gitignore'ga qo'sh!
   .env — faqat LOKAL/dev qulayligi; production'da secrets manager (2.9)

dotenv — har ishga tushirishda o'nlab export yozish o'rniga, barcha o'zgaruvchilarni bitta .env faylga yozib, uni avtomatik process.envga yuklaydigan kutubxona (dotenv, npm — 5.8: 2.3). .env fayl formati — har qatorda KALIT=qiymat; # bilan izoh; bo'sh joy yoki maxsus belgi bo'lsa qiymatni qo'shtirnoqga ol (JWT_SECRET="..."); ko'p qatorli qiymat uchun \n (yoki haqiqiy qator). Node.js'da yuklash — eng tepada import 'dotenv/config' (yoki require('dotenv').config()), boshqa importlardan oldin (aks holda ular yuklanganda env hali bo'sh bo'ladi). 2025-2026'da dotenvx ham keng — u .env fayllarni shifrlab saqlashga imkon beradi (qo'shimcha himoya). Eng muhim qoida: .env fayl hech qachon Git'ga tushmasligi kerak — uni .gitignorega qo'sh (2.6, Xato 1). .env — faqat lokal/dev qulayligi uchun; production serverda secret'lar .envda emas, secrets managerda (AWS/Vault) yoki injection orqali beriladi (2.9, 2.12).

2.5. Nega secret'ni kodga/git'ga yozmaslik (leak va abadiy tarix)

text
  HARDCODED SECRET — kodga to'g'ridan yozilgan maxfiy qiymat:

  //  FALOKAT:
  const apiKey = "sk_live_51H8x...";        kod ichida
  const dbPass = "SuperSecret123";           har kim ko'radi

  NEGA HALOKATLI:
  1) Kod Git'da  har bir clone'da SECRET bor (jamoa, eski xodim, fork)
  2) GitHub'ga push  PUBLIC bo'lsa, botlar DAQIQALARDA topadi
  3) Private repo ham xavfsiz EMAS (access ko'p, leak bo'ladi)

   ENG YOMONI — GIT TARIXI ABADIY:
  // commit'da secret bor edi, keyin O'CHIRDIM va commit qildim
  //  secret HALI HAM tarixda (git log -p bilan topiladi!)
  //  faqat o'chirish YETARLI EMAS: secret'ni ALMASHTIRISH (rotate) shart

  REAL OQIBAT:
  - AWS kalit leak  botlar mayning qiladi  $10,000+ hisob (bir kechada)
  - DB parol leak  ma'lumot o'g'irlanadi/o'chiriladi (GDPR jarima)

Hardcoded secret — kodga to'g'ridan-to'g'ri yozilgan maxfiy qiymat (const apiKey = "sk_live_...") — eng keng tarqalgan va eng halokatli xato. Nega: (1) kod Git'da saqlanadi, demak secret har bir clone'da bor — jamoa a'zolari, ketgan xodim, fork qilganlar hammasi ko'radi; (2) GitHub'ga push qilinsa va repo public bo'lsa — avtomatik botlar daqiqalarda topadi (GitHub'ni doimiy skanerlaydi); (3) private repo ham to'liq xavfsiz emas (kim access olgani, kelajakda public bo'lishi noma'lum). Eng yomon va ko'pchilik bilmaydigan haqiqat: Git tarixi abadiy. Secret'ni commit qilib, keyin o'chirib qayta commit qilsangiz ham — secret hali ham tarixda (git log -p yoki har qanday eski commit bilan topiladi). Shuning uchun secret leak bo'lsa, faqat o'chirish yetarli emas — uni almashtirish (rotate) shart (2.10, 2.12). Real oqibatlar: leak bo'lgan AWS kaliti — botlar bulutda kripto mayning qiladi, bir kechada ming dollarlik hisob; leak bo'lgan DB paroli — ma'lumot o'g'irlanadi yoki o'chiriladi.

2.6. Muhit ajratish (dev/staging/prod) va .env.example

text
  HAR MUHIT — har xil qiymat, AMMO bir xil kalitlar (kod o'zgarmaydi):

  ┌────────────┬─────────────────────┬──────────────────────────────┐
  │ Kalit      │ dev (lokal)         │ production                   │
  ├────────────┼─────────────────────┼──────────────────────────────┤
  │ NODE_ENV   │ development         │ production                   │
  │ DATABASE_  │ localhost:5432      │ prod-db.xxx.rds.amazonaws... │
  │ JWT_SECRET │ test-secret (zaif)  │ kuchli tasodifiy (64 belgi)  │
  │ LOG_LEVEL  │ debug               │ warn                         │
  └────────────┴─────────────────────┴──────────────────────────────┘

  .env.example — KALITLAR ro'yxati (QIYMATSIZ — Git'ga TUSHADI):
  ┌──────────────────────────────────┐
  │ NODE_ENV=                         │   qanday kalitlar kerakligini ko'rsatadi
  │ PORT=                             │   qiymat YO'Q (xavfsiz)
  │ DATABASE_URL=                     │   yangi dasturchi nusxa olib to'ldiradi
  │ JWT_SECRET=                       │
  └──────────────────────────────────┘

   .env  gitignore (qiymat bor); .env.example  Git'da (qiymatsiz andoza)
   PROD secret'ni DEV'da ishlatma (test paytida prod ma'lumot buziladi — Xato 5)

Muhit ajratish — bir xil kod, lekin har muhitda har xil qiymat. dev (lokal kompyuter), staging (production'ga o'xshash test muhiti) va production (real foydalanuvchilar) — bir xil kalitlar (DATABASE_URL, JWT_SECRET...), lekin butunlay boshqa qiymatlar: lokalda localhost, zaif test parol; production'da haqiqiy RDS endpoint, kuchli 64-belgili tasodifiy secret. Kod hech o'zgarmaydi — faqat environment boshqacha qiymat beradi 2.2-bob. Buni soddalashtiradigan kelishuv — .env.example pattern: bu fayl kalitlar ro'yxatini (qiymatsiz!) saqlaydi va Git'ga tushadi. Yangi dasturchi loyihani clone qiladi, .env.exampleni .envga nusxalaydi va o'z qiymatlarini to'ldiradi — qaysi o'zgaruvchilar kerakligini darrov ko'radi (sirlarni so'rab yurmasdan). Ikki fayl: .env (haqiqiy qiymatlar — .gitignoreda), .env.example (bo'sh andoza — Git'da). Frontend'ga secret yuborib bo'lmaydi 2.3-bob — brauzerga ketadigan har narsani foydalanuvchi ko'radi; faqat backend secret'larni ushlaydi. Production secret'ni hech qachon dev'da ishlatma — test paytidagi xato real ma'lumotni buzadi (Xato 5).

2.7. Secret turlari va env validatsiya

text
  SECRET TURLARI (har biri o'z xavfi):
  - DB CREDENTIAL    DATABASE_URL, DB_PASSWORD (ma'lumotga to'liq kirish)
  - API KEY          STRIPE_KEY, OPENAI_KEY (pul/servis egasi hisobidan)
  - JWT SECRET       token imzolash (leak  kim xohlasa token yasaydi — 5.15)
  - TLS PRIVATE KEY  HTTPS sertifikat kaliti (leak  trafik ochiladi — 10.7)
  - OAuth secret     client_secret (uchinchi tomon login buziladi)

  ENV VALIDATSIYA (Zod bilan — 5.9) — ishga tushishda TEKSHIR:
  ┌────────────────────────────────────────────────────────┐
  │ import { z } from 'zod';                                │
  │ const envSchema = z.object({                            │
  │   PORT: z.coerce.number().default(3000),   songa o'gir │
  │   DATABASE_URL: z.string().url(),          URL bo'lsin │
  │   JWT_SECRET: z.string().min(32),          kamida 32   │
  │ });                                                      │
  │ export const env = envSchema.parse(process.env);        │
  └────────────────────────────────────────────────────────┘

   Validatsiyasiz: yetishmagan env "undefined" bo'lib, ilova YARIM ishlaydi
     (xato KEYIN, production'da chiqadi — fail-fast: BOSHIDA yiqilsin)

Secret turlari — har birining o'z xavf darajasi bor: DB credential (DATABASE_URL, parol — ma'lumotga to'liq kirish, 6-QISM); API key (STRIPE_KEY, OPENAI_KEY — leak bo'lsa pul/servis sizning hisobingdan sarflanadi); JWT secret (token imzolaydi — leak bo'lsa kim xohlasa o'zini admin qilib token yasaydi, 5.15: 2.x); TLS private key (HTTPS sertifikat kaliti — leak bo'lsa shifrlangan trafik ochiladi, 10.7: 2.10); OAuth client_secret (uchinchi tomon login buziladi). Env validatsiya — ilovani ishga tushishida environment to'g'ri o'rnatilganini tekshirish (Zod yoki Joi bilan — 5.9: 2.4). Zod sxemasi env'ni o'qiydi, turlarni to'g'rilaydi (z.coerce.number() — string'ni songa), shartlarni qo'yadi (z.string().url(), .min(32)) va xato bo'lsa darrov yiqiladi. Validatsiyasiz xavf: yetishmagan o'zgaruvchi undefined bo'lib qoladi, ilova "yarim" ishlaydi va xato keyinroq, production'da chiqadi (debug qiyin). Tamoyil — fail-fast: noto'g'ri sozlama bo'lsa ilova boshida, ishga tushmasdan yiqilsin (NestJS ConfigModule ham buni qiladi — 2.11).

2.8. Encryption at rest va in transit, least privilege

text
  SECRET HAYOTI BO'YICHA HIMOYA — ikki holatda shifrlanishi kerak:

  ┌─────────────────────────────────────────────────────────────┐
  │ ENCRYPTION AT REST  — DISKDA turganda shifrlangan            │
  │   (DB, secrets manager, backup — o'g'irlangan disk o'qilmaydi)│
  │ ENCRYPTION IN TRANSIT — TARMOQDA ketayotganda shifrlangan    │
  │   (TLS/HTTPS — yo'lda ushlab o'qib bo'lmaydi — 10.7: 2.10)   │
  └─────────────────────────────────────────────────────────────┘

  LEAST PRIVILEGE (eng kam imtiyoz — 10.1: 2.4) — secret darajasida:
  - Har servis FAQAT o'ziga kerakli secret'ni o'qiy olsin (hammasini emas)
  - "billing" servis "auth" DB parolini KO'RMASLIGI kerak
  - IAM/Vault policy bilan: kim  qaysi secret  o'qiydimi (read-only)

  ┌──────────┐  faqat o'z secret'i  ┌──────────────┐
  │ auth svc │ ─────────────────── │ auth DB pass │  
  │ auth svc │ ───────X─────────── │ billing key  │   (ruxsat yo'q)
  └──────────┘                      └──────────────┘

   Bitta servis buzilsa — faqat O'Z secret'lari ketadi (boshqasi himoyalangan)

Encryption at rest va in transit — secret'ni ikki holatda ham shifrlash. Encryption at rest — secret diskda turganda shifrlangan (DB, secrets manager, backup fayl): server diski o'g'irlansa ham, shifr kalitisiz o'qib bo'lmaydi. AWS Secrets Manager va Vault secret'larni at-rest avtomatik shifrlaydi (AWS — KMS kaliti bilan; Vault — o'z encryption engine'i bilan). Encryption in transit — secret tarmoqda ketayotganda shifrlangan (TLS/HTTPS — yo'lda ushlab o'qib bo'lmaydi, 10.7: 2.10). Least privilege (eng kam imtiyoz — 10.1: 2.4) tamoyilini secret darajasiga ko'taramiz: har servis faqat o'ziga kerakli secret'ni o'qiy olsin, hammasini emas. "Billing" servis "auth" DB parolini ko'rmasligi kerak. Buni IAM policy (AWS) yoki Vault policy bilan o'rnatasiz: kim, qaysi secret, faqat o'qish (read-only). Foydasi: bitta servis buzilsa, faqat o'z secret'lari ketadi — qolganlari himoyalangan ("blast radius" — zarar doirasi kichik). Bu — secrets manager'larning oddiy .envdan ustun bo'lgan asosiy sababi.

2.9. Secret saqlash yechimlari (lokal, CI, cloud, vault)

text
  SECRET QAYERDA SAQLANADI — darajaga qarab uch yechim:

  1) LOKAL / DEV   .env fayl (gitignore'da — 2.4)
      oddiy, tez    faqat lokal; tarqatib bo'lmaydi; rotation yo'q

  2) CI/CD         GitHub Actions Secrets 10.5-bob
      pipeline build/deploy paytida ishlatadi; log'da MASK qilinadi
      faqat CI uchun; ilova runtime'iga bevosita emas

  3) CLOUD MANAGED  AWS Secrets Manager / SSM Parameter Store
      markazlashgan, at-rest shifr (KMS), IAM access, AVTO-ROTATION, audit
      Secrets Manager: rotation kerak bo'lsa (DB parol — Lambda bilan)
      SSM Parameter Store: arzon/bepul, oddiy config + secret (SecureString)

  4) SELF-HOSTED   HashiCorp Vault (eng kuchli)
      DYNAMIC secrets (vaqtinchalik, o'zi muddati tugaydi), lease, audit,
       encryption-as-a-service, ko'p bulutda ishlaydi
      o'rnatish/boshqarish murakkab (katta jamoa uchun)

   Boshlovchi: .env (lokal) + GitHub Secrets (CI) + SSM/Secrets Manager (prod)

Secret saqlash yechimlari — darajaga qarab tanlanadi. (1) Lokal/dev.env fayl (.gitignoreda, 2.4): oddiy va tez, lekin faqat lokal, tarqatib bo'lmaydi, rotation yo'q. (2) CI/CDGitHub Actions Secrets (10.5: 2.x): pipeline build/deploy paytida ishlatadi (${{ secrets.X }}), GitHub ularni log'da avtomatik mask qiladi; lekin faqat CI uchun. (3) Cloud managedAWS Secrets Manager yoki SSM Parameter Store: markazlashgan, at-rest shifr (KMS), IAM access, audit (CloudTrail). Ikkisining farqi: Secrets Manageravtomatik rotation kerak bo'lsa (DB parolni Lambda bilan o'zi almashtiradi), lekin pullik (har secret oyiga to'lov); SSM Parameter Store — arzon/bepul, oddiy config + secret (SecureString turi), rotation o'zi yo'q. (4) Self-hostedHashiCorp Vault: eng kuchli — dynamic secrets (so'ralganda yaratiladigan, muddati o'zi tugaydigan vaqtinchalik credential), lease/renewal, audit log, encryption-as-a-service, ko'p bulutda; lekin o'rnatish va boshqarish murakkab (katta jamoa/kompaniya uchun). Boshlovchi uchun amaliy yo'l: .env (lokal) + GitHub Secrets (CI) + SSM/Secrets Manager (production).

2.10. Secret rotation (vaqti-vaqti almashtirish)

text
  ROTATION — secret'ni VAQTI-VAQTI bilan yangisiga almashtirish:

  NEGA: secret qancha uzoq yashasa — leak xavfi shuncha oshadi
  (kim ko'rgani, qayerda nusxasi bor — vaqt o'tib noma'lum bo'ladi)

  ┌── eski secret ──┐    rotation    ┌── yangi secret ──┐
  │ leak bo'lgan    │ ────────────  │ toza (eski keraksiz)│
  │ bo'lishi mumkin │                │                  │
  └─────────────────┘                └──────────────────┘

  IKKI HOLAT:
  1) REJALI rotation — har 30/90 kunda (xavfsizlik siyosati)
      AWS Secrets Manager: AVTOMATIK (Lambda yangi parol yaratadi,
       DB'ni yangilaydi, secret'ni yangilaydi — ilova qayta deploysiz oladi)
  2) SHOSHILINCH rotation — LEAK aniqlangach DARROV (xodim ketdi, git'ga chiqdi)

   Leak bo'lsa: avval ROTATE (eski kalitni bekor qil), KEYIN tozalash 2.12-bob
      eski kalitni o'chirish (revoke) — botlar uni ishlata olmasin

Secret rotation — secret'ni vaqti-vaqti bilan yangisiga almashtirish. Nega kerak: secret qancha uzoq yashasa, leak xavfi shuncha oshadi — vaqt o'tib kim ko'rgani, qayerda nusxasi qolgani noma'lum bo'ladi. Ikki holat: (1) rejali rotation — xavfsizlik siyosati bo'yicha har 30/90 kunda muntazam almashtirish. AWS Secrets Manager buni avtomatik qiladi: Lambda funksiyasi yangi parol yaratadi, DB'ni yangi parol bilan yangilaydi, secret'ni yangilaydi — ilovani qayta deploy qilmasdan yangi qiymatni oladi (chunki ilova secret'ni runtime'da o'qiydi, kodda emas). (2) shoshilinch rotationleak aniqlangach darrov: xodim ketdi, secret git'ga chiqdi, yoki shubhali faollik. Eng muhim tartib: leak bo'lganda avval rotate qil (yangi secret yarat, eskisini bekor qil/revoke), keyin git tarixini tozala 2.12-bob — chunki eski kalit allaqachon nusxalangan bo'lishi mumkin, faqat tozalash botni to'xtatmaydi; bekor qilingan (revoked) kalit esa ishlamaydi.

2.11. NestJS ConfigModule va secret injection

text
  SECRET ILOVAGA QANDAY YETADI — INJECTION (kodga emas, RUNTIME'da env sifatida):

  ┌──────────────┐   env sifatida beriladi   ┌────────────────────┐
  │ Secret manba │ ──────────────────────── │ ILOVA (process.env)│
  │ .env / K8s   │   (kod ichida YO'Q)       │ faqat O'QIYDI      │
  │ Secret / SSM │                           │                    │
  └──────────────┘                           └────────────────────┘

  NESTJS ConfigModule 8.14-bob — env'ni markazlashgan, tipli o'qish:
  ┌────────────────────────────────────────────────────────┐
  │ ConfigModule.forRoot({                                  │
  │   isGlobal: true,             hamma modulda ishlasin   │
  │   validationSchema,           Joi/Zod bilan tekshir    │
  │   envFilePath: '.env',                                  │
  │ })                                                      │
  │ // ishlatish:                                           │
  │ config.get<string>('JWT_SECRET')    tipli, markazda    │
  └────────────────────────────────────────────────────────┘

  INJECTION USULLARI:
  - Docker:  -e KEY=val  yoki  --env-file .env 10.4-bob
  - K8s:     Secret obyekti  env yoki volume 10.8-bob
  - PM2:     ecosystem env_production (10.7: 2.6)

Secret injection — secret ilovaga kod ichida emas, runtime'da environment sifatida beriladi (12-factor mohiyati). Manba (.env, K8s Secret, SSM) ilovaning process.enviga kiritiladi (inject), ilova esa faqat o'qiydi — secret hech qachon kodda yozilmaydi. NestJS ConfigModule (8.14: 2.x) — env'ni markazlashgan va tipli o'qish vositasi: ConfigModule.forRoot({ isGlobal: true, validationSchema, envFilePath })isGlobal bilan hamma modulda ishlaydi, validationSchema (Joi/Zod) bilan ishga tushishda tekshiradi (fail-fast — 2.7), va config.get<string>('JWT_SECRET') bilan tipli o'qiladi (process.envga to'g'ridan murojaat o'rniga — markazlashgan, sinovga oson). Injection usullari muhitga qarab: Docker-e KEY=val yoki --env-file .env (10.4: 2.x); KubernetesSecret obyekti env yoki volume sifatida ulanadi (10.8: 2.x); PM2ecosystem.config.js ichida env_production (10.7: 2.6). Hammasining mohiyati bir xil: secret tashqaridan, env orqali keladi.

2.12. Git'dan secret tozalash va secret scanning

text
  SECRET GIT'GA CHIQIB KETDI — ikki ish (TARTIB MUHIM):

  1) AVVAL ROTATE — leak bo'lgan secret'ni DARROV almashtir/bekor qil 2.10-bob
     (tozalash sekin; bot esa allaqachon ko'rgan bo'lishi mumkin)

  2) KEYIN TARIXDAN TOZALA — git tarixi abadiy 2.5-bob, maxsus vosita kerak:
     git filter-repo --path .env --invert-paths    .env'ni BUTUN tarixdan o'chir
      keyin force-push (jamoa qayta clone qilsin)
     (eski "git filter-branch" sekin — git-filter-repo tavsiya etiladi)

  SECRET SCANNING — leak'ni OLDINDAN ushlash (proaktiv):

  GITLEAKS — git repo'da hardcoded secret qidiruvchi (regex + entropy):
  gitleaks git .                   butun tarixni skanerlaydi
  gitleaks dir .                   joriy fayllarni
   pre-commit hook: commit'dan OLDIN tekshiradi (leak'ni kiritmaydi)
   GitHub Action: har push/PR'da CI'da skanerlaydi 10.5-bob

  GITHUB SECRET SCANNING — GitHub o'zi push'da ma'lum kalitlarni topadi
  (Stripe, AWS... topsa — ogohlantiradi yoki bloklaydi)

   ENG YAXSHISI — leak'ni OLDINI olish (scanning), tozalashdan ko'ra

Git'dan secret tozalash — secret tasodifan commit bo'lib ketsa, ikki ish (tartib muhim). (1) Avval rotate — leak bo'lgan secret'ni darrov almashtir/bekor qil 2.10-bob; tozalash sekin va bot allaqachon ko'rgan bo'lishi mumkin, shuning uchun birinchi qadam — eski kalitni ishlamas qilish. (2) Keyin tarixdan tozala — git tarixi abadiy 2.5-bob, oddiy rm + commit yetarli emas; maxsus vosita: git filter-repo --path .env --invert-paths.envni butun tarixdan o'chiradi, so'ng git push --force (jamoa qayta clone qiladi). Eski git filter-branch sekin va xavfli — 2025-2026'da git-filter-repo rasmiy tavsiya. Secret scanning — leak'ni oldindan ushlash (proaktiv): gitleaks — git repo'da hardcoded secret'ni regex + entropy bilan qidiradi: gitleaks git . (butun tarix), gitleaks dir . (joriy fayllar); pre-commit hook sifatida commit'dan oldin tekshiradi (leak'ni umuman kiritmaydi), GitHub Action sifatida har push/PR'da CI'da skanerlaydi 10.5-bob. GitHub Secret Scanning — GitHub o'zi push'da ma'lum provayder kalitlarini (Stripe, AWS, ...) topib ogohlantiradi yoki push'ni bloklaydi (push protection). trufflehog — gitleaks'ga o'xshash, lekin qo'shimcha imkoniyati topilgan kalitni tirikligini tekshiradi (verify) — provayder API'siga so'rov yuborib, kalit haqiqatan ishlaydimi (false positive'ni kamaytiradi). Eng yaxshisi — leak'ni oldini olish (scanning + gitignore), tozalashga qaraganda ancha arzon va xavfsiz.

2.13. Shifrlangan secret (SOPS, envelope encryption), boshqa managerlar, OIDC va audit

text
  DASROJ MUAMMO: .env fayl xavfsiz emas, lekin har secret'ni cloud manager'ga
  qo'yish og'ir. YECHIM: secret'ni SHIFRLAB, git'ga qo'yish (GitOps'ga mos).

  ENVELOPE ENCRYPTION (ikki qavatli — cloud KMS asosi):
  ┌────────────────────────────────────────────────────────────┐
  │ 1) DEK (data key) bilan secret'ni shifrla (tez, simmetrik)  │
  │ 2) DEK'ni KEK (master key, KMS'da) bilan shifrla            │
  │  shifrlangan DEK + shifrlangan secret birga saqlanadi      │
  │  master key (KEK) HECH QACHON KMS'dan chiqmaydi            │
  └────────────────────────────────────────────────────────────┘

  SOPS (Secrets OPerationS) + age/KMS — git'da SHIFRLANGAN secret:
   faqat QIYMATLAR shifrlanadi, kalit nomlari OCHIQ (diff o'qiladi)
   shifr kaliti: age (oddiy) yoki AWS/GCP KMS, Vault (envelope)
   CI/prod deshifrlaydi (kimda kalit bor); git'da xavfsiz turadi

   dotenvx — .env'ni SOPS'ga o'xshab shifrlaydi (.env.vault)

Shifrlangan secret git'da.envni git'ga qo'yish mumkin emas 2.4-bob, lekin har bir secret uchun cloud manager ham og'ir. O'rta yechim — secret'ni shifrlab, git'ga qo'yish (GitOps oqimiga mos, 10.10). Buning zamirida envelope encryption (ikki qavatli shifrlash) yotadi: secret data key (DEK) bilan shifrlanadi, DEK esa cloud KMS'dagi master key (KEK) bilan shifrlanadi — master key hech qachon KMS'dan chiqmaydi, faqat u orqali deshifrlash mumkin. AWS/GCP/Azure KMS ayni shu tamoyilda ishlaydi. Amaliy vosita — SOPS (Mozilla, hozir CNCF): u secret faylning (YAML/JSON/.env) faqat qiymatlarini shifrlaydi, kalit nomlarini ochiq qoldiradi — shuning uchun git diff'da qaysi kalit o'zgargani ko'rinadi (lekin qiymat shifrlangan). Shifr kaliti sifatida age (oddiy, kompakt) yoki AWS/GCP KMS, HashiCorp Vault ishlatiladi; CI yoki production deshifrlab, ilovaga beradi (deshifr kaliti faqat kerakli joyda). dotenvx ham shu g'oyani .env uchun beradi (.env.vault — shifrlangan .env).

Boshqa secret managerlar — AWS/Vault'dan tashqari keng tarqalganlari: Doppler — SaaS, ko'p muhitni (dev/staging/prod) markazdan boshqarish, CLI orqali process.envga inject; 1Password Secrets Automation — jamoa parol menejeri asosida, op run bilan runtime injection; GCP Secret Manager va Azure Key Vault — mos bulutlarning o'z yechimlari (AWS Secrets Manager ekvivalenti). Tanlov mezoni: qaysi bulutdasiz, rotation/audit kerakmi, jamoa hajmi.

Docker va K8s'da native secret — oddiy -e KEY=val 2.11-bob qulay, lekin docker inspect yoki process ro'yxatida ko'rinishi mumkin. Kuchliroq: Docker secret (Swarm) — secret konteynerga fayl sifatida (/run/secrets/) beriladi, env emas (buyruq tarixida qolmaydi). Kubernetes Secret — base64 (shifr emas — 2.8, Xato 7); shuning uchun ikki yaxshilash: Sealed Secrets (Bitnami) — secret'ni shifrlab git'ga qo'yasiz, klasterdagi controller deshifrlaydi (GitOps'ga mos); External Secrets Operator — K8s Secret'ni tashqi manager'dan (Vault/AWS/GCP) avtomatik sinxronlaydi (secret git'ga umuman tushmaydi, manba — manager).

CI/CD'da OIDC (kalitsiz autentifikatsiya) — an'anaviy yo'lda GitHub Actions'ga uzoq yashaydigan AWS kalit (AWS_ACCESS_KEY_ID) secret sifatida beriladi — bu statik, leak bo'lsa xavfli secret. Zamonaviy yo'l — OIDC (OpenID Connect, 10.5): GitHub Actions bulutga vaqtinchalik token bilan kiradi (ish tugagach o'chadi) — uzoq yashaydigan kalitni umuman saqlamaysiz. AWS IAM'da GitHub OIDC provayderiga ishonch (trust) o'rnatiladi va aws-actions/configure-aws-credentials OIDC rejimida ishlaydi. Bu — "eng kam secret" tamoyili: saqlanmagan secret leak bo'lmaydi.

Audit va monitoring — secrets manager'ning .envdan yana bir ustunligi: kim, qachon, qaysi secret'ni o'qigani yozib boriladi (AWS — CloudTrail, Vault — audit log). Bu leak tekshiruvida (forensics) va anomaliyani sezishda muhim: masalan, bir secret odatda faqat production serverdan o'qiladi, birdan boshqa IP'dan o'qilsa — signal. .env faylda bunday audit umuman yo'q (kim ochgani noma'lum). Amaliy qoida: secret o'qishga alert qo'ying (kutilmagan manba/vaqt), rotation bilan birga — bu "senior" darajadagi himoya.


3. Sintaksis — tez ma'lumotnoma

text
DOTENV 2.4-bob:     import 'dotenv/config'  | KEY=value (.env) | KEY="bo'sh joyli"
GITIGNORE 2.6-bob:  .env  +  .env.*  +  !.env.example   (qiymatli o'chir, andoza qoldir)
NODE ENV 2.3-bob:   process.env.KEY  | Number(process.env.PORT) || 3000
VALIDATSIYA 2.7-bob:z.object({...}).parse(process.env)  | Joi.object({...})
DOCKER 2.11-bob:    docker run -e KEY=val ...  | docker run --env-file .env ... 10.4-bob
K8S SECRET 2.11-bob:kubectl create secret generic app --from-env-file=.env 10.8-bob
GITHUB CI 2.9-bob:  ${{ secrets.DATABASE_URL }}   (workflow ichida — 10.5)
AWS SSM:          aws ssm get-parameter --name /app/db --with-decryption
AWS SECRETS MGR:  aws secretsmanager get-secret-value --secret-id app/prod
VAULT:            vault kv put secret/app db_pass=...  | vault kv get secret/app
SCANNING 2.12-bob:  gitleaks git .   | gitleaks dir .   | trufflehog | pre-commit hook
TOZALASH 2.12-bob:  git filter-repo --path .env --invert-paths   (keyin force-push)
SOPS 2.13-bob:      sops --encrypt --age <pub> f.yaml  | sops exec-env f.enc.yaml '...'
OIDC 2.13-bob:      permissions: id-token: write  +  configure-aws-credentials (kalitsiz)

4. Batafsil kod namunalari

Misol 1 — .env, .gitignore va .env.example (poydevor — 2.4, 2.6)

bash
# .env  — HAQIQIY qiymatlar (HECH QACHON Git'ga tushmasin!)
NODE_ENV=development
PORT=3000
DATABASE_URL=postgres://dev:devpass@localhost:5432/myapp   # lokal DB
JWT_SECRET=local-dev-secret-faqat-test-uchun                # dev'da zaif — OK
STRIPE_KEY=sk_test_51AbC...                                 # test kaliti (live emas)
gitignore
# .gitignore — .env'ni Git'dan butunlay chiqaramiz (2.6)
.env                # asosiy
.env.local          # lokal override
.env.*.local        # .env.production.local va h.k.
!.env.example       #  ISTISNO: andozani Git'da QOLDIR (oldida "!")
bash
# .env.example  — KALITLAR andozasi (QIYMATSIZ — Git'ga TUSHADI — 2.6)
NODE_ENV=development
PORT=3000
DATABASE_URL=          # postgres://user:pass@host:5432/db ko'rinishida to'ldiring
JWT_SECRET=            # `openssl rand -hex 32` bilan yarating
STRIPE_KEY=            # Stripe dashboard'dan oling
#  Yangi dasturchi: cp .env.example .env   so'ng qiymatlarni to'ldiradi

Misol 2 — dotenv'ni Node.js'da yuklash (5.8, 2.3, 2.4)

typescript
//  ENG TEPADA — boshqa importlardan OLDIN (aks holda env hali bo'sh)
import 'dotenv/config';                 // .env'ni process.env'ga yuklaydi

// endi har joyda process.env ishlaydi:
const port = Number(process.env.PORT) || 3000;      // string  son (2.3)
const dbUrl = process.env.DATABASE_URL;             // string | undefined

if (!dbUrl) {
  throw new Error('DATABASE_URL yetishmayapti (.env tekshiring)');  // fail-fast (2.7)
}

console.log(`Server ${port}-portda ishga tushyapti`);
//  DIQQAT: secret'ni log'ga chiqarma! console.log(dbUrl) — MUMKIN EMAS (Xato 2)

Misol 3 — Env validatsiya (Zod bilan — 5.9, 2.7)

typescript
// src/config/env.ts — env'ni BIR JOYDA, tipli va tekshirilgan holda
import 'dotenv/config';
import { z } from 'zod';

const envSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  PORT: z.coerce.number().default(3000),          // "3000"  3000 (avto o'girish)
  DATABASE_URL: z.string().url(),                 // to'g'ri URL bo'lishi shart
  JWT_SECRET: z.string().min(32),                 // kamida 32 belgi (kuchli — 2.7)
  STRIPE_KEY: z.string().startsWith('sk_'),       // formatni tekshir
});

// parse — xato bo'lsa BU YERDA yiqiladi (production'gacha bormaydi — fail-fast)
const parsed = envSchema.safeParse(process.env);
if (!parsed.success) {
  console.error(' Env xato:', parsed.error.flatten().fieldErrors);
  process.exit(1);                                // ilovani BOSHIDA to'xtat
}

export const env = parsed.data;                   // tipli: env.PORT — number 
// ishlatish: import { env } from './config/env';   env.JWT_SECRET (string)

Misol 4 — Docker'da env (-e va --env-file — 10.4, 2.11)

bash
# 1) Bitta o'zgaruvchi (-e / --env) — tez sinash uchun
docker run -e NODE_ENV=production -e PORT=3000 my-app

# 2) Fayldan (--env-file) — ko'p o'zgaruvchi (lokal/staging uchun qulay)
docker run --env-file .env my-app          # .env'ni konteynerga inject qiladi
#  Image ICHIGA .env'ni COPY QILMA — image registry'ga chiqsa secret ketadi!
#    env'ni RUNTIME'da ber (build-time emas)
yaml
# docker-compose.yml — env_file bilan (10.4: 2.x)
services:
  api:
    image: my-app
    env_file: .env                # .env'dagi hammasini inject qiladi
    environment:                  # yoki ayrim-ayrim (compose ichida)
      - NODE_ENV=production
#  docker-compose.yml Git'da bo'ladi, lekin .env — YO'Q (gitignore — 2.6)

Misol 5 — Kubernetes Secret (10.8, 2.11)

bash
# 1) Secret yaratish (.env fayldan — eng oson)
kubectl create secret generic app-secrets --from-env-file=.env
# yoki bittalab:
kubectl create secret generic app-secrets \
  --from-literal=JWT_SECRET='uzun-tasodifiy-qiymat' \
  --from-literal=DB_PASSWORD='Xk9#mP2...'
#  K8s Secret base64 (shifr EMAS) — etcd encryption at-rest yoqilgan bo'lsin (2.8)
yaml
# Deployment'da Secret'ni env sifatida ulash (10.8: 2.x)
spec:
  containers:
    - name: api
      image: my-app
      envFrom:
        - secretRef:
            name: app-secrets        # butun Secret'ni env qilib inject
      # yoki bitta o'zgaruvchi:
      env:
        - name: JWT_SECRET
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: JWT_SECRET        # faqat kerakli kalit (least privilege — 2.8)

Misol 6 — GitHub Actions secret (CI/CD — 10.5, 2.9)

yaml
# .github/workflows/deploy.yml — secret'lar repo Settings'da saqlanadi
# (Settings  Secrets and variables  Actions  New repository secret)
name: Deploy
on: { push: { branches: [main] } }

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production           # environment secret'lari (qo'shimcha himoya)
    steps:
      - uses: actions/checkout@v4
      - name: Deploy serverga
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}   # secrets context (2.9)
          SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
        run: |
          echo "Deploy boshlandi"      #  echo "$DATABASE_URL" QILMA — log'ga chiqadi!
          ./deploy.sh
#  GitHub log'da secret'ni AVTOMATIK mask qiladi (*** ko'rinadi), lekin
#   fork'dan kelgan PR'ga secret BERILMAYDI (xavfsizlik — GitHub docs 2026)

Misol 7 — AWS Secrets Manager'dan o'qish (SDK v3 — 2.9)

typescript
// AWS Secrets Manager'dan secret'ni RUNTIME'da o'qish (@aws-sdk/client-secrets-manager)
import {
  SecretsManagerClient,
  GetSecretValueCommand,
} from '@aws-sdk/client-secrets-manager';

const client = new SecretsManagerClient({ region: 'us-east-1' });

export async function getSecret(secretId: string): Promise<Record<string, string>> {
  const command = new GetSecretValueCommand({ SecretId: secretId });
  const response = await client.send(command);     // IAM ruxsati bilan (least privilege — 2.8)
  return JSON.parse(response.SecretString!);       // {"DB_PASSWORD":"...","JWT_SECRET":"..."}
}

// ishga tushishda bir marta o'qib, process.env'ga joylaymiz (yoki config'ga):
const secrets = await getSecret('myapp/production');
process.env.DB_PASSWORD = secrets.DB_PASSWORD;
//  Kodda HECH QANDAY parol yo'q — IAM role serverga secret o'qish huquqini beradi
//    rotation bo'lsa 2.10-bob, keyingi o'qishda YANGI qiymat keladi (qayta deploysiz)

Misol 8 — NestJS ConfigModule (8.14, 2.11)

typescript
// app.module.ts — env'ni markazlashgan, validatsiyali o'qish
import { ConfigModule } from '@nestjs/config';
import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,                          // hamma modulda ishlasin
      envFilePath: '.env',                     // qaysi fayl (lokal)
      validationSchema: Joi.object({           // ishga tushishda tekshir (fail-fast — 2.7)
        NODE_ENV: Joi.string().valid('development', 'production').default('development'),
        PORT: Joi.number().default(3000),
        DATABASE_URL: Joi.string().uri().required(),
        JWT_SECRET: Joi.string().min(32).required(),
      }),
    }),
  ],
})
export class AppModule {}
typescript
// ishlatish (har joyda inject — 8.2)
constructor(private config: ConfigService) {}
const secret = this.config.get<string>('JWT_SECRET');   // tipli, markazlashgan
//  process.env'ga to'g'ridan murojaat o'rniga config.get — sinovga oson, markazda

Misol 9 — gitleaks bilan secret scanning (2.12)

bash
# 1) Lokal: butun git tarixini skanerlash (leak bormi?)
gitleaks git .                          # commit tarixini regex+entropy bilan tekshir
gitleaks dir .                          # joriy (commit qilinmagan) fayllarni
gitleaks git . --report-path leaks.json --report-format json   # hisobot fayli
#  topsa exit code 1 (CI to'xtaydi); topmasa 0
yaml
# 2) Pre-commit hook (.pre-commit-config.yaml) — commit'dan OLDIN tekshir
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.x
    hooks:
      - id: gitleaks                    # secret bo'lgan commit BLOKLANADI
yaml
# 3) GitHub Action — har push/PR'da CI'da skanerlash (10.5)
- name: Secret scanning
  uses: gitleaks/gitleaks-action@v2
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
#  GitHub o'zining "secret scanning + push protection"ini ham yoq (Settings  Security)

Misol 10 — Git tarixidan leak bo'lgan secret tozalash (2.12)

bash
#  TARTIB: AVVAL secret'ni ROTATE qil (yangi yarat, eskini BEKOR qil — 2.10)
#    tozalash sekin, bot esa allaqachon ko'rgan bo'lishi mumkin!

# 1) git-filter-repo o'rnatish (rasmiy tavsiya — eski filter-branch'dan yaxshi)
pip install git-filter-repo

# 2) .env (yoki aniq fayl)'ni BUTUN tarixdan o'chirish
git filter-repo --path .env --invert-paths     # .env ni hamma commit'dan olib tashla
#   --invert-paths = berilgan path'NI o'chir (qolganini saqla)

# 3) Agar faqat bitta SATR (kalit) bo'lsa — matn bo'yicha:
git filter-repo --replace-text <(echo 'sk_live_51H8x==>REMOVED')

# 4) Remote'ni qayta ulab, force-push (tarix qayta yozildi)
git remote add origin <URL>
git push origin --force --all
#  Jamoa: hamma QAYTA clone qilsin (eski local'da hali secret bor)
#  Yana takror: rotate qilmasang, tozalash O'ZI yetarli emas (2.5, 2.10)

Misol 11 — SOPS bilan git'da shifrlangan secret (2.13)

bash
# 1) age kaliti yaratish (oddiy, kalitsiz KMS o'rniga)
age-keygen -o key.txt                 # key.txt — MAXFIY (gitignore'da!)
# public qismini SOPS'ga beramiz (age1...):
export SOPS_AGE_KEY_FILE=key.txt

# 2) secret faylni SHIFRLASH (faqat QIYMATLAR shifrlanadi, kalitlar ochiq)
sops --encrypt --age age1qz...public secrets.dec.yaml > secrets.enc.yaml
#     secrets.enc.yaml GIT'GA tushishi MUMKIN (qiymat shifrlangan)

# 3) ishlatishdan oldin DESHIFRLASH (kimda kalit bor — CI/prod)
sops --decrypt secrets.enc.yaml > secrets.dec.yaml    # yoki to'g'ridan env'ga:
sops exec-env secrets.enc.yaml 'node app.js'          # deshifrlab process.env'ga

#  Prod'da: AWS KMS bilan (age o'rniga) — envelope encryption (2.13)
#    sops --encrypt --kms arn:aws:kms:...:key/xxx secrets.yaml
yaml
# secrets.enc.yaml (SOPS chiqishi) — kalit OCHIQ, qiymat SHIFRLANGAN (diff o'qiladi)
DATABASE_URL: ENC[AES256_GCM,data:9xK2...==,tag:...]     # <- qiymat shifr
JWT_SECRET: ENC[AES256_GCM,data:pQ7v...==,tag:...]
sops:
  age:
    - recipient: age1qz...                              # kim deshifrlay oladi
#  secrets.dec.yaml (ochiq) — gitignore'da; faqat secrets.enc.yaml git'da

Misol 12 — GitHub Actions'da OIDC (kalitsiz AWS kirish — 2.13, 10.5)

yaml
# .github/workflows/deploy.yml — statik AWS kalit SAQLAMAYMIZ
permissions:
  id-token: write            #  OIDC token so'rash uchun SHART
  contents: read
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::1234567890:role/github-oidc-deploy
          aws-region: us-east-1
          #  AWS_ACCESS_KEY_ID/SECRET YO'Q — OIDC token bilan VAQTINCHALIK
          #    credential olinadi (ish tugagach o'chadi — leak bo'lmaydi — 2.13)
      - run: aws s3 ls        # endi AWS'ga vaqtinchalik ruxsat bor

5. To'g'ri va noto'g'ri holatlar

1) Secret qayerda

text
 const apiKey = "sk_live_..."        // kodga yozilgan (hardcoded — 2.5)
 const apiKey = process.env.API_KEY  // environment'dan (12-factor — 2.2)

2) .env va Git

text
 git add .env  (qiymatli fayl Git'ga tushadi — leak — 2.6)
 .gitignore'da .env; Git'da faqat .env.example (qiymatsiz — 2.6)

3) Env o'qish va turlar

text
 if (process.env.DEBUG) {...}        // "false" ham truthy! (string — 2.3)
 if (process.env.DEBUG === 'true')   // yoki Zod bilan validatsiya (2.7)

4) Production secret manbasi

text
 Production'da ham .env fayl (rotation/audit yo'q, server'da ochiq turadi)
 Secrets Manager / SSM / Vault (shifr, IAM, rotation, audit — 2.9)

5) Secret va log

text
 console.log('Config:', process.env)  // BARCHA secret log'ga chiqadi (2.5)
 Faqat kerakli, secret'siz qiymatlarni log qil (mask — Xato 2)

6) Leak bo'lganda

text
 Git'dan o'chirib commit qilish (tarix qoladi — secret hali tirik — 2.5)
 AVVAL rotate (eskini bekor qil), KEYIN filter-repo bilan tozalash (2.12)

7) Git'da secret saqlash zarurati

text
 .env'ni git'ga to'g'ridan qo'shish (ochiq qiymat — leak — 2.4)
 SOPS/dotenvx bilan SHIFRLAB qo'yish (qiymat shifr, kalit ochiq — 2.13)

8) CI'da bulutga kirish

text
 Uzoq yashaydigan AWS_ACCESS_KEY_ID'ni CI secret sifatida saqlash (2.13)
 OIDC — vaqtinchalik token (saqlanmagan secret leak bo'lmaydi — 2.13)

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — .env Git'ga commit bo'lib ketishi

Sababi: .gitignorega qo'shilmagan, yoki qo'shishdan oldin allaqachon commit qilingan (gitignore eski tracked faylga ta'sir qilmaydi). Yechimi: .gitignorega .env qo'sh; allaqachon tushgan bo'lsa — git rm --cached .env (tracking'dan chiqar), commit qil; tarixda bo'lsa — avval rotate, keyin git filter-repo 2.12-bob. Oldini olish: loyiha boshida .gitignore + gitleaks pre-commit hook 2.12-bob.

Xato 2 — Secret log'da yoki xato xabarida chiqishi

Sababi: console.log(process.env), console.log(config), yoki xato stack-trace'da secret. Yechimi: hech qachon butun process.env yoki config obyektini log qilma; logger'da (Pino/Winston — 5.12) maxfiy maydonlarni mask qil (password: '***'); xato xabarida secret bo'lmasin. CI'da echo "$SECRET" qilma 10.5-bob.

Xato 3 — Hardcoded API key (kodda qolib ketishi)

Sababi: "tezda sinab ko'rdim" deb kodga yozib, olib tashlashni unutish. Yechimi: doim process.envdan o'qi (boshidanoq); gitleaks scanning bilan ushlash 2.12-bob; GitHub secret scanning push protection yoqish. Oldini olish: "tezda sinash" ham .envdan — hech qachon kodga emas.

Xato 4 — .env.example sinxron emas (eskirgan)

Sababi: yangi o'zgaruvchi .envga qo'shildi, lekin .env.examplega emas. Yangi dasturchi yoki CI'da o'zgaruvchi yetishmaydi (undefined). Yechimi: har yangi env qo'shganda ikkalasiga ham qo'sh (qiymatsiz example'ga); env validatsiya 2.7-bob yetishmaganini darrov ko'rsatadi (fail-fast).

Xato 5 — Production secret'ni dev'da ishlatish

Sababi: qulaylik uchun prod DATABASE_URLni lokalga nusxalash. Yechimi: har muhitda alohida secret 2.6-bob; dev — test DB, test kalitlar (sk_test_); prod credential dev mashinaga umuman tushmasin (leak xavfi + test paytida real ma'lumot buzilishi).

Xato 6 — Frontend'ga secret yuborish

Sababi: API kalit yoki secret'ni React/Next env'iga qo'yish (NEXT_PUBLIC_*, VITE_*) — bular brauzerga ketadi. Yechimi: secret faqat backendda qolsin 2.3-bob; frontend faqat public qiymatlarni ko'rsin (API base URL — secret emas); maxfiy ish backend orqali bajarilsin (frontend backend tashqi API).

Xato 7 — K8s Secret'ni shifr deb o'ylash

Sababi: K8s Secret faqat base64 (kodlash, shifr emas — har kim ochadi). Yechimi: etcd'da encryption at rest yoq 2.8-bob; yoki tashqi secrets manager (External Secrets Operator Vault/AWS); Secret'ga RBAC qo'y (kim o'qiy oladi — least privilege — 2.8).


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • dotenv/env 5.8-bob: bu bob uni chuqurlashtiradi — secret/config farqi, validatsiya, production.
  • Validatsiya 5.9-bob: Zod/Joi bilan env'ni ishga tushishda tekshirish (fail-fast — 2.7).
  • JWT/auth 5.15-bob: JWT_SECRET — eng muhim secret (leak har kim token yasaydi).
  • NestJS ConfigModule 8.14-bob: env'ni markazlashgan, tipli, validatsiyali o'qish 2.11-bob.
  • Docker 10.4-bob: -e, --env-file, compose env_file bilan injection 2.11-bob.
  • CI/CD 10.5-bob: GitHub Actions Secrets — build/deploy paytida (2.9, Misol 6).
  • Cloud/AWS 10.6-bob: Secrets Manager, SSM Parameter Store, KMS, IAM 2.9-bob.
  • Deploy/PM2 10.7-bob: ecosystem env, TLS private key serverda 2.7-bob.
  • Kubernetes 10.8-bob: Secret obyekti env/volume sifatida, RBAC 2.11-bob.
  • Terraform 10.10-bob: secret'ni state'ga yozma (state ham maxfiy bo'lsin — 2.9); SOPS/KMS bilan shifrlangan tfvars 2.13-bob.
  • Xavfsizlik (14-QISM): 14.5 — Secrets va token xavfsizligi (bu bob poydevor).

8. Eng yaxshi amaliyotlar (best practices)

  • Secret kodda emas, environment'da (12-factor III — open-source testidan o'tsin — 2.2).
  • .env .gitignore (har doim, loyiha boshida); .env.example Git'da 2.6-bob.
  • Env validatsiya (Zod/Joi — ishga tushishda, fail-fast — 2.7, Misol 3).
  • Har muhit — alohida secret (dev/staging/prod; prod credential dev'ga tushmasin — 2.6).
  • Production'da secrets manager (.env emas — shifr, IAM, audit, rotation — 2.9).
  • Least privilege (har servis faqat o'z secret'ini o'qisin — IAM/Vault policy — 2.8).
  • Rotation (rejali + leak'da shoshilinch; avval rotate keyin tozala — 2.10, 2.12).
  • Secret'ni log qilma (mask; CI'da echo qilma — Xato 2).
  • Secret scanning (gitleaks pre-commit + CI; GitHub push protection — 2.12).
  • Encryption at rest + in transit (TLS; manager/disk shifri — 2.8).
  • Frontend'ga secret bermaslik (faqat backend ushlaydi — Xato 6).
  • Git'ga secret kerak bo'lsa — shifrlab (SOPS/dotenvx; envelope encryption — 2.13).
  • CI'da OIDC (statik bulut kaliti o'rniga vaqtinchalik token — 2.13).
  • Audit yoqilgan bo'lsin (kim/qachon secret o'qidi — anomaliyaga alert — 2.13).

9. Amaliy loyiha: "Xavfsiz Secrets Pipeline'i"

Bitta full-stack ilova uchun environment va secret'larni lokaldan production'gacha xavfsiz boshqarish tizimini qurish — har muhitda to'g'ri qiymat, hech qayerda leak yo'q.

Maqsad

NestJS (yoki Express) ilovaga to'liq secrets boshqaruvini qo'shish: env validatsiya, muhit ajratish, CI secrets, secret scanning va (ixtiyoriy) cloud manager — leak'siz, fail-fast, jamoaga qulay.

Talablar (requirements)

  1. .env + .env.example + .gitignore: qiymatli .env gitignore'da, qiymatsiz .env.example Git'da (Misol 1, 2.6).
  2. dotenv yuklash: import 'dotenv/config' eng tepada, process.env ishlasin (Misol 2, 2.4).
  3. Env validatsiya: Zod yoki Joi sxema — ishga tushishda tekshir, xato bo'lsa yiqil (Misol 3/8, 2.7).
  4. Muhit ajratish: development va production uchun alohida qiymatlar (test DB vs prod) 2.6-bob.
  5. Secret'larni audit: kodingni skanerlab, bitta ham hardcoded secret qolmaganini tasdiqla 2.5-bob.
  6. gitleaks: lokal gitleaks git . toza o'tsin + pre-commit hook qo'sh (Misol 9, 2.12).
  7. GitHub Actions: CI'da gitleaks + secret'larni ${{ secrets.X }} orqali ishlat (Misol 6, 2.9).
  8. Docker injection: --env-file yoki compose env_file bilan konteynerga env ber (Misol 4, 2.11).
  9. Cloud (ixtiyoriy): SSM Parameter Store yoki Secrets Manager'dan bitta secret o'qib ko'r (Misol 7, 2.9).
  10. Rotation rejasi: leak bo'lsa qanday rotate + tozalash qilishingni SECURITY.mdda yoz (2.10, 2.12).

Maslahatlar (hint)

  • .gitignoreni birinchi commit'dan oldin sozla (keyin qo'shsangiz — tracked fayl qoladi — Xato 1).
  • JWT_SECRETni openssl rand -hex 32 bilan yarat (kuchli, tasodifiy — 2.7).
  • Validatsiyani main.ts/bootstrapdan oldin ishlat — fail-fast (Misol 3).
  • gitleaks pre-commit'ni Husky 15.3-bob bilan ulasangiz — har commit'da avtomatik 2.12-bob.
  • Hech qachon console.log(process.env) qilma (Xato 2) — sinashda ham.

"Tayyor" mezonlari (acceptance criteria)

  • .env Git'da YO'Q (git status toza); .env.example bor va to'liq.
  • Yetishmagan/noto'g'ri env'da ilova boshida yiqiladi (fail-fast — validatsiya).
  • Kodda bitta ham hardcoded secret yo'q (hammasi process.env/config).
  • gitleaks git . toza o'tadi (exit 0); pre-commit hook ishlaydi.
  • CI'da secret'lar ${{ secrets.X }} orqali (log'da *** ko'rinadi).
  • --env-file bilan Docker konteynerda ilova to'g'ri env oladi.
  • SECURITY.mdda rotation + leak'da tozalash tartibi yozilgan.

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda environment va secret'larni boshqarishni o'rgandik:

  • Config vs secret (farqi — 2.1); 12-factor config (kodda emas, environment'da; open-source testi — 2.2); environment variable (process.env, string — 2.3).
  • dotenv/.env (lokal qulaylik — 2.4); nega kodga/git'ga yozmaslik (leak, abadiy tarix — 2.5); muhit ajratish va .env.example 2.6-bob; env validatsiya (Zod/Joi, fail-fast — 2.7).
  • Encryption at rest/in transit va least privilege 2.8-bob; saqlash yechimlari (.env, GitHub Secrets, AWS Secrets Manager/SSM, Vault — 2.9); rotation 2.10-bob; injection va ConfigModule 2.11-bob; git tozalash va gitleaks scanning 2.12-bob; shifrlangan secret (SOPS/envelope), OIDC va audit 2.13-bob.

Endi siz secret'ni hech qayerda leak qilmasdan, har muhitda to'g'ri qiymat bilan ilovani xavfsiz boshqara olasiz — bu DevOps va xavfsizlikning eng nozik, "senior" chizig'i.

10-QISM (DevOps va Deploy) TO'LIQ TUGADI!

  • 10.1 Linux server va SSH (poydevor); 10.2 Nginx (reverse proxy, load balancer); 10.3 Docker (image, container); 10.4 Docker Compose va multi-stage build.
  • 10.5 CI/CD (GitHub Actions); 10.6 Cloud (AWS — EC2, S3, RDS); 10.7 Deployment (PM2, domen, SSL); 10.8 Kubernetes asoslari.
  • 10.9 Monitoring va logging (Prometheus, Grafana, Sentry); 10.10 Infrastructure as Code (Terraform); 10.11 Environment va secrets boshqaruvi (mana shu bob).

Bu qism bilan siz bo'sh serverni olib, ilovani xavfsiz, masshtablanadigan, monitoring qilinadigan, avtomatik deploy bo'ladigan production tizimga aylantira olasiz — to'liq DevOps zanjiri. Bu — ko'pchilik kursda umuman o'rgatilmaydigan, lekin senior dasturchini junior'dan ajratadigan alohida ustunlik.

Endi backend va DevOps poydevori tayyor — vaqt keldi foydalanuvchi ko'radigan tomonga, ya'ni frontendga o'tish.

Keyingi qism — 11-QISM: Frontend — React (chuqur). Hozirgacha biz API'lar, server, deploy bilan ishladik — foydalanuvchi bularning hech birini ko'rmaydi. U faqat brauzerdagi interfeysni — tugma, forma, ro'yxat, animatsiyani ko'radi. React — dunyodagi eng mashhur frontend kutubxonasi: komponentlarga asoslangan, deklarativ, tez. 11-QISM'da JSX, komponentlar, props, state, hooks (useState, useEffect...), routing, formalar, performance va testing'ni noldan chuqur o'rganamiz — va nihoyat siz qurgan backend'ga ulanadigan to'liq, jonli interfeys yasaymiz.


Foydalanilgan rasmiy/ishonchli manbalar

  • The Twelve-Factor App — III. Config (12factor.net/config) — config'ni environment'da saqlash, open-source testi (2026)
  • HashiCorp Vault Documentation — "What is Vault?", dynamic secrets, policies, encryption at rest (developer.hashicorp.com/vault, 2026)
  • AWS Secrets Manager User Guide — intro, automatic rotation, KMS encryption, retrieving secrets; SSM Parameter Store (docs.aws.amazon.com, 2026)
  • GitHub Docs — "Using secrets in GitHub Actions" — secrets context, masking, fork cheklovi, environment secrets (2026)
  • dotenv (npm) va dotenvx — .env format, dotenv/config, .env.example konvensiyasi (2026)
  • gitleaks (github.com/gitleaks/gitleaks) — secret scanning (regex+entropy), pre-commit, GitHub Action (2026)
  • trufflehog (github.com/trufflesecurity/trufflehog) — secret scanning va topilgan kalitni tekshirish (verified) (2026)
  • git-filter-repo — git tarixidan fayl/secret tozalash (rasmiy tavsiya, filter-branch o'rniga, 2026); BFG Repo-Cleaner — alternativa
  • GitHub Docs — "Secret scanning" va "Push protection" — repozitoriyda kalitlarni topish/bloklash (2026)
  • SOPS (github.com/getsops/sops) + age/KMS — git'da shifrlangan secret fayllarni saqlash (envelope encryption) (2026)
  • Kubernetes Documentation — "Secrets", "Encrypting Confidential Data at Rest" (base64 vs shifr, etcd encryption); Sealed Secrets, External Secrets Operator (2026)
  • Docker Documentation — "Manage sensitive data with Docker secrets", --env-file (2026)
  • NestJS Documentation — "Configuration" (ConfigModule, validationSchema) (2026)
  • OWASP — "Secrets Management Cheat Sheet" (rotation, least privilege, at-rest/in-transit) (2026)

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
10.11-bob: Environment va secrets boshqaruvi — Wisar