Private Docs

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)เนื้อหา
A1src/yamls/security/namespace.yaml + service-account.yamlnamespace security + SA ผูก Workload Identity เดิม (มีสิทธิ์ KV GET แล้ว)
A2src/yamls/security/sonarqube/*.yamlSonarQube Community: Deployment + Service + PVC + SecretProviderClass (DB password จาก KV)
A3src/yamls/security/dependency-track/*.yamlDependency-Track API server + frontend
A4argocd/security-app.yamlArgoCD Application ชี้ namespace security
A5pipelines/templates/security/gitleaks-scan.ymlstep template — รัน gitleaks บน $(Build.SourcesDirectory)
A6pipelines/templates/security/sonar-scan.ymlbegin/analyze/end + quality gate check
A7pipelines/templates/security/trivy-scan.ymlscan image ก่อน push, --severity CRITICAL,HIGH --exit-code 1 (param ปรับได้)
A8pipelines/templates/security/sbom-upload.ymlCycloneDX generate + curl upload ไป DT
A9pipelines/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
B1pipelines/ci.ymlแทรก template calls: gitleaks (ก่อน Test) · sonar (คร่อม dotnet test) · trivy + sbom (หลัง build ก่อน push) · regression-gates
B2sonar-project.properties (สร้างใหม่ root repo)project key, exclusions (Migrations/, obj/, bin/)

Group C — Frontend_HostAppSuperApp (pilot frontend)

#ไฟล์Action
C1azure-pipelines-uat.ymlgitleaks + 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
1Azure PostgreSQL Flexible Server สำหรับ SonarQube + DT❓ (open item จาก design)
2KV secrets: sonar-db-password, sonar-admin-token, dtrack-api-keyทีม infra
3ADO variable group security-scanning ผูก KV ($(SONAR_TOKEN), $(DTRACK_API_KEY))ADO admin
4APIM API objects สำหรับ Sonar/DT UI (policy XML อยู่ใน git แล้ว — ตัว API resource ต้อง register ใน portal)ทีม infra
5Federated 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

⚠️ ข้อควรระวัง

  1. อย่าเปิด blocking ทุกตัววันแรก — ยกเว้น Gitleaks (secret ใหม่ไม่มีข้ออ้าง) · ตัวอื่น non-blocking จน triage baseline เสร็จ มิฉะนั้นทีม bypass gate ด้วยการปิด scan = แย่กว่าเดิม
  2. SonarQube Community ไม่รองรับ PR decoration บน Azure DevOps (ฟีเจอร์ Developer Edition) — ใช้ quality gate + dashboard แทน
  3. Trivy DB ต้อง update ได้จาก build agent (egress ไป ghcr.io) — ตรวจ firewall
  4. BOT tool-acceptability (design §8) — user ยอมรับความเสี่ยงเดินหน้าก่อนแล้ว แต่บันทึกไว้เป็น decision D8

🎯 ถ้าเป็นผมจะทำอย่างไร (ความเห็น Fable)

  1. เริ่มจากตัวที่ไม่ต้องมี infra: Gitleaks + Regression Gates (A9) + Trivy — ทั้งสามตัวรันใน pipeline เปล่าๆ ไม่ต้อง host อะไรบน AKS เลย เปิดได้ภายในสัปดาห์เดียว · SonarQube + Dependency-Track (ต้องมี PostgreSQL + คนดูแล) ค่อยตามทีหลัง — อย่าให้ scanner ที่ infra หนัก block การเริ่ม scanner ที่เบา
  2. A9 regression gates สำคัญกว่า SonarQube — SonarQube หาของใหม่ทั่วไป แต่ gate กัน if(isDev) กลับมาคือสิ่งที่ปกป้องงาน Phase 0 โดยตรง — ผมจะ merge A9 เข้าทุก repo ทันทีที่ Phase 0 ของ repo นั้นเสร็จ (ไม่รอ pilot 2 สัปดาห์)
  3. Gate policy: Gitleaks = blocking วันแรก (secret ใหม่ไม่มีข้ออ้าง) · Trivy = blocking เฉพาะ Critical หลัง grace 2 สัปดาห์ · SonarQube = non-blocking จน baseline เคลียร์ — ตาม activity diagram เดิม ไม่มีอะไรต้องเถียง
  4. เพิ่ม FE-specific gate ใน A9 (จาก findings IMPL_PLAN_10 §9): localStorage.*[Tt]oken · console\.log.*(user|profile|token) · bypassSecurityTrust นอก allowlist — ถูกกว่ารอ DAST
  5. 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 pipelineOWASP Top 10 CI/CD Security Risks
แนวทาง DevSecOps + ตำแหน่ง scanner ใน pipelineOWASP DevSecOps Guideline
SBOM format มาตรฐาน (ใช้กับ Dependency-Track)CycloneDX — OWASP SBOM Standard
Supply-chain integrity levels (เทียบ maturity)SLSA — Supply-chain Levels for Software Artifacts