Thuta Learning
API Integration & Webhooks
BasicWeb Developmentintermediate

Secret Management

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Secret Management concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • Diagram ကို ဖတ်ပြီး request/response (သို့) event flow ဘယ်လိုစီးဆင်းသလဲ ခြေရာခံနိုင်ရန်
  • ကိုယ့် ကိုယ်ပိုင် API integration အတွက် ဘယ်လို အသုံးချသင့်သလဲ ရှင်းပြနိုင်ရန်

နားလည်ထားရမယ့် အချက်

API Tutorial က API key တစ်ခုကို request တစ်ခုပေါ် တပ်ဆင်ဖို့ သင်ပေးခဲ့ပါတယ်။ အဲဒီ key က ဘယ်မှာ တကယ် နေထိုင်သင့်လဲဆိုတာကို မပြောခဲ့ပါဘူး၊ ဒါက real-world security failure အများဆုံးတစ်ခုပါ။

`const apiKey = "sk_live_abc123"` ကို frontend (သို့) mobile app code ထဲမှာ တိုက်ရိုက် ရေးလိုက်ရင် key က user တစ်ယောက်စီရဲ့ device ပေါ် run နေတဲ့ JavaScript bundle (သို့) app binary ထဲ ပါသွားပါတယ်။ ဘယ်သူမဆို browser devtools ကို ဖွင့်ပြီး secret key ကို စက္ကန့်အနည်းငယ်အတွင်း ကူးယူနိုင်ပါတယ်။

Minification က Encryption မဟုတ်ပါဘူး

Code ကို minify လုပ်ထားလို့ ဖတ်ရခက်သွားပေမယ့် secret string တွေကတော့ bundle ထဲမှာ plain text အတိုင်း ဆက်ရှိနေပါတယ် — search လုပ်ရင် ရှာတွေ့နိုင်ပါတယ်။

မှန်ကန်တဲ့ architecture ကတော့ layer တစ်ခု ထပ်ထည့်ပါတယ် — browser က သင့်ကိုယ်ပိုင် backend server ကို ပြောဆိုပြီး၊ backend ကသာ real secret key ကို ကိုင်ဆောင်ကာ external API နဲ့ ပြောဆိုပါတယ်။ Backend ဟာ trusted boundary ဖြစ်လာပါတယ်။

Environment variable တွေက အဲဒီ secret ကို source file ထဲ hardcode မလုပ်ဘဲ backend ဆီ လက်ဆင့်ကမ်းပေးဖို့ standard နည်းလမ်းပါ။ `.env` file ကို `.gitignore` ထဲ ထည့်ထားရမှာပါ — Git ထဲ commit ဖြစ်သွားတဲ့ secret က line ဖျက်လိုက်ပါလည်း history ထဲမှာ အမြဲ ပြန်ရနိုင်နေဆဲပါ။

Secret
Access ရရှိစေတဲ့ API key, password, token စတဲ့ private value တစ်ခု — public ဖြစ်သွားရင် misuse ဖြစ်နိုင်တယ်။
Environment Variable
Codebase အပြင်ဘက်မှာ သိမ်းထားပြီး runtime မှာ process တစ်ခုဆီ ပေးအပ်တဲ့ configuration value — secret တွေကို hardcode မလုပ်ဘဲ ပေးဖို့ standard နည်းလမ်း။
text
SECRET KEY: GOOD PATH VS BAD PATH
---------------------------------
GOOD:
  Browser --> Your Backend --> [ Secret Key (env var) ] --> External API

BAD (do not do this):
  Browser --> [ Secret Key hardcoded in JS ] --> External API
          X-- anyone can read this in devtools --X

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

အောက်က scanner က ဂရုမစိုက်တတ်တဲ့ pattern အများအားဖြင့်တွေ့ရတဲ့ ပုံစံတစ်ခုကို ရှာဖွေပါတယ် — variable name ထဲမှာ "key", "secret", (သို့) "token" ပါတဲ့ declaration တစ်ခုကို string literal အနည်းဆုံး စာလုံး ၁၂ လုံးနဲ့ တိုက်ရိုက် assign လုပ်ထားခြင်းပါ။

Source snippet နှစ်ခုအပေါ် run ကြည့်ပါ။ Risky version က API key ကို `fetch` call တစ်ခုအပေါ်မှာ တိုက်ရိုက် hardcode ထားပြီး scanner က အဲဒီ line ကို အတိအကျ flag လုပ်ပေးပါတယ်။ Clean version ကတော့ key ကို `process.env.API_KEY` ကနေ ဖတ်ထားပြီး scanner က empty array ကို မှန်ကန်စွာ ပြန်ပေးပါတယ်။

