IlmHamroh
JavaScript Full-stack/25-qism. HTTP, Express va REST API39/51-dars16 daqiqa
Mundarija (28)

Sirlarni boshqarish: .env, git tarixi, rotatsiya va secret manager'lar

Qisqacha: Sir — parol, API kalit, token, ichida parol bor baza manzili. .env faylni git'dan saqlaydi, lekin sirni himoya qilmaydi: u diskda ochiq matn, jarayon muhitida, ba'zan logda. Eng xavfli xato — sirni bir marta commit qilish: keyingi commit'da o'chirsangiz ham, u tarixda qoladi (kanon git log -S bilan ikkala commit'ni topdi). Sizib chiqqan sirning yagona davosi — rotatsiya: eski kalitni bekor qilib, yangisini berish. Jamoa va serverlar ko'payganda sirlar maxsus omborga (Vault, Doppler, Infisical, bulut secret manager) yoki shifrlangan faylga (SOPS + age) ko'chadi.

Bu darsda

  • Sir nima va u qayerlardan sizib chiqishini sanab bera olasiz.
  • Git tarixidagi sirni topasiz va nega o'chirish yetmasligini tushuntira olasiz.
  • Sir sizib chiqqanda qadamlar tartibini bilasiz.
  • Ikki kalitli rotatsiyani (eski va yangi bir vaqtda) kodda yozasiz.
  • Sir saqlash usullarini (env, fayl, secret manager, SOPS) solishtira olasiz.

Oldin bilishingiz kerak: Environment o'zgaruvchilar va .env, Env validatsiyasi va tipli config, crypto 1: hash va HMAC, .gitignore: to'liq qo'llanma.

1. Nega bu kerak?

Jasur kechqurun xorijiy mijoz uchun Stripe to'lov tizimini ulayapti. Tezroq sinash uchun kalitni to'g'ridan kodga yozdi: const KALIT = "sk_live_…" (Stripe'ning haqiqiy, pul yechadigan kalitlari shu prefiks bilan boshlanadi). Ishladi, commit qildi, push qildi. Ertalab esladi va kalitni .env ga ko'chirib, yangi commit qildi: "kalit olib tashlandi". Hammasi tozadek.

Lekin repo ochiq. Kalit tunda 9 soat tarixda turdi. GitHub'dagi ochiq kodni avtomatik skanerlaydigan botlar bor — ular bunday kalitni tez topadi. Kalit esa haqiqiy pul yechishi mumkin.

env darsida sozlamani koddan chiqardik, tipli config darsida xato xabarida qiymatni yashirdik. Bu dars sirlarning butun hayotini yopadi: qayerda saqlanadi, qanday sizib chiqadi, sizsa nima qilinadi.

O'xshatish: uy kaliti. Kalitni eshik ostidagi gilam tagiga qo'yish (.env) — ko'chadagi odamdan yashiradi, lekin uyga kirgan har kishi topadi. Kalitni yo'qotsangiz, "topilmasa kerak" deb kutmaysiz — qulfni almashtirasiz. Bu — rotatsiya.

2. Sir qayerlardan sizadi

2.1 Xarita

Joy Qanday Kim ko'radi
Git tarixi Bir marta commit Repo'ga kirgan har kim, abadiy
Log console.log(config), xato xabari Log tizimiga kirganlar
Xato javobi Stack, detail Mijoz (global ishlovchi darsi)
Frontend build VITE_…, NEXT_PUBLIC_… Har foydalanuvchi
Jarayon muhiti Bola jarayon, crash dump, docker inspect Server foydalanuvchilari
Chat, skrinshot, AI yordamchi "Mana kalit, nega ishlamayapti?" Suhbat ishtirokchilari va xizmat
CI logi echo $KALIT Repo'ga kirganlar

Oxirgi qatorlar texnik emas, lekin eng ko'p uchraydi. AI yordamchiga kod bilan birga .env ni yuborish — sirni uchinchi tomonga berish demak (AI bilan ishlash darsi).

