API Key 101 — บัตรพนักงานของ server
อธิบายแบบง่ายที่สุด: API Key คืออะไร ตอบคำถามอะไร (ใครโทรมา) ต่างจาก JWT/HMAC/ลายเซ็นยังไง ทำไมใช้ได้เฉพาะ server-to-server และ best practice ที่ต้องทำเมื่อใช้
อัปเดต: 2026-08-06
API Key 101 — บัตรพนักงานของ server
คู่กับ Subscription Key (APIM) 101 — สองตัวนี้หน้าตาคล้ายกัน (string ลับแนบไปกับ request) แต่ตรวจคนละที่ ตอบคนละคำถาม · ทั้งคู่เป็นเครื่องมือขา server-to-server เท่านั้น (ภาพระบบข้อ 6 — มติ 18) ห้ามโผล่ขา browser (เหตุผลอยู่ท้ายเล่มนี้)
TL;DR — อ่าน 30 วิ
- API Key = string ลับที่ caller แนบมากับ request (
X-Api-Key) เพื่อบอกว่า “ฉันคือ service/ระบบตัวนี้” — เหมือนบัตรพนักงาน: แตะประตูแล้วรู้ว่าใครเข้า แต่ไม่ได้พิสูจน์อะไรมากกว่านั้น - ตอบคำถามเดียว: “ใครโทรมา (ระดับ system) และอนุญาตไหม” — ไม่ใช่ตัวตนผู้ใช้ (นั่นคือ JWT), ไม่กันแก้ข้อมูล (นั่นคือ HMAC/ลายเซ็น), ไม่กันอ่าน (นั่นคือ encryption)
- ใช้ได้เฉพาะ server → server เพราะมันคือ shared secret — ฝั่งที่ถือ key ต้องเก็บเป็นความลับได้จริง (Key Vault) ซึ่ง browser ทำไม่ได้
- ในระบบเรา:
ApiKeyAuthFilterในBackend_Package+ secret อยู่ Key Vault — ของมีครบแล้ว ไม่ต้องสร้างใหม่
1. ทำงานยังไง — เรียบง่ายที่สุดในบรรดาเครื่องมือ auth ทั้งหมด
sequenceDiagram
autonumber
participant A as Service A (caller)
participant KV as Key Vault
participant B as Service B (มี ApiKeyAuthFilter)
A->>KV: โหลด key ตอน start (ไม่ hardcode)
A->>B: request + header X-Api-Key: <key>
B->>B: เทียบกับ key ที่ตัวเองถือ (จาก KV เช่นกัน)
alt ตรง
B-->>A: 200 — รู้แล้วว่า caller คือใคร ปล่อยเข้า
else ไม่ตรง / ไม่ส่งมา
B-->>A: 401 — ไม่รู้จัก ปัดตก
end
ไม่มี crypto ไม่มีการคำนวณ — แค่ “จำรหัสตรงกันไหม” ความง่ายนี้คือทั้งจุดแข็ง (เร็ว, ไม่มีอะไรพัง) และจุดอ่อน (ใครเห็น key = ปลอมเป็น caller นั้นได้เต็มตัว) จึงต้องคุมที่ “ใครเห็น key ได้บ้าง” อย่างเดียวเลย
ตัวอย่างจริงในระบบ: RedisUserInfoMiddleware (lib กลาง) เวลา cache miss จะ HTTP fallback ไปถาม UserService — แนบ X-Api-Key เพื่อบอกว่า “ฉันเป็น service ภายในด้วยกัน” ก่อนเข้า endpoint ภายใน
2. API Key ตอบคำถามไหน — และไม่ตอบคำถามไหน
| คำถาม | API Key ตอบไหม | ตัวที่ตอบจริง |
|---|---|---|
| ใครโทรมา (ระดับ system: “นี่คือ NotificationService”) | ✅ | — |
| ใครโทรมา (ระดับ ผู้ใช้: “นี่คือคุณสมชาย”) | ❌ | JWT (ชั้น 1) |
| request ถูกแก้กลางทางไหม | ❌ | HMAC (server↔server) / body signature (browser) |
| คนกลางอ่านเนื้อหาได้ไหม | ❌ | TLS + field encryption |
| ยิงซ้ำ (replay) ได้ไหม | ❌ — key เดิมใช้ซ้ำได้เสมอโดยนิยาม | timestamp + nonce |
จุดที่คนสับสนบ่อย: เห็น request มี X-Api-Key แล้วคิดว่า “ปลอดภัยแล้ว” — จริงๆ มันแค่บอกว่าประตูหน้ารู้ว่าใครเข้ามา เนื้อ request ยังปลอม/แก้/อ่านได้หมดถ้าไม่มีชั้นอื่นประกบ ดังนั้นขา server-to-server ของเราถึงมี 3 ตัวทำงานร่วมกัน: API Key (ใครโทรมา) + HMAC (ของไม่ถูกแก้) + AES field encryption (คนกลางอ่านไม่ได้)
3. ทำไมใช้กับ browser ไม่ได้ — เหตุผลเดียว จบทุกข้อ
ค่าใดก็ตามที่ browser ต้องส่ง มันต้องอยู่ใน bundle/config ที่ browser โหลดได้ = เปิด DevTools เห็น = กลายเป็นค่า public โดยนิยาม:
- attacker copy key ไปแนบเหมือน app จริง → การป้องกันเป็นศูนย์เป๊ะ (ไม่ใช่ลดลง — ศูนย์)
- แต่ภาระเพิ่มเต็มๆ: ต้อง rotate, ต้อง sync ทุก env, rotate ทีหน้าเว็บพังที
- นี่คือเหตุผลของมติ 7 (ตัด API Key จากขา browser) และมติ 18 (นำกลับเข้า architecture เฉพาะขา server) — ขา browser การพิสูจน์ “เครื่องจริง” ทำด้วย body signature (กุญแจคู่ non-extractable) ซึ่งไม่มี secret ให้ขโมย (Body Signature 101)
กติกาตายตัว: เห็น X-Api-Key ในโค้ด FE / ใน Network tab ของ browser เมื่อไหร่ = bug security ทันที ไม่มีข้อยกเว้น
4. Best practice เมื่อใช้ (ขา server)
| กติกา | เพราะ |
|---|---|
| key อยู่ Key Vault เท่านั้น — ไม่อยู่ใน appsettings, ไม่อยู่ใน source code, ไม่อยู่ใน pipeline variable แบบ plaintext | จุดรั่วอันดับหนึ่งของ API Key คือ commit ติดลง git |
| แยก key ต่อ caller — ไม่ใช้ key กลางตัวเดียวทั้งระบบ | เพิกถอน/rotate ราย caller ได้โดยไม่กระทบตัวอื่น + log บอกได้ว่าใครเป็นใคร |
| ห้าม log ค่า key — log แค่ “caller ไหน ผ่าน/ไม่ผ่าน” | log อ่านได้กว้างกว่า KV เสมอ |
| เทียบ key แบบ constant-time | กัน timing attack (lib ใน Backend_Package จัดการแล้ว) |
| rotate มีแผนตั้งแต่แรก — ช่วง overlap รับ 2 key พร้อมกัน | rotate แบบ big-bang = ทุก caller พังพร้อมกัน (ดูวิธี dual-key ของ APIM ในเล่มถัดไป) |
5. สรุปเทียบเครื่องมือทั้งตระกูล — ใครทำหน้าที่อะไร
| เครื่องมือ | ระบุตัว | ระดับ | ตรวจที่ | ใช้ขาไหน |
|---|---|---|---|---|
| API Key | caller (system) | หยาบ — ต่อ service | backend filter (ApiKeyAuthFilter) | server → server |
| Subscription Key | caller (subscription) | หยาบ — ต่อผู้สมัครใช้ API | APIM gateway (ก่อนถึง backend) | server/partner → APIM (เล่มถัดไป) |
| JWT | ผู้ใช้ (คน) | ละเอียด — ต่อ user + roles | backend (validate กับ Entra) | ทุกขาที่มี user |
| HMAC | integrity + caller โดยนัย | ต่อ request | backend | server → server |
| Body signature | เครื่องของผู้ใช้ + integrity | ต่อ request ต่อ user | backend filter (ใหม่ — POC) | browser → backend |