ဒီလို tool တစ်ခုမျိုးဟာ real team တွေက pre-commit hook (သို့) CI pipeline ထဲ တပ်ဆင်လေ့ရှိတဲ့ check အတိအကျပါ — key တစ်ခု hardcode ဖြစ်နေတာကို shared Git history ဆီ မရောက်ခင် ဖမ်းယူနိုင်ပြီး၊ နောက်မှ ဖယ်ရှားရတာက ပထမကတည်းက commit မလုပ်ခြင်းထက် ပိုခက်ခဲပါတယ်။

Code Commit မလုပ်ခင်

အတူတူ စမ်းရေးကြည့်မယ်

javascript
function scanForHardcodedSecrets(sourceCode) {
  const pattern = /(const|let|var)\s+(\w*(?:key|secret|token)\w*)\s*=\s*["']([A-Za-z0-9_\-]{12,})["']/gi;
  const findings = [];
  let match;
  while ((match = pattern.exec(sourceCode)) !== null) {
    findings.push({ variable: match[2], flagged: true, snippet: match[0] });
  }
  return findings;
}

const risky = `
const apiKey = "sk_live_51H8x9aBcDeFgHiJkLmNoP";
const userName = "guest";
fetch("https://api.example.com/charge", { headers: { Authorization: apiKey } });
`;

const clean = `
const apiKey = process.env.API_KEY;
const userName = "guest";
fetch("https://api.example.com/charge", { headers: { Authorization: apiKey } });
`;

console.log("Risky file findings:", scanForHardcodedSecrets(risky));
console.log("Clean file findings:", scanForHardcodedSecrets(clean));
You should see
Risky file findings: [{ variable: 'apiKey', flagged: true, snippet: 'const apiKey = "sk_live_51H8x9aBcDeFgHiJkLmNoP"' }]
Clean file findings: []
(Clean version က key ကို process.env ကနေ ဖတ်ထားလို့ scanner က ဘာမှ မတွေ့ပါ)

၅ မိနစ် စမ်းကြည့်

`scanForHardcodedSecrets` ကို run ပြီး `const dbPassword = "SuperSecret2024!"` ပါတဲ့ snippet အသစ် တစ်ခု စမ်းသပ်ကြည့်ပါ။ ဘာကြောင့် flag ဖြစ်လဲ (သို့) မဖြစ်လဲ ရှင်းပြပါ။

သတိလေးတစ်ချက်

`.env` file ကို .gitignore ထဲ ထည့်ဖို့ မေ့ခြင်း — တစ်ခါ commit ဖြစ်သွားရင် history ထဲက ရှင်းရခက်တယ်

Secret ကို frontend build ထဲ inline environment variable (NEXT_PUBLIC_ စတာမျိုး) အဖြစ် သုံးမိခြင်း — bundle ထဲ ထည့်သွင်းသွားနိုင်တယ်

About secret scanning - GitHub DocsAPI Integration & Webhooks

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • `.env` file ကို .gitignore ထဲ ထည့်ဖို့ မေ့ခြင်း — တစ်ခါ commit ဖြစ်သွားရင် history ထဲက ရှင်းရခက်တယ်
  • Secret ကို frontend build ထဲ inline environment variable (NEXT_PUBLIC_ စတာမျိုး) အဖြစ် သုံးမိခြင်း — bundle ထဲ ထည့်သွင်းသွားနိုင်တယ်
  • API Tutorial (apiguide) ကို မလေ့လာရသေးရင် ဒီ course ကို စမလိုက်ခင် အရင် ပြီးအောင် လေ့လာထားသင့်ပါတယ် — ဒီ course က REST/HTTP/Auth အခြေခံတွေကို ထပ်မသင်ဘဲ webhook, testing, reliability, integration architecture တို့ကိုသာ ဆက်လက် တည်ဆောက်ပါတယ်။

လေ့ကျင့်ခန်း

`scanForHardcodedSecrets` ကို run ပြီး `const dbPassword = "SuperSecret2024!"` ပါတဲ့ snippet အသစ် တစ်ခု စမ်းသပ်ကြည့်ပါ။ ဘာကြောင့် flag ဖြစ်လဲ (သို့) မဖြစ်လဲ ရှင်းပြပါ။

You'll know it worked when: Risky file findings: [{ variable: 'apiKey', flagged: true, snippet: 'const apiKey = "sk_live_51H8x9aBcDeFgHiJkLmNoP"' }] Clean file findings: [] (Clean version က key ကို process.env ကနေ ဖတ်ထားလို့ scanner က ဘာမှ မတွေ့ပါ)

Secret Management | Thuta Learning