IMPL PLAN 01 — CI Pipeline Security Scanning
เพิ่ม 5 scanner เข้า CI (SAST/SCA/secrets/image/IaC) + regression gate กันช่องโหว่เดิมย้อนกลับ
อัปเดต: 2026-07-07
IMPL PLAN 01 — CI Pipeline Security Scanning
วันที่: 07/07/2026 · สถานะ: ⏳ รอ verify · Priority: 🟠 Phase 2 (หลังหมวด 0) อ้างอิง: DISCUSSION หมวด 1 · design เต็ม: SONARQUBE_AKS_CI_INTEGRATION_DESIGN.md (ยังไม่เผยแพร่) + PLAN_SECURITY_SCANNING_CI_INTEGRATION.md (ยังไม่เผยแพร่) (task-by-task พร้อมใช้)
สรุป
เพิ่ม 5 scanner เข้า CI (SonarQube SAST · Dependency-Track SCA · Gitleaks secrets · Trivy image · Checkov IaC) + regression gates กันช่องโหว่เดิมย้อนกลับ — pilot ที่ Backend_UserService + Frontend_HostAppSuperApp ก่อน rollout
สถานะปัจจุบัน: ci.yml = dotnet test → docker build → push — ไม่มี security scan ใดๆ
Sequence Diagram — Pipeline เป้าหมาย
sequenceDiagram
autonumber
participant Dev as Developer
participant ADO as Azure DevOps Pipeline
participant GL as Gitleaks
participant SQ as SonarQube (AKS ns:security)
participant DT as Dependency-Track (AKS)
participant TR as Trivy
participant CK as Checkov
participant ACR as Azure Container Registry
Dev->>ADO: git push / PR → trigger CI
ADO->>GL: Stage 0: scan commits หา secret
GL-->>ADO: ❌ พบ secret → fail ทันที (blocking ตั้งแต่วันแรก)
ADO->>ADO: Stage 1: dotnet test (เดิม)
ADO->>SQ: Stage 1.5: SAST analysis + coverage
SQ-->>ADO: Quality Gate (non-blocking → blocking ภายหลัง)
ADO->>ADO: Stage 2: docker build
ADO->>TR: Stage 2.5: scan image (CVE base+layers)
TR-->>ADO: ❌ Critical CVE → fail (หลัง grace period)
ADO->>DT: upload SBOM (CycloneDX จาก dotnet/npm)
DT-->>ADO: dependency vulnerability report (async — ไม่ block)
ADO->>CK: scan IaC manifests (เฉพาะ Backend_Iac pipeline)
ADO->>ACR: Stage 3: push image (เฉพาะเมื่อผ่าน gate)
Note over ADO,ACR: Regression gates (custom): grep bypass pattern,<br/>controller ไม่มี auth attribute → fail
Activity Diagram — Gate Policy ต่อ Phase
flowchart TD
A[เริ่มใช้ scanner] --> B{Phase A: 2-4 สัปดาห์แรก}
B -->|Gitleaks| C[Blocking ทันที<br/>secret ใหม่ = fail]
B -->|SonarQube/Trivy/DT/Checkov| D[Non-blocking<br/>report อย่างเดียว + ทีม triage baseline]
D --> E{ทีมเคลียร์ backlog<br/>Critical/High เดิมหมด?}
E -->|ใช่| F[Phase B: Blocking เฉพาะ<br/>New Critical/High]
E -->|ไม่| D
F --> G[Phase C: ขยับเกณฑ์<br/>ตาม maturity ทีม]
ขั้นตอน Implement
รายละเอียด task-by-task (checkbox ครบ) อยู่ที่ PLAN 01/07 (ยังไม่เผยแพร่) แล้ว — ตารางนี้คือ view สรุป + สิ่งที่เพิ่มจากรอบนั้น
Group A — Backend_Iac (shared infra + templates) — ทำก่อน
| # | ไฟล์ (สร้างใหม่ใน Backend_Iac) | เนื้อหา |
|---|---|---|
| A1 | src/yamls/security/namespace.yaml + service-account.yaml | namespace security + SA ผูก Workload Identity เดิม (มีสิทธิ์ KV GET แล้ว) |
| A2 | src/yamls/security/sonarqube/*.yaml | SonarQube Community: Deployment + Service + PVC + SecretProviderClass (DB password จาก KV) |
| A3 | src/yamls/security/dependency-track/*.yaml | Dependency-Track API server + frontend |
| A4 | argocd/security-app.yaml | ArgoCD Application ชี้ namespace security |
| A5 | pipelines/templates/security/gitleaks-scan.yml | step template — รัน gitleaks บน $(Build.SourcesDirectory) |
| A6 | pipelines/templates/security/sonar-scan.yml | begin/analyze/end + quality gate check |
| A7 | pipelines/templates/security/trivy-scan.yml | scan image ก่อน push, --severity CRITICAL,HIGH --exit-code 1 (param ปรับได้) |
| A8 | pipelines/templates/security/sbom-upload.yml | CycloneDX generate + curl upload ไป DT |
| A9 | pipelines/templates/security/regression-gates.yml | ใหม่ (ไม่อยู่ใน design เดิม) — ดูด้านล่าง |
Regression Gates (A9) — กันงานหมวด 0 ถอยหลัง
# pipelines/templates/security/regression-gates.yml (Backend_Iac)
steps:
- script: |
set -e
# Gate 1: ห้ามมี dev-bypass pattern กลับมา
if grep -rn "if (isDev)" --include="AuthenticationExtensions.cs" .; then
echo "##vso[task.logissue type=error]dev-bypass pattern พบใน AuthenticationExtensions"; exit 1; fi
if grep -rn "BypassAuthHandler" --include="*.cs" .; then
echo "##vso[task.logissue type=error]BypassAuthHandler ห้ามใช้"; exit 1; fi
# Gate 2: controller ทุกตัวต้องมี [Authorize] หรือ [AllowAnonymous] ชัดเจน
# (Roslyn analyzer ดีกว่า grep ระยะยาว — เริ่มด้วย script ก่อน)
for f in $(grep -rlL "\[Authorize\|\[AllowAnonymous" --include="*Controller.cs" src/*/Controllers 2>/dev/null); do
echo "##vso[task.logissue type=error]$f ไม่มี auth attribute"; FAIL=1; done
[ -z "$FAIL" ] || exit 1
displayName: "🔒 Security Regression Gates"
⚠️ Gate 2 ผ่านแม้ controller ติด
[AllowAnonymous]ตั้งใจบน write endpoint — งาน audit รายตัวอยู่ IMPL_PLAN_05 · gate นี้กันแค่ “ลืมติด”
Group B — Backend_UserService (pilot backend)
| # | ไฟล์ | Action |
|---|---|---|
| B1 | pipelines/ci.yml | แทรก template calls: gitleaks (ก่อน Test) · sonar (คร่อม dotnet test) · trivy + sbom (หลัง build ก่อน push) · regression-gates |
| B2 | sonar-project.properties (สร้างใหม่ root repo) | project key, exclusions (Migrations/, obj/, bin/) |
Group C — Frontend_HostAppSuperApp (pilot frontend)
| # | ไฟล์ | Action |
|---|---|---|
| C1 | azure-pipelines-uat.yml | gitleaks + sonar (typescript) + npm SBOM (CycloneDX) + trivy (nginx image) |
Group D — Rollout ทุก repo (หลัง pilot เขียว 2 สัปดาห์)
ทุก Backend_* + Frontend_* เรียก template ชุดเดียวกันจาก @iac — ไม่ copy-paste
Setup / Prerequisites (นอก git — ต้องมีคนทำใน Azure)
| # | งาน | Owner |
|---|---|---|
| 1 | Azure PostgreSQL Flexible Server สำหรับ SonarQube + DT | ❓ (open item จาก design) |
| 2 | KV secrets: sonar-db-password, sonar-admin-token, dtrack-api-key | ทีม infra |
| 3 | ADO variable group security-scanning ผูก KV ($(SONAR_TOKEN), $(DTRACK_API_KEY)) | ADO admin |
| 4 | APIM API objects สำหรับ Sonar/DT UI (policy XML อยู่ใน git แล้ว — ตัว API resource ต้อง register ใน portal) | ทีม infra |
| 5 | Federated identity credential สำหรับ SA namespace security | ทีม infra |
Verify
- Pipeline pilot รันครบทุก stage — inject test: commit secret ปลอม → Gitleaks fail · Dockerfile ใช้ base image เก่ามี CVE → Trivy fail
- SonarQube dashboard เห็น project + quality gate ทำงาน
- DT เห็น SBOM + วิเคราะห์ CVE ได้
- Regression gates: แอบใส่
if (isDev)กลับ → build fail
⚠️ ข้อควรระวัง
- อย่าเปิด blocking ทุกตัววันแรก — ยกเว้น Gitleaks (secret ใหม่ไม่มีข้ออ้าง) · ตัวอื่น non-blocking จน triage baseline เสร็จ มิฉะนั้นทีม bypass gate ด้วยการปิด scan = แย่กว่าเดิม
- SonarQube Community ไม่รองรับ PR decoration บน Azure DevOps (ฟีเจอร์ Developer Edition) — ใช้ quality gate + dashboard แทน
- Trivy DB ต้อง update ได้จาก build agent (egress ไป ghcr.io) — ตรวจ firewall
- BOT tool-acceptability (design §8) — user ยอมรับความเสี่ยงเดินหน้าก่อนแล้ว แต่บันทึกไว้เป็น decision D8
🎯 ถ้าเป็นผมจะทำอย่างไร (ความเห็น Fable)
- เริ่มจากตัวที่ไม่ต้องมี infra: Gitleaks + Regression Gates (A9) + Trivy — ทั้งสามตัวรันใน pipeline เปล่าๆ ไม่ต้อง host อะไรบน AKS เลย เปิดได้ภายในสัปดาห์เดียว · SonarQube + Dependency-Track (ต้องมี PostgreSQL + คนดูแล) ค่อยตามทีหลัง — อย่าให้ scanner ที่ infra หนัก block การเริ่ม scanner ที่เบา
- A9 regression gates สำคัญกว่า SonarQube — SonarQube หาของใหม่ทั่วไป แต่ gate กัน
if(isDev)กลับมาคือสิ่งที่ปกป้องงาน Phase 0 โดยตรง — ผมจะ merge A9 เข้าทุก repo ทันทีที่ Phase 0 ของ repo นั้นเสร็จ (ไม่รอ pilot 2 สัปดาห์) - Gate policy: Gitleaks = blocking วันแรก (secret ใหม่ไม่มีข้ออ้าง) · Trivy = blocking เฉพาะ Critical หลัง grace 2 สัปดาห์ · SonarQube = non-blocking จน baseline เคลียร์ — ตาม activity diagram เดิม ไม่มีอะไรต้องเถียง
- เพิ่ม FE-specific gate ใน A9 (จาก findings IMPL_PLAN_10 §9):
localStorage.*[Tt]oken·console\.log.*(user|profile|token)·bypassSecurityTrustนอก allowlist — ถูกกว่ารอ DAST - Grep-based gate เป็น stopgap — ถ้าทีมมี capacity ค่อยยกระดับเป็น Roslyn analyzer ใน Backend_Package (กันได้แม่นกว่า เช่น controller ไม่มี auth attribute) — แต่อย่าเอา analyzer มา block การเปิด grep gate วันนี้
📚 อ้างอิงมาตรฐาน (สำหรับใช้ในที่ประชุม):
| หลักการ | แหล่งอ้างอิง |
|---|---|
| Secure development framework ระดับชาติ (รวม SAST/SCA ใน pipeline) | NIST SP 800-218 — Secure Software Development Framework (SSDF) |
| ความเสี่ยงเฉพาะของ CI/CD pipeline | OWASP Top 10 CI/CD Security Risks |
| แนวทาง DevSecOps + ตำแหน่ง scanner ใน pipeline | OWASP DevSecOps Guideline |
| SBOM format มาตรฐาน (ใช้กับ Dependency-Track) | CycloneDX — OWASP SBOM Standard |
| Supply-chain integrity levels (เทียบ maturity) | SLSA — Supply-chain Levels for Software Artifacts |