2.2 Kanon: sir xato xabariga tushmaydi

vazifalar-api da hozircha haqiqiy sir yo'q (auth — 28-qismda). Lekin himoya allaqachon bor:

  • configYukla xatosida qiymatlar yo'q — test assert.doesNotMatch(x.message, /maxfiy-qiymat/) (tipli config darsi).
  • 500 javobida ichki xabar yo'q — test /parol|maxfiy|…/ (global ishlovchi darsi).
  • .env.example da faqat namuna — "haqiqiy parol/kalit YO'Q va bo'lmasligi kerak".
  • Loglarda authorization, cookie, *.parol, *.token — yashiriladi (Pino darsida).

3. Git tarixi

3.1 Kanon tajribasi

Kanon vaqtinchalik repo yaratdi va Jasurning xatosini takrorladi (t39-sirlar.txt; kalit — soxta sk_test_SOXTA_…): config.js ga kalit yozildi va commit qilindi, keyingi commit'da olib tashlandi. Chiqishda har qator — bitta git buyrug'i va uning natijasi. Asosiy savol: kalit hozirgi fayllarda yo'q bo'lsa ham, tarixda topiladimi?

text
git status --short (.gitignore'da .env): "?? .env.example\n?? .gitignore"
git check-ignore -v .env: .gitignore:1:.env	.env
joriy fayllarda: ".env.example\n.gitignore"
git log -p -S "<kalit>" --oneline (kalit TARIXDA):
a9042b6 kalit olib tashlandi
411a5c3 tolov qo'shildi
git grep (barcha commitlarda): 1 ta mos

O'qiymiz:

  1. .env — .gitignore tufayli umuman ko'rinmaydi. Yaxshi.
  2. Joriy fayllarda kalit yo'q — config.js tozalangan.
  3. git log -S "<kalit>" — "shu matn qo'shilgan yoki olib tashlangan commit'lar": ikkalasi topildi. -p bilan har birining farqi (diff) ham ko'rinadi — kalit to'liq.

git log -S ni "pickaxe" (cho'kich) deyishadi — u tarixdan matnni qazib chiqaradi. Hujumchi ham aynan shuni qiladi. Kanon xulosasi: o'chirish yetmaydi — kalit almashtiriladi (rotatsiya), keyin kerak bo'lsa tarix tozalanadi.

3.2 Tarixni tozalash — ikkinchi qadam

Tarixdan sirni olib tashlash mumkin (git filter-repo, BFG). Lekin:

  • Repo'ni klonlagan har kishida eski tarix qoladi.
  • GitHub fork'lari, keshlar, CI artefaktlari — sizning nazoratingizdan tashqarida.
  • Tarixni qayta yozish butun jamoaga force push va qayta klon degani.

Shuning uchun tartib qat'iy: avval rotatsiya, keyin (ixtiyoriy) tozalash. Tozalash usullari — 32-qismda.

Tekshirib ko'ring: Kalit .env da edi, lekin .gitignore ga .env qatorini kalit commit qilingandan keyin qo'shdingiz. .env endi himoyalanganmi?

Javob

Yo'q. .gitignore faqat kuzatilmayotgan fayllarga ta'sir qiladi. .env allaqachon kuzatuvda — keyingi o'zgarishlar ham commit'ga tushaveradi. Kerak: git rm --cached .env (faylni diskda qoldirib kuzatuvdan chiqarish), keyin commit. Va tarixdagi kalit uchun — rotatsiya.

4. Sizib chiqqanda nima qilish

flowchart TD
  A[Sir sizdi] --> B["1. Bekor qilish / rotatsiya<br/>(daqiqalar ichida)"]
  B --> C["2. Ishlatilganmi?<br/>provayder loglari"]
  C --> D["3. Koddan olib tashlash<br/>to'g'ri joyga ko'chirish"]
  D --> E["4. Tarixni tozalash<br/>(ixtiyoriy)"]
  E --> F["5. Sabab va oldini olish<br/>skaner, hook"]

Diagrammadagi tartib muhim: rotatsiya birinchi, hatto kod hali tuzatilmagan bo'lsa ham. Har daqiqa hisobda.

Qadam Amalda
1. Bekor qilish Provayder panelida kalitni o'chirish, yangisini yaratish; serverga yangisini berish
2. Tekshirish To'lov tizimi, bulut yoki API'ning faollik logi: noma'lum IP, g'alati so'rovlar
3. Tuzatish Kod → env/sir ombori; .gitignore; testlar
4. Tozalash git filter-repo, jamoaga xabar
5. Oldini olish Secret scanning, pre-commit hook (har commit'dan oldin avtomatik ishlaydigan tekshiruv skripti), kod ko'rib chiqish

Uyalib yashirish — eng yomon reaksiya. Jamoada "sir sizdi" deyish oson bo'lishi kerak: tez aytilgan sizish — kichik hodisa, yashirilgani — katta.

5. Oldini olish: skanerlar

Sirlarni avtomatik qidiradigan vositalar:

Vosita Qayerda ishlaydi Holat
GitHub secret scanning + push protection GitHub serveri: ma'lum formatdagi kalitli push'ni rad etadi Ochiq repolarda bepul (GitHub hujjati)
gitleaks Lokal, pre-commit hook, CI Ochiq kodli
trufflehog Lokal, CI; topilgan kalitni provayderda tekshiradi Ochiq kodli

Halol: kanon mashinasida gitleaks yo'q — sinalmagan; trufflehog va push protection ham sinalmagan. Bu yerda ularning g'oyasini o'z skanerimiz bilan ko'ramiz.

5.1 Skaner qanday ishlaydi

Ko'p provayderlar kalitlariga prefiks qo'yadi — aynan skanerlar topishi uchun: GitHub tokeni ghp_, Stripe sk_live_, AWS AKIA. Qolganini — "qiymati uzun va tasodifiy" belgisi bilan topishadi:

js
const QOIDALAR = [
  ["GitHub token", /\bghp_[A-Za-z0-9]{36}\b/],
  ["Stripe live kalit", /\bsk_live_[A-Za-z0-9]{16,}\b/],
  ["AWS kalit ID", /\bAKIA[0-9A-Z]{16}\b/],
  ["Parolli URL", /\b\w+:\/\/[^\s:/]+:[^\s@/]+@/],
];

function skanerla(matn) {
  const topildi = [];
  matn.split("\n").forEach((qator, i) => {
    for (const [nom, re] of QOIDALAR) {
      if (re.test(qator)) topildi.push(`${i + 1}-qator: ${nom}`);
    }
  });
  return topildi;
}

const fayl = [
  'const port = 3000;',
  'const url = "postgres://ali:Maxfiy123@db.example.com/app";',
  `const k = "sk_live_${"x".repeat(24)}";`,
  "// ghp_ — bu shunchaki izoh",
].join("\n");
console.log(skanerla(fayl));

Konsolda:

text
[ '2-qator: Parolli URL', '3-qator: Stripe live kalit' ]

To'rtinchi qator — faqat prefiks, kalit uzunligi yo'q: skaner jim. Kalitni "x".repeat(24) bilan yasadik — dars matnining o'zi ham skanerlarni "bezovta qilmasin". Haqiqiy vositalarda yuzlab qoidalar va entropiya (tasodiflik) o'lchovi bor.

6. Sirni qayerda saqlash

6.1 Darajalar

Usul Qachon Kamchilik
.env (lokal) Dasturchi kompyuteri Diskda ochiq; jamoaga tarqatish — chat orqali (yomon)
Server env (systemd, Docker environment) Bitta server, kichik jamoa docker inspect va jarayon muhitida ko'rinadi
Fayl (/run/secrets/…, *_FILE) Docker/Compose secrets, Kubernetes Fayl huquqlari to'g'ri bo'lishi kerak
SOPS + age Shifrlangan fayl git'da Kalit boshqaruvi o'zingizda
Secret manager (Vault, Doppler, Infisical, AWS/GCP) Ko'p server, ko'p odam Yana bir xizmat; narx

Kanon bularning hech birini sinamagan (Docker — 33-qism, CI secrets — 34-qism). Quyida — har birining g'oyasi.

6.2 *_FILE konvensiyasi

Docker va Kubernetes sirni fayl sifatida beradi (/run/secrets/db_parol) — u docker inspect va jarayon muhitida ko'rinmaydi. Ko'p rasmiy image'lar (masalan, postgres) POSTGRES_PASSWORD_FILE kabi o'zgaruvchini qo'llaydi: "qiymat emas, faylning yo'li". O'z ilovangizda ham shunday qilish mumkin:

js
import { readFileSync, writeFileSync, mkdtempSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";

function sirOqi(env, nom) {
  const yol = env[`${nom}_FILE`];
  if (yol !== undefined) return readFileSync(yol, "utf8").trim();
  return env[nom];
}

const papka = mkdtempSync(join(tmpdir(), "sir-"));
const fayl = join(papka, "db_parol");
writeFileSync(fayl, "namuna-parol-emas\n", { mode: 0o600 });

console.log(sirOqi({ DB_PAROL_FILE: fayl }, "DB_PAROL"));
console.log(sirOqi({ DB_PAROL: "env-dan" }, "DB_PAROL"));
console.log(sirOqi({}, "DB_PAROL"));

Konsolda:

text
namuna-parol-emas
env-dan
undefined

trim() — fayl oxiridagi yangi qatorni olib tashlaydi (aks holda parol "…\n" bo'lib, baza "parol noto'g'ri" deydi — klassik tuzoq). mode: 0o600 — faqat egasi o'qiy oladi (Linux'da; Windows bu bitlarni deyarli e'tiborsiz qoldiradi). Kanondagi FaylOmbori ham ma'lumot faylini 0o600 bilan yozadi.

6.3 Secret manager'lar

  • HashiCorp Vault — o'z serveringizda; sirlarni so'rov bo'yicha beradi, hatto dinamik sir yaratadi (har ishga tushganda yangi, qisqa muddatli baza paroli).
  • Doppler, Infisical — bulut (Infisical — ochiq kodli, o'zingiz ham joylashtirasiz): veb panel, CLI doppler run -- npm start sirlarni jarayon muhitiga quyadi.
  • AWS Secrets Manager, GCP Secret Manager — bulut provayderining o'zi; avtomatik rotatsiya.

Umumiy g'oya: sirning bitta haqiqiy manbai, kim qachon o'qiganining logi, va rotatsiya — bir joyda. Ilova kodi uchun farqi kam: oxir-oqibat qiymat process.env yoki faylga keladi — configYukla o'zgarmaydi.

6.4 SOPS + age

SOPS — YAML/JSON/env faylning qiymatlarini shifrlaydi, kalitlarni ochiq qoldiradi: git diff'da "qaysi sir o'zgardi" ko'rinadi, nima ga o'zgargani — yo'q. age — zamonaviy, oddiy shifrlash vositasi (kalit — bitta qator). Shifrlangan fayl git'da yashaydi, ochish kaliti — faqat serverda va mas'ul odamlarda. Kichik jamoa uchun secret manager'siz yaxshi yo'l. Kamchiligi — boshqa vositalar darsidagi .env.vault bilan bir xil: kalit sizsa, tarixdagi hamma versiya ochiladi.

7. Rotatsiya — kodda qanday ko'rinadi

Kalitni almashtirish bir lahzada bo'lmaydi: 3 ta server bor, birinchisiga yangi kalit berildi, qolgan ikkitasi hali eskisida. Agar kalit imzo uchun bo'lsa (webhook, cookie), server bir muddat ikkala kalitni qabul qilishi kerak. crypto darsidagi HMAC bilan:

js
const kodla = new TextEncoder();
const hex = (b) =>
  [...new Uint8Array(b)].map((x) => x.toString(16).padStart(2, "0"))
    .join("");

async function imzola(kalit, xabar) {
  const k = await crypto.subtle.importKey("raw", kodla.encode(kalit),
    { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
  const b = kodla.encode(xabar);
  const imzo = await crypto.subtle.sign("HMAC", k, b);
  return hex(imzo);
}

/** kalitlar[0] — joriy, qolganlari — hali qabul qilinadigan */
async function imzoKimniki(kalitlar, xabar, imzo) {
  for (const [i, kalit] of kalitlar.entries()) {
    if ((await imzola(kalit, xabar)) === imzo) return i;
  }
  return -1;
}

const xabar = '{"hodisa":"vazifa.bajarildi","id":7}';
const eski = await imzola("eski-namuna-kalit", xabar);
const yangi = await imzola("yangi-namuna-kalit", xabar);
const kalitlar = ["yangi-namuna-kalit", "eski-namuna-kalit"];
console.log(await imzoKimniki(kalitlar, xabar, yangi)); // 0
console.log(await imzoKimniki(kalitlar, xabar, eski)); // 1
const faqatYangi = ["yangi-namuna-kalit"];
console.log(await imzoKimniki(faqatYangi, xabar, eski)); // -1

Konsolda:

text
0
1
-1

Rotatsiya bosqichlari: (1) hamma serverga [yangi, eski]; (2) imzolash faqat yangisi bilan; (3) eski bilan kelayotgan so'rovlar tugagach — [yangi]. Natija 1 (eski kalit) kelsa — logga yozing: kim hali yangilanmagani ko'rinadi.

Haqiqiy kodda === o'rniga vaqtga chidamli solishtirish kerak (crypto.timingSafeEqual — Node, crypto darsi), aks holda hujumchi javob vaqtidan imzoni bayt-bayt taxmin qilishi mumkin.

Tekshirib ko'ring: Nega rotatsiya uchun KALIT ni bitta qiymat emas, ro'yxat (KALITLAR=yangi,eski) qilish kerak?

Javob

Bitta qiymat bilan kalitni almashtirish — "hamma joyda bir vaqtda" degani. Bunday lahza yo'q: serverlar ketma-ket yangilanadi, mijozlar eski kalit bilan imzolagan so'rovlarni hali yuborayotgan bo'ladi. Ro'yxat bilan o'tish davri bor — hech kim uzilmaydi.

8. Hujumchi nigohi

  • Ochiq repo skaneri. Hujumchi GitHub'dagi yangi commit'larni avtomatik skanerlaydi va sk_live_, AKIA, parolli URL'larni qidiradi. Himoya: sir hech qachon commit'ga tushmasin (.gitignore, push protection, pre-commit skaner); tushsa — darhol rotatsiya.
  • git log -S. "Olib tashlangan" kalit tarixdan bir buyruq bilan chiqadi. Himoya: rotatsiya, keyin tarix tozalash.
  • Xato xabari va log. Buzuq so'rov bilan stack yoki config qiymatini chiqartirishga urinish. Himoya: kanondagi uch test — 500 yashirin, config xatosi qiymatsiz, log redact.
  • Frontend build. VITE_STRIPE_SECRET — build'da JS faylga yoziladi, "Sahifa kodini ko'rish" bilan ochiladi. Himoya: frontend'da faqat ochiq kalit (publishable), sir — faqat server env'ida.
  • Ortiqcha huquq. Sizgan kalitning zarari uning huquqlariga teng. Himoya: har xizmatga alohida, minimal huquqli kalit (faqat o'qish, faqat bitta bucket — bulutdagi bitta fayl ombori).

9. API qadami: sirlar gigiyenasi (holat 40, 5-qism)

Hali commit qilmang — commit keyingi darsda. vazifalar-api da yangi kod yo'q — tekshiruv ro'yxati:

bash
git check-ignore -v .env
git log --all -p -S "sk_" --oneline
git grep -n -E "(parol|token|secret|_KEY)\s*=" -- ':!*.example'
  1. .env e'tiborsiz qolyaptimi (check-ignore chiqishi bor)?
  2. Tarixda kalitga o'xshash narsa bormi (-S bo'sh bo'lishi kerak)?
  3. Kodda sir qiymati bormi (git grep faqat nomlarni ko'rsatishi kerak, qiymatlarni emas)?
  4. .env.example da faqat namuna qiymatlar.
  5. test/config.test.ts va test/xato.test.ts dagi "qiymat yo'q" tekshiruvlari o'tadi.

Kanon .gitignore (holat 40):

text
node_modules/
dist/
.env
*.log
coverage/
data/

data/ — SAQLASH=fayl dagi vazifalar fayli; unda foydalanuvchi ma'lumoti bor, u ham git'ga tushmasligi kerak. *.log — loglarda tasodifan sir bo'lishi mumkin.

10. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
Kalit "o'chirildi", lekin ishlatildi Faqat yangi commit, rotatsiya yo'q Avval rotatsiya
.env git'da, garchi .gitignore da bo'lsa ham Avval commit qilingan git rm --cached .env + rotatsiya
Baza "parol noto'g'ri", parol to'g'ri Fayldagi \n .trim()
CI logida sir echo, set -x, xato xabarida qiymat CI maskalash, qiymatsiz xabarlar
Kalit almashtirildi — yarim serverlar ishlamayapti Bir lahzada almashtirish Ikki kalitli o'tish davri
Frontend'da maxfiy kalit VITE_/NEXT_PUBLIC_ prefiksi Faqat serverda
Sir chatda yuborildi "Tezroq" Secret manager yoki bir martalik havola

11. Mashqlar

Yechimlar kurs/mashqlar/25/39-sirlar/ da.

1-mashq (oson): to'g'ri tartib

Stripe live kaliti ochiq repo'ga push qilindi. Qadamlarni tartiblang: (a) git filter-repo; (b) Stripe panelida kalitni bekor qilish; (c) kodni env'ga o'tkazish; (d) Stripe logida noma'lum to'lovlarni tekshirish.

Tartib: [:b], [:d], [:c], [:a]

Yechim

b → d → c → a. Bekor qilish birinchi — u zararni to'xtatadi. Keyin zarar bo'lganmi — tekshirish. Keyin kodni tuzatish (yangi kalit endi env'da). Tarixni tozalash oxirida va ixtiyoriy: kalit allaqachon yaroqsiz.

2-mashq (o'rta): maskalash

maskala(qiymat) yozing: 8 belgidan qisqa bo'lsa — butunlay ***; aks holda birinchi 4 belgi + … + uzunlik (sk_l…(32)). Keyin configniLogla(config, sirlar) — obyektni nusxalab, sirlar ro'yxatidagi kalitlarni maskalasin.

Yechim
js
function maskala(qiymat) {
  const s = String(qiymat);
  if (s.length < 8) return "***";
  return `${s.slice(0, 4)}…(${s.length})`;
}

function configniLogla(config, sirlar) {
  const nusxa = { ...config };
  for (const k of sirlar) {
    if (nusxa[k] !== undefined) nusxa[k] = maskala(nusxa[k]);
  }
  return nusxa;
}

const config = {
  PORT: 3000,
  WEBHOOK_URL: "https://example.com/hook?token=abc123def456",
  DB_PAROL: "qisqa",
};
console.log(configniLogla(config, ["WEBHOOK_URL", "DB_PAROL"]));

Konsolda:

text
{ PORT: 3000, WEBHOOK_URL: 'http…(43)', DB_PAROL: '***' }

Uzunlikni ko'rsatish foydali: "parol bo'sh keldimi yoki to'liqmi?" degan savolga qiymatni ochmasdan javob beradi. Qisqa qiymatda boshini ham ko'rsatmaymiz — 4 belgi uning yarmi bo'lardi.

3-mashq (qiyin): .env ni tarixda qidirish

Commit'lar ro'yxati berilgan: [{ id, fayllar: { "yo'l": "matn" } }] (har commit — o'sha paytdagi to'liq holat). pickaxe(commitlar, matn) yozing: git log -S kabi — matn soni o'zgargan commit'larni qaytarsin (qo'shilgan yoki olib tashlangan).

Yechim
js
function sana(fayllar, matn) {
  let n = 0;
  for (const t of Object.values(fayllar)) {
    n += t.split(matn).length - 1;
  }
  return n;
}

function pickaxe(commitlar, matn) {
  const natija = [];
  let oldingi = 0;
  for (const c of commitlar) {
    const hozir = sana(c.fayllar, matn);
    if (hozir !== oldingi) {
      natija.push(`${c.id} ${hozir > oldingi ? "+" : "-"}`);
    }
    oldingi = hozir;
  }
  return natija;
}

const KALIT = "sk_test_SOXTA_123";
const commitlar = [
  { id: "a1", fayllar: { "app.js": "port = 3000" } },
  { id: "b2", fayllar: { "app.js": `kalit = "${KALIT}"` } },
  { id: "c3", fayllar: { "app.js": `kalit = "${KALIT}"; x = 1` } },
  { id: "d4", fayllar: { "app.js": "kalit = process.env.K" } },
];
console.log(pickaxe(commitlar, KALIT));

Konsolda:

text
[ 'b2 +', 'd4 -' ]

c3 da kalit bor, lekin soni o'zgarmagan — -S uni ko'rsatmaydi (haqiqiy git ham shunday). Kanon tajribasidagi ikki commit — aynan "+" va "−".

4-mashq: API qadami

«API qadami» bo'limidagi uch buyruqni o'z vazifalar-api repo'ngizda bajaring va besh banddan iborat ro'yxatni tekshiring. Qo'shimcha: configYukla ga WEBHOOK_URL xato bo'lganda qiymat chiqmasligini tekshiradigan test yozing. Commit qilmang.

Yechim

Test: assert.throws(() => configYukla({ WEBHOOK_URL: "token-bor-yaroqsiz" }), (x) => x instanceof ConfigXatosi && !x.message.includes("token-bor")). prettifyError faqat xato turini va → at WEBHOOK_URL ni yozadi — test o'tadi. git log -S "sk_" bo'sh bo'lishi kerak; agar biror narsa chiqsa — bu mashq emas, haqiqiy hodisa: «Sizib chiqqanda» bo'limidagi tartib bilan.

12. Real ishda

  • Jamoaga kelgan birinchi haftada so'raladigan savol: "sirlar qayerda?" Javob odatda: secret manager (Doppler/Vault/bulut) yoki CI secrets + server env.
  • Kompaniyalarda sizish hodisasi uchun yozma tartib (runbook) bo'ladi — yuqoridagi besh qadam uning asosi.
  • Intervyu savollari: "Kalitni commit qilib qo'ysangiz nima qilasiz?", ".env ni nega xavfsiz deb bo'lmaydi?", "Kalit rotatsiyasini uzilishsiz qanday qilasiz?"

Xulosa

  • Sir sizadigan joylar: git tarixi, log, xato javobi, frontend build, jarayon muhiti, chat.
  • Commit qilingan sir o'chirilgandan keyin ham tarixda (git log -S) — davosi rotatsiya, tozalash — ikkinchi.
  • Tartib: bekor qilish → ishlatilganmi → kodni tuzatish → tarix → oldini olish.
  • Saqlash darajalari: .env (lokal) → server env → fayl (*_FILE) → SOPS → secret manager.
  • Rotatsiya — ikki kalitli o'tish davri; skanerlar (push protection, gitleaks, trufflehog) — oldini olish.

Keyingi dars: Backend'da sana va vaqt — UTC'da saqlash, Toshkent kuni bo'yicha filtr va holat 40 ning commit'i.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Sirlarni boshqarish: .env, git tarixi, rotatsiya va secret manager'lar — IlmHamroh