Mundarija (40)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Config nima, secret nima va farqi
- 2.2. 12-factor config: sozlama kodda emas, environment'da
- 2.3. Environment variable nima (process.env)
- 2.4. .env fayl va dotenv (lokal qulaylik)
- 2.5. Nega secret'ni kodga/git'ga yozmaslik (leak va abadiy tarix)
- 2.6. Muhit ajratish (dev/staging/prod) va .env.example
- 2.7. Secret turlari va env validatsiya
- 2.8. Encryption at rest va in transit, least privilege
- 2.9. Secret saqlash yechimlari (lokal, CI, cloud, vault)
- 2.10. Secret rotation (vaqti-vaqti almashtirish)
- 2.11. NestJS ConfigModule va secret injection
- 2.12. Git'dan secret tozalash va secret scanning
- 2.13. Shifrlangan secret (SOPS, envelope encryption), boshqa managerlar, OIDC va audit
- 3. Sintaksis — tez ma'lumotnoma
- 4. Batafsil kod namunalari
- Misol 1 — .env, .gitignore va .env.example (poydevor — 2.4, 2.6)
- Misol 2 — dotenv'ni Node.js'da yuklash (5.8, 2.3, 2.4)
- Misol 3 — Env validatsiya (Zod bilan — 5.9, 2.7)
- Misol 4 — Docker'da env (-e va --env-file — 10.4, 2.11)
- Misol 5 — Kubernetes Secret (10.8, 2.11)
- Misol 6 — GitHub Actions secret (CI/CD — 10.5, 2.9)
- Misol 7 — AWS Secrets Manager'dan o'qish (SDK v3 — 2.9)
- Misol 8 — NestJS ConfigModule (8.14, 2.11)
- Misol 9 — gitleaks bilan secret scanning (2.12)
- Misol 10 — Git tarixidan leak bo'lgan secret tozalash (2.12)
- Misol 11 — SOPS bilan git'da shifrlangan secret (2.13)
- Misol 12 — GitHub Actions'da OIDC (kalitsiz AWS kirish — 2.13, 10.5)
- 5. To'g'ri va noto'g'ri holatlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- 8. Eng yaxshi amaliyotlar (best practices)
- 9. Amaliy loyiha: "Xavfsiz Secrets Pipeline'i"
- Maqsad
- Talablar (requirements)
- Maslahatlar (hint)
- "Tayyor" mezonlari (acceptance criteria)
- 10. Xulosa va keyingi bobga ko'prik
- Foydalanilgan rasmiy/ishonchli manbalar
Environment variables va secrets boshqaruvi — 12-factor config (10.11-bob)
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 ilovangiz lokal kompyuteringizda 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, hisobingizni o'g'irlaydi yoki bulutda mayning qiladi (sizning hisobingizga minglab 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 ajrating. Birinchisi — secret (maxfiy): bu uyingizning 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.exampleko'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
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 hisoblang (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 hisoblang (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
12-FACTOR APP (12factor.net) — bulutga mos ilova qurish 12 tamoyili.
III-tamoyil — CONFIG: "Config'ni ENVIRONMENT'da saqlang, 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 saqlang, 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)
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'giring (2.7 validatsiya)
❗ Frontend'da process.env YO'Q (brauzer) — bu faqat backend/Node uchunEnvironment variable (muhit o'zgaruvchisi) — operatsion tizim har bir jarayonga (process) beradigan
KALIT=qiymatjuftliklari. Ilova ulardan o'qiydi, lekin ularni o'z koditida saqlamaydi — bu config'ni tashqaridan olishning standart mexanizmi. Terminalda o'rnatish: Linux/mac'daexport DB_HOST=localhost(yoki bitta buyruq oldidanDB_HOST=localhost node app.js), Windows PowerShell'da$env:DB_HOST="localhost". Node.js'da o'qish —process.envorqali (5.8: 2.1):process.env.DB_HOST. Eng keng adashish:process.envqiymatlari har doim string —process.env.PORT"3000"(matn), raqam emas; shuning uchunNumber(process.env.PORT), boolean uchun esa=== "true"tekshirish kerak (2.7 validatsiya bu ishni avtomatlashtiradi). Ikkinchi muhim nuqta:process.envfaqat 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)
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'shing!
❗ .env — faqat LOKAL/dev qulayligi; production'da secrets manager (2.9)dotenv — har ishga tushirishda o'nlab
exportyozish o'rniga, barcha o'zgaruvchilarni bitta.envfaylga yozib, uni avtomatikprocess.envga yuklaydigan kutubxona (dotenv, npm — 5.8: 2.3)..envfayl formati — har qatordaKALIT=qiymat;#bilan izoh; bo'sh joy yoki maxsus belgi bo'lsa qiymatni qo'shtirnoqga oling (JWT_SECRET="..."); ko'p qatorli qiymat uchun\n(yoki haqiqiy qator). Node.js'da yuklash — eng tepadaimport 'dotenv/config'(yokirequire('dotenv').config()), boshqa importlardan oldin (aks holda ular yuklanganda env hali bo'sh bo'ladi). 2025-2026'dadotenvxham keng — u.envfayllarni shifrlab saqlashga imkon beradi (qo'shimcha himoya). Eng muhim qoida:.envfayl hech qachon Git'ga tushmasligi kerak — uni.gitignorega qo'shing (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)
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 -pyoki 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
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 ishlatmang (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) vaproduction(real foydalanuvchilar) — bir xil kalitlar (DATABASE_URL,JWT_SECRET...), lekin butunlay boshqa qiymatlar: lokaldalocalhost, 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.examplepattern: 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 ishlatmang — test paytidagi xato real ma'lumotni buzadi (Xato 5).
2.7. Secret turlari va env validatsiya
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 TEKSHIRISH:
┌────────────────────────────────────────────────────────┐
│ 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 hisobingizdan 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); OAuthclient_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'zgaruvchiundefinedbo'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
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)
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 —
.envfayl (.gitignoreda, 2.4): oddiy va tez, lekin faqat lokal, tarqatib bo'lmaydi, rotation yo'q. (2) CI/CD — GitHub 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 managed — AWS Secrets Manager yoki SSM Parameter Store: markazlashgan, at-rest shifr (KMS), IAM access, audit (CloudTrail). Ikkisining farqi: Secrets Manager — avtomatik 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 (SecureStringturi), rotation o'zi yo'q. (4) Self-hosted — HashiCorp 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)
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 qilish), KEYIN tozalash 2.12-bob
→ eski kalitni o'chirish (revoke) — botlar uni ishlata olmasinSecret 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 rotation — leak aniqlangach darrov: xodim ketdi, secret git'ga chiqdi, yoki shubhali faollik. Eng muhim tartib: leak bo'lganda avval rotate qiling (yangi secret yarating, eskisini bekor qiling/revoke), keyin git tarixini tozalang 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
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 tekshirish │
│ 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) ilovaningprocess.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 })—isGlobalbilan hamma modulda ishlaydi,validationSchema(Joi/Zod) bilan ishga tushishda tekshiradi (fail-fast — 2.7), vaconfig.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=valyoki--env-file .env(10.4: 2.x); Kubernetes —Secretobyekti env yoki volume sifatida ulanadi (10.8: 2.x); PM2 —ecosystem.config.jsichidaenv_production(10.7: 2.6). Hammasining mohiyati bir xil: secret tashqaridan, env orqali keladi.
2.12. Git'dan secret tozalash va secret scanning
SECRET GIT'GA CHIQIB KETDI — ikki ish (TARTIB MUHIM):
1) AVVAL ROTATE — leak bo'lgan secret'ni DARROV almashtirish/bekor qilish 2.10-bob
(tozalash sekin; bot esa allaqachon ko'rgan bo'lishi mumkin)
2) KEYIN TARIXDAN TOZALASH — git tarixi abadiy 2.5-bob, maxsus vosita kerak:
git filter-repo --path .env --invert-paths ← .env'ni BUTUN tarixdan o'chirish
→ 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'raGit'dan secret tozalash — secret tasodifan commit bo'lib ketsa, ikki ish (tartib muhim). (1) Avval rotate — leak bo'lgan secret'ni darrov almashtiring/bekor qiling 2.10-bob; tozalash sekin va bot allaqachon ko'rgan bo'lishi mumkin, shuning uchun birinchi qadam — eski kalitni ishlamas qilish. (2) Keyin tarixdan tozalash — 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'nggit push --force(jamoa qayta clone qiladi). Eskigit filter-branchsekin 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
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 shifrlash (tez, simmetrik)│
│ 2) DEK'ni KEK (master key, KMS'da) bilan shifrlash │
│ → 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.envuchun 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 runbilan 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=val2.11-bob qulay, lekindocker inspectyoki 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 vaaws-actions/configure-aws-credentialsOIDC 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..envfaylda 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
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)
# .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 — .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 "!")# .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'ldiradiMisol 2 — dotenv'ni Node.js'da yuklash (5.8, 2.3, 2.4)
// ❗ 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 chiqarmang! console.log(dbUrl) — MUMKIN EMAS (Xato 2)Misol 3 — Env validatsiya (Zod bilan — 5.9, 2.7)
// 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 tekshirish
});
// 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'xtatish
}
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)
# 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 QILMANG — image registry'ga chiqsa secret ketadi!
# env'ni RUNTIME'da bering (build-time emas)# 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)
# 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)# 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)
# .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" QILMANG — 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)
// 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)
// 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 tekshirish (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 {}// 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, markazdaMisol 9 — gitleaks bilan secret scanning (2.12)
# 1) Lokal: butun git tarixini skanerlash (leak bormi?)
gitleaks git . # commit tarixini regex+entropy bilan tekshirish
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# 2) Pre-commit hook (.pre-commit-config.yaml) — commit'dan OLDIN tekshirish
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.x
hooks:
- id: gitleaks # secret bo'lgan commit BLOKLANADI# 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 yoqing (Settings → Security)Misol 10 — Git tarixidan leak bo'lgan secret tozalash (2.12)
# ❗❗ TARTIB: AVVAL secret'ni ROTATE qiling (yangi yarating, eskini BEKOR qiling — 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 tashlash
# --invert-paths = berilgan path'NI o'chirish (qolganini saqlash)
# 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 qilinmasa, tozalash O'ZI yetarli emas (2.5, 2.10)Misol 11 — SOPS bilan git'da shifrlangan secret (2.13)
# 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# 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'daMisol 12 — GitHub Actions'da OIDC (kalitsiz AWS kirish — 2.13, 10.5)
# .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 bor5. To'g'ri va noto'g'ri holatlar
1) Secret qayerda
❌ 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
❌ 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
❌ 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
❌ 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
❌ console.log('Config:', process.env) // BARCHA secret log'ga chiqadi 2.5-bob
✅ Faqat kerakli, secret'siz qiymatlarni log qilish (mask — Xato 2)6) Leak bo'lganda
❌ Git'dan o'chirib commit qilish (tarix qoladi — secret hali tirik — 2.5)
✅ AVVAL rotate (eskini bekor qilish), KEYIN filter-repo bilan tozalash (2.12)7) Git'da secret saqlash zarurati
❌ .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
❌ Uzoq yashaydigan AWS_ACCESS_KEY_ID'ni CI secret sifatida saqlash 2.13-bob
✅ 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'shing; allaqachon tushgan bo'lsa — git rm --cached .env (tracking'dan chiqaring), commit qiling; 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 qilmang; logger'da (Pino/Winston — 5.12) maxfiy maydonlarni mask qiling (password: '***'); xato xabarida secret bo'lmasin. CI'da echo "$SECRET" qilmang 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 restni yoqing 2.8-bob; yoki tashqi secrets manager (External Secrets Operator → Vault/AWS); Secret'ga RBAC qo'ying (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, composeenv_filebilan 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:
ecosystemenv, 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 yozmaslik (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.exampleGit'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 (
.envemas — 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 tozalash — 2.10, 2.12).
- Secret'ni log qilmaslik (mask; CI'da
echoqilmaslik — 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)
.env+.env.example+.gitignore: qiymatli.envgitignore'da, qiymatsiz.env.exampleGit'da (Misol 1, 2.6).- dotenv yuklash:
import 'dotenv/config'eng tepada,process.envishlasin (Misol 2, 2.4). - Env validatsiya: Zod yoki Joi sxema — ishga tushishda tekshiring, xato bo'lsa yiqilsin (Misol 3/8, 2.7).
- Muhit ajratish:
developmentvaproductionuchun alohida qiymatlar (test DB vs prod) 2.6-bob. - Secret'larni audit: kodingizni skanerlab, bitta ham hardcoded secret qolmaganini tasdiqlang 2.5-bob.
- gitleaks: lokal
gitleaks git .toza o'tsin + pre-commit hook qo'shing (Misol 9, 2.12). - GitHub Actions: CI'da gitleaks + secret'larni
${{ secrets.X }}orqali ishlating (Misol 6, 2.9). - Docker injection:
--env-fileyoki composeenv_filebilan konteynerga env bering (Misol 4, 2.11). - Cloud (ixtiyoriy): SSM Parameter Store yoki Secrets Manager'dan bitta secret o'qib ko'ring (Misol 7, 2.9).
- Rotation rejasi: leak bo'lsa qanday rotate + tozalash qilishingizni
SECURITY.mdda yozing (2.10, 2.12).
Maslahatlar (hint)
.gitignoreni birinchi commit'dan oldin sozlang (keyin qo'shsangiz — tracked fayl qoladi — Xato 1).JWT_SECRETniopenssl rand -hex 32bilan yarating (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)qilmang (Xato 2) — sinashda ham.
"Tayyor" mezonlari (acceptance criteria)
-
.envGit'da YO'Q (git statustoza);.env.examplebor 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-filebilan 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.example2.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 —
.envformat,dotenv/config,.env.examplekonvensiyasi (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)
O'qiganingizni mustahkamlang
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!