Private Docs

Security Baseline — Target-State Checklist

สิ่งที่เราควรมี — baseline ความปลอดภัย backend (scoped 4 ตัวแทน) เทียบ API-GL-001 §7

อัปเดต: 2026-07-02

Security Baseline — “สิ่งที่เราควรมี” (Target-State Checklist)

เอกสารนี้คืออะไร: เช็กลิสต์ “security baseline ที่ API ของธนาคารควรมี” เรียงตาม 7 หมวดมาตรฐาน API-GL-001 (ธสน./EXIM) — ตอบคำถามว่า “เออ สิ่งที่เราควรมีมีอะไรบ้างนะ แล้วตอนนี้เรามีแล้วแค่ไหน” ไม่ใช่รายงานเจาะช่องโหว่รายตัว

ทำไมดู 4 ตัวแทน ไม่ scan ทั้ง platform: เราเลือก 4 component ตัวแทน 1 ตัวต่อ 1 ชั้น ของเส้นทาง request แทนการไล่สแกน ~13 service (เปลืองเวลา/ต้นทุน และซ้ำ) — 4 ตัวนี้ครอบคลุม “แบบแผน” ที่ service อื่นทำตาม ถ้าตัวแทนแต่ละชั้นมี baseline ครบ = ยกทั้ง platform ตามได้ (โดยเฉพาะ Backend_Package = จุดคานงัด)

เขียนสำหรับใคร: ทีมพัฒนา SuperApp ที่ยังไม่มีผู้เชี่ยวชาญ security — ใช้เป็นไกด์ว่า “อะไรควรมี อะไรควรเติม” และเอาไปตอบผู้ตรวจ/ธนาคารได้

วันที่: 2 กรกฎาคม 2026 · สถานะ: Draft · ขอบเขต: target-state baseline (scoped)

เอกสารพี่น้อง: สำหรับ gap register เต็มทั้ง platform (evidence file

ทุก service, ผ่าน fact-check 3 รอบ) ดู SECURITY_MASTER_PLAN_DEFENSE_ROADMAP.md — เอกสารนี้คือฉบับย่อ/มุม “ควรมีอะไร”


§0 — 4 ตัวแทน = 1 ตัวต่อ 1 ชั้นของเส้นทาง request

เราไม่ไล่ทุก service แต่หยิบตัวแทน “ชั้นละ 1” เพื่อเห็นภาพทั้งเส้นทางในหน้าเดียว:

  ผู้ใช้

 [ด่านนอก]     ①  APIM / edge (Cloudflare + App GW + APIM)   ← perimeter: WAF, rate limit, session façade

 [identity]    ②  Sentinel Gateway                           ← OIDC, session store, resolve-session

 [shared lib]  ③  Backend_Package                            ← จุดคานงัด: helper กลางที่ทุก service ใช้ร่วม

 [1 service]   ④  User Service                               ← ตัวอย่าง backend service ที่ "ทำถูก" ที่สุด

ทำไม 4 ตัวนี้:

  • ① APIM/edge — ด่านแรกที่ traffic ทุกอย่างผ่าน คุมได้ที่เดียวกระทบทั้งหมด
  • ② Sentinel — เจ้าของ authentication/session ทั้งระบบ
  • ③ Backend_Package — library กลาง ถ้า baseline อยู่ที่นี่ = service อื่น “เรียกบรรทัดเดียว” ก็ได้ของถูก (pit of success)
  • ④ User Service — service ตัวอย่างที่ปิด dev-bypass แล้ว + wire API-key filter ครบ = ใช้เป็น “แม่แบบที่ควรเป็น” ของ service อื่น

สัญลักษณ์สถานะ: ✅ มีครบ · 🟡 มีบางส่วน/ต้องเติม · ❌ ยังไม่มี · — ไม่เกี่ยวกับชั้นนี้

หมายเหตุความแม่นยำ: สถานะที่ ยืนยันตรงจากโค้ดรอบนี้ = ④ User Service (dev-bypass ปิด if(false), Filters.Add<ApiKeyAuthFilter> register แล้ว, MapHealthChecks, ไม่มี AddRateLimiter/FallbackPolicy, ShowPII=true non-prod) และ ③ Package (มี AES/SecurityHeaders/CORS/ApiKeyFilter/RequestSizeLimit จริง; ไม่มี FallbackPolicy/authorization/partitioned-rate-limit helper — เจอแค่ใน README = ยังเป็น design). ส่วนเซลล์ ④ ที่เป็น feature ของ Package (encryption/headers/CORS/audit) = “คาดว่าใช้ผ่าน Package” ตาม convention ทีม — ควร confirm การ wire ต่อ service ก่อนใช้ตอบผู้ตรวจ · ที่มา evidence เต็ม: ROADMAP


§1 — Target-State Checklist ตาม 7 หมวด API-GL-001

หมวด 1 — Authentication (การยืนยันตัวตน)

สิ่งที่ควรมี (baseline): OIDC/OAuth2 มาตรฐาน · token short-lived เก็บ server-side · JWT validation เต็ม (issuer/audience/lifetime/signing key) ทุก service · ไม่มี dev-bypass ที่ active บน cluster จริง · session สั้นเท่าที่จำเป็น

baseline ที่ควรมี① APIM② Sentinel③ Package④ User Svc
OIDC (PKCE S256 + state), token เก็บ server-side (Redis)🟡 façade cookie→JWT
JWT validation เต็มรูป (issuer/aud/lifetime/key + JWKS)🟡 ไม่ validate ก่อน passthrough🟡 มี pattern แต่ไม่มี helper กลาง
ไม่มี dev-bypass ที่ active บน cluster❌ ไม่มี guard กลาง✅ ปิดแล้ว (if(false))
session TTL สั้น🟡 default 720h (RememberMe)

จุดที่ควรเติม: ① เพิ่ม JWT pre-validation ที่ APIM (reject malformed/expired ที่ขอบ) · ③ ทำ helper กลางใน Package ที่รวม JWT validation + ผูก dev-bypass กับ flag ที่ไม่มีวันเป็น true บน cluster → service อื่นเลิกเขียน if(isDev) เอง · ④ User Service = แม่แบบที่ถูกแล้ว ใช้ลอกไป service อื่น

หมวด 2 — Authorization (การตรวจสอบสิทธิ์)

สิ่งที่ควรมี: default-deny (FallbackPolicy = RequireAuthenticatedUser) · [AllowAnonymous] เฉพาะที่จำเป็น + มีเหตุผล · แยก read/admin · API-key filter ที่ enforce จริง · InternalOnly สำหรับ internal endpoint

baseline ที่ควรมี① APIM② Sentinel③ Package④ User Svc
default-deny (FallbackPolicy)❌ ไม่มี helper (มีแค่ design ใน README)❌ ยังเป็น default-allow
API-key filter ที่ enforce จริง (ต้อง Filters.Add)🟡 มี ApiKeyAuthFilter (opt-in)✅ register แล้ว (Program.cs:119)
internal endpoint กันด้วย InternalOnly/CIDR🟡 InternalOnly default Enabled=false — ต้อง confirm IaC
subscription-key enforcement ที่ขอบ🟡 ควรบังคับ

จุดที่ควรเติม: ③ ทำ AddSuperAppAuthorization (ตั้ง FallbackPolicy + register API-key filter อัตโนมัติ + fail-fast ถ้า ApiKeys ว่าง) — ลำดับสำคัญ: ต้อง inventory + decorate endpoint anonymous ให้ครบก่อนเปิด FallbackPolicy มิฉะนั้น health probe 401 → pod restart (ดูลำดับปลอดภัยใน ROADMAP §4.2)

หมวด 3 — Data Confidentiality & Integrity

สิ่งที่ควรมี: เข้ารหัส field sensitive (AES-256) · ไม่มี secret ใน source/config (ใช้ Key Vault) · message-level integrity (HMAC/signature) สำหรับ external write · secret ไม่หลุดทาง URL/log

baseline ที่ควรมี① APIM② Sentinel③ Package④ User Svc
field encryption (AES-256, [Encrypt])AesEncryptionService + MediatR behavior✅ ใช้ของ Package
ไม่มี secret hardcode ใน source/config✅ (ReportToken ใน KV)
message-level integrity (HMAC signature)✅ มี service🟡 เปิดใช้ตาม service
secret ไม่หลุดทาง URL/log🟡

จุดที่ควรเติม: helper encryption/signature พร้อมแล้วที่ Package — งานคือ บังคับใช้ให้ทั่ว (external write ควรมี signature) + audit ว่าไม่มี secret hardcode หลงเหลือ (ดู ROADMAP #1: Notification + ThirdParty prod config)

หมวด 4 — Secure Communication

สิ่งที่ควรมี: TLS 1.2+ ทุก hop · terminate ที่ขอบ · strong cipher suite เท่านั้น · certificate ถูกต้อง/ไม่หมดอายุ

baseline ที่ควรมี① APIM② Sentinel③ Package④ User Svc
TLS ทุก hop✅ App GW/APIM terminate✅ ingress internal
strong cipher (ปิดตัวอ่อน)🟡 ควร audit ที่ App GW/APIM
WAF (OWASP ruleset) ที่ขอบ✅ Cloudflare + App GW

จุดที่ควรเติม: ① audit cipher suite ที่ App GW/APIM ว่าปิดตัวอ่อนครบ (ส่วน message-level integrity ดูหมวด 3)

หมวด 5 — Secure Coding & Configuration

สิ่งที่ควรมี: security headers (nosniff/X-Frame/CSP) · CORS allowlist บังคับ · error message ไม่เปิดเผยเกินจำเป็น · ปิด PII ใน log/error บน non-local · Swagger ไม่เปิด public · input validation

baseline ที่ควรมี① APIM② Sentinel③ Package④ User Svc
security headers ครบ (CSP nonce, COOP/COEP, strip Server)AdvancedSecurityHeadersMiddleware✅ ใช้ของ Package
CORS allowlist (throw ถ้าว่าง)AddStrictCors
RFC 9457 exception handler (ไม่รั่ว stack)
ShowPII=false บน non-localShowPII=true non-prod (มาจาก template)
Swagger ไม่เข้าถึงจากภายนอกบน SIT/UAT🟡 ต้อง confirm🟡 ต้อง confirm

จุดที่ควรเติม: ③ template/Package ควร default ShowPII เปิดเฉพาะ local (ตอนนี้ inherit เป็น non-prod ทั้งหมด → กระทบทุก service รวม ④) · confirm การเข้าถึง Swagger บน SIT/UAT

หมวด 6 — Audit Log & Monitoring

สิ่งที่ควรมี: audit log ระบุตัวบุคคล (ใคร/ทำอะไร/เมื่อไหร่) · retention ≥ 90 วัน + tamper-proof · correlation ID · security alerting (brute-force/anomaly) · ไม่มี PII ใน log

baseline ที่ควรมี① APIM② Sentinel③ Package④ User Svc
structured logging + [Audit] + correlation ID✅ Serilog + MediatR [Audit] + correlation middleware✅ ใช้ของ Package
retention ≥ 90 วัน + tamper-proof (WORM)🟡 ต้องกำหนดนโยบาย
security alerting (brute-force/anomaly)🟡 ยังไม่เป็นระบบ
ไม่มี PII ใน log sink🟡 ต้อง audit (คู่กับ ShowPII หมวด 5)🟡

จุดที่ควรเติม: เครื่องมือ (Serilog/audit/correlation) พร้อมที่ Package แล้ว — งานเชิงนโยบาย: retention/tamper-proof + alert rule + ยืนยัน log ไม่มี PII

หมวด 7 — Resource Sufficiency (Rate Limit / DDoS / Payload)

สิ่งที่ควรมี: rate limit per-client (partitioned) ทุก service · DDoS ที่ขอบ (WAF) · จำกัดขนาด request · circuit breaker · exclude health probe จาก limiter

baseline ที่ควรมี① APIM② Sentinel③ Package④ User Svc
DDoS/WAF ที่ขอบ✅ Cloudflare + App GW
rate limit ที่ขอบ✅ Bearer 200/60s, Anon 30/60s
partitioned (per-client) rate limiter ระดับ service❌ ไม่มี helper (penalty middleware ≠ primary limiter + ยังไม่มี enforcement จริง)❌ ไม่มี AddRateLimiter
จำกัดขนาด requestRequestSizeLimitMiddleware
circuit breaker✅ Polly (session read)

จุดที่ควรเติม: ③ ทำ partitioned rate-limit helper ใน Package (partition key = user sub → API key → forwarded IP, exclude /health) → wire ทุก service · อย่า ใช้ RateLimitPenaltyMiddleware เดี่ยวๆ (ยังไม่มี enforcement) หรือลอก pattern non-partitioned (self-DoS) — ดูรายละเอียด ROADMAP #5


§2 — สรุป: 5 “สิ่งที่ควรมีแต่ยังขาด” (เรียงตาม leverage)

ทั้งหมดนี้แก้ที่ Backend_Package (③) เป็นหลัก แล้ว service อื่น inherit — คุ้มที่สุด:

  1. AddSuperAppAuthorization helper — ตั้ง FallbackPolicy (default-deny) + register API-key filter อัตโนมัติ (หมวด 2)
  2. dev-bypass guard กลาง — ผูก bypass กับ flag ที่ไม่มีวัน true บน cluster → เลิก if(isDev) รายตัว (หมวด 1)
  3. partitioned rate-limit helper — per-client, exclude /health (หมวด 7)
  4. ShowPII default = local เท่านั้น ใน template/Package (หมวด 5)
  5. บังคับ message-level integrity (signature) สำหรับ external write — ของมีแล้ว แค่เปิดใช้ (หมวด 3)

หลักการ: ทำที่ library กลาง + template = “pit of success” (ทางที่ถูกเป็นทางที่ง่ายที่สุด) แล้วมี CI gate กันถอยหลัง — ทีมไม่ต้องจำกฎเยอะ

ลำดับที่ปลอดภัย (สำคัญมาก): ก่อนเปิด FallbackPolicy ต้อง inventory + decorate endpoint ที่ต้อง anonymous จริง (health probe, OIDC callback, OTP, API-key endpoint, SignalR hub) ให้ครบก่อน มิฉะนั้น pod restart ทั้ง cluster — ดูลำดับ 5 step ใน ROADMAP §4.2


§3 — อ้างอิง

  • API-GL-001 แนวปฏิบัติการใช้ API V3.0 (ธสน./EXIM) — 7 หมวด API Security Standard
  • SECURITY_MASTER_PLAN_DEFENSE_ROADMAP.md — gap register เต็มทั้ง platform (evidence file
    ทุก service, ผ่าน fact-check 3 รอบ) + roadmap 4 phase + ลำดับปลอดภัยการเปิด FallbackPolicy
  • OWASP API Security Top 10, ASVS (อ้างอิงเสริม)

เอกสารนี้เป็นฉบับ scoped (4 ตัวแทน) เน้น “สิ่งที่ควรมี” — สถานะปัจจุบันอ้างจากโค้ดที่ verify แล้วในงานรอบก่อน; สำหรับหลักฐานรายบรรทัดต่อ service ดู ROADMAP