SiamCafe.net Blog
Cybersecurity

Snyk Code Security Compliance Automation — สร้างระบบ Security Scanning อัตโนมัติ

snyk code security compliance automation
Snyk Code Security Compliance Automation | SiamCafe Blog
2026-05-20· อ. บอม — SiamCafe.net· 1,595 คำ

Snyk คืออะไรและทำไมต้องใช้

Snyk เป็น developer security platform ที่ช่วยค้นหาและแก้ไขช่องโหว่ใน code, dependencies, containers และ infrastructure as code แบบอัตโนมัติ Snyk ออกแบบมาสำหรับ developers ทำให้ security เป็นส่วนหนึ่งของ development workflow ไม่ใช่ขั้นตอนแยกที่ทำทีหลัง

Snyk มี 4 products หลักคือ Snyk Open Source ที่ scan dependencies สำหรับ known vulnerabilities (SCA), Snyk Code ที่เป็น SAST tool สำหรับ scan source code, Snyk Container ที่ scan Docker images สำหรับ OS vulnerabilities และ Snyk IaC ที่ scan Terraform, CloudFormation, Kubernetes configs

Compliance Automation หมายถึงการทำให้กระบวนการตรวจสอบ security compliance เป็นอัตโนมัติ แทนที่จะตรวจสอบด้วยมือทุกครั้ง ให้ CI/CD pipeline ตรวจสอบให้โดยอัตโนมัติ ปฏิเสธ code ที่ไม่ผ่าน security standards และสร้าง compliance reports อัตโนมัติ

Standards ที่ Snyk ช่วย comply ได้แก่ SOC 2 Type II, ISO 27001, PCI DSS, HIPAA, GDPR, OWASP Top 10 และ CIS Benchmarks

ติดตั้ง Snyk CLI และ Scan โปรเจกต์

เริ่มต้นใช้งาน Snyk

# ติดตั้ง Snyk CLI
npm install -g snyk

# หรือใช้ standalone binary
# Linux
curl -sL https://static.snyk.io/cli/latest/snyk-linux -o snyk
chmod +x snyk
sudo mv snyk /usr/local/bin/

# macOS
brew install snyk

# Windows
scoop install snyk

# Authenticate
snyk auth
# หรือใช้ API token
export SNYK_TOKEN="your-api-token-here"
snyk auth $SNYK_TOKEN

# === Open Source Scan (SCA) ===
# Scan dependencies
snyk test

# Scan และดู details
snyk test --severity-threshold=high

# Scan specific file
snyk test --file=requirements.txt
snyk test --file=package.json
snyk test --file=go.mod

# Monitor (track ใน Snyk dashboard)
snyk monitor --project-name="my-project"

# === Code Scan (SAST) ===
snyk code test

# Scan specific directory
snyk code test ./src

# Output as JSON
snyk code test --json > code_results.json

# === Container Scan ===
# Scan Docker image
snyk container test nginx:latest
snyk container test my-app:v1.0 --file=Dockerfile

# Scan และ monitor
snyk container monitor my-app:v1.0

# === IaC Scan ===
# Scan Terraform
snyk iac test terraform/

# Scan Kubernetes manifests
snyk iac test k8s/deployment.yaml

# Scan CloudFormation
snyk iac test cloudformation/template.yaml

# Custom severity threshold
snyk iac test --severity-threshold=medium

# === Output Formats ===
# JSON output
snyk test --json > results.json

# SARIF output (for GitHub Code Scanning)
snyk test --sarif > results.sarif

# HTML report
snyk test --json | snyk-to-html -o report.html

# === Fix vulnerabilities ===
# Auto-fix (upgrade dependencies)
snyk fix

# ดู fix suggestions
snyk test --show-vulnerable-paths=all

รวม Snyk กับ CI/CD Pipeline

GitHub Actions workflow สำหรับ Snyk scanning

# .github/workflows/snyk-security.yml
name: Snyk Security Scan

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 6 * * 1'  # Weekly Monday 06:00

permissions:
  security-events: write
  contents: read

jobs:
  snyk-open-source:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install Dependencies
        run: npm ci
      
      - name: Snyk Open Source Scan
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: }
        with:
          args: >
            --severity-threshold=high
            --fail-on=all
            --sarif-file-output=snyk-oss.sarif
        continue-on-error: true
      
      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: snyk-oss.sarif

  snyk-code:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Snyk Code Scan
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: }
        with:
          command: code test
          args: --sarif-file-output=snyk-code.sarif
        continue-on-error: true
      
      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: snyk-code.sarif

  snyk-container:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Build Docker Image
        run: docker build -t my-app:} .
      
      - name: Snyk Container Scan
        uses: snyk/actions/docker@master
        env:
          SNYK_TOKEN: }
        with:
          image: my-app:}
          args: >
            --severity-threshold=high
            --file=Dockerfile
            --sarif-file-output=snyk-container.sarif
        continue-on-error: true
      
      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: snyk-container.sarif

  snyk-iac:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Snyk IaC Scan
        uses: snyk/actions/iac@master
        env:
          SNYK_TOKEN: }
        with:
          args: >
            --severity-threshold=medium
            --sarif-file-output=snyk-iac.sarif
        continue-on-error: true
      
      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: snyk-iac.sarif

  security-gate:
    needs: [snyk-open-source, snyk-code, snyk-container, snyk-iac]
    runs-on: ubuntu-latest
    steps:
      - name: Security Gate Check
        run: |
          echo "All security scans completed"
          echo "Check GitHub Security tab for results"

Compliance Automation ด้วย Snyk API

ใช้ Snyk API สร้างระบบ compliance อัตโนมัติ

#!/usr/bin/env python3
# snyk_compliance.py — Automated Compliance with Snyk API
import requests
import json
import logging
from datetime import datetime
from typing import Dict, List, Optional
from dataclasses import dataclass

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("snyk_compliance")

@dataclass
class ComplianceResult:
    project_name: str
    scan_type: str
    critical: int
    high: int
    medium: int
    low: int
    compliant: bool
    violations: List[str]

class SnykComplianceChecker:
    def __init__(self, api_token, org_id):
        self.base_url = "https://api.snyk.io/v1"
        self.headers = {
            "Authorization": f"token {api_token}",
            "Content-Type": "application/json",
        }
        self.org_id = org_id
    
    def get_projects(self) -> List[Dict]:
        resp = requests.get(
            f"{self.base_url}/org/{self.org_id}/projects",
            headers=self.headers,
        )
        resp.raise_for_status()
        return resp.json().get("projects", [])
    
    def get_project_issues(self, project_id) -> Dict:
        resp = requests.post(
            f"{self.base_url}/org/{self.org_id}/project/{project_id}/aggregated-issues",
            headers=self.headers,
            json={"includeDescription": False, "includeIntroducedThrough": False},
        )
        resp.raise_for_status()
        return resp.json()
    
    def check_compliance(self, policy: Dict) -> List[ComplianceResult]:
        projects = self.get_projects()
        results = []
        
        for project in projects:
            issues = self.get_project_issues(project["id"])
            
            critical = 0
            high = 0
            medium = 0
            low = 0
            
            for issue in issues.get("issues", []):
                severity = issue.get("issueData", {}).get("severity", "low")
                if severity == "critical":
                    critical += 1
                elif severity == "high":
                    high += 1
                elif severity == "medium":
                    medium += 1
                else:
                    low += 1
            
            violations = []
            compliant = True
            
            if critical > policy.get("max_critical", 0):
                violations.append(f"Critical: {critical} (max: {policy['max_critical']})")
                compliant = False
            
            if high > policy.get("max_high", 0):
                violations.append(f"High: {high} (max: {policy['max_high']})")
                compliant = False
            
            results.append(ComplianceResult(
                project_name=project["name"],
                scan_type=project.get("type", "unknown"),
                critical=critical, high=high, medium=medium, low=low,
                compliant=compliant, violations=violations,
            ))
        
        return results
    
    def generate_compliance_report(self, results: List[ComplianceResult]):
        total = len(results)
        compliant = sum(1 for r in results if r.compliant)
        
        report = {
            "report_date": datetime.utcnow().isoformat(),
            "organization": self.org_id,
            "summary": {
                "total_projects": total,
                "compliant": compliant,
                "non_compliant": total - compliant,
                "compliance_rate": f"{compliant/total*100:.1f}%" if total > 0 else "N/A",
            },
            "total_vulnerabilities": {
                "critical": sum(r.critical for r in results),
                "high": sum(r.high for r in results),
                "medium": sum(r.medium for r in results),
                "low": sum(r.low for r in results),
            },
            "projects": [
                {
                    "name": r.project_name,
                    "type": r.scan_type,
                    "compliant": r.compliant,
                    "violations": r.violations,
                    "vulnerabilities": {
                        "critical": r.critical,
                        "high": r.high,
                        "medium": r.medium,
                        "low": r.low,
                    },
                }
                for r in results
            ],
        }
        
        return report

# ใช้งาน
# checker = SnykComplianceChecker("snyk-api-token", "org-id")
# 
# policy = {
#     "max_critical": 0,
#     "max_high": 5,
#     "max_medium": 20,
# }
# 
# results = checker.check_compliance(policy)
# report = checker.generate_compliance_report(results)
# print(json.dumps(report, indent=2))

สร้าง Security Dashboard และ Reports

Dashboard สำหรับ security overview

#!/usr/bin/env python3
# security_dashboard.py — Security Compliance Dashboard
import json
from datetime import datetime
from pathlib import Path

class SecurityDashboard:
    def __init__(self):
        self.reports = []
    
    def add_snyk_report(self, report_data):
        self.reports.append({
            "source": "snyk",
            "data": report_data,
            "timestamp": datetime.utcnow().isoformat(),
        })
    
    def generate_html_dashboard(self, output_path="dashboard.html"):
        total_critical = sum(
            r["data"]["total_vulnerabilities"]["critical"]
            for r in self.reports if r["source"] == "snyk"
        )
        total_high = sum(
            r["data"]["total_vulnerabilities"]["high"]
            for r in self.reports if r["source"] == "snyk"
        )
        
        compliance_rates = []
        for r in self.reports:
            if r["source"] == "snyk":
                s = r["data"]["summary"]
                if s["total_projects"] > 0:
                    rate = s["compliant"] / s["total_projects"] * 100
                    compliance_rates.append(rate)
        
        avg_compliance = sum(compliance_rates) / len(compliance_rates) if compliance_rates else 0
        
        html = f"""



Snyk Code Security Compliance Automation — | SiamCafe




Generated: {datetime.utcnow().strftime('%Y-%m-%d %H:%M UTC')}

{total_critical}
Critical Vulnerabilities
{total_high}
High Vulnerabilities
{avg_compliance:.0f}%
Compliance Rate
{len(self.reports)}
Scans Completed

Project Details

""" for r in self.reports: if r["source"] == "snyk": for p in r["data"].get("projects", []): badge = "badge-pass" if p["compliant"] else "badge-fail" status = "PASS" if p["compliant"] else "FAIL" v = p["vulnerabilities"] html += f""" """ html += """
ProjectTypeCriticalHighMediumStatus
{p['name']} {p['type']} {v['critical']} {v['high']} {v['medium']} {status}
""" Path(output_path).write_text(html) print(f"Dashboard saved to {output_path}") def export_csv(self, output_path="compliance_report.csv"): lines = ["Project, Type, Critical, High, Medium, Low, Compliant, Violations"] for r in self.reports: if r["source"] == "snyk": for p in r["data"].get("projects", []): v = p["vulnerabilities"] violations = "; ".join(p.get("violations", [])) lines.append( f"{p['name']},{p['type']},{v['critical']},{v['high']}," f"{v['medium']},{v['low']},{p['compliant']},{violations}" ) Path(output_path).write_text("\n".join(lines)) print(f"CSV exported to {output_path}") # dashboard = SecurityDashboard() # dashboard.add_snyk_report(report) # dashboard.generate_html_dashboard() # dashboard.export_csv()

Policy as Code และ Custom Rules

กำหนด security policies แบบ code

# === Snyk Policy File (.snyk) ===
# วางที่ root ของ project

# .snyk
# version: v1.25.0
# ignore:
#   SNYK-JS-LODASH-567746:
#     - '*':
#         reason: 'Not exploitable in our context'
#         expires: 2025-06-01T00:00:00.000Z
#   SNYK-PYTHON-REQUESTS-5595532:
#     - '*':
#         reason: 'Will fix in next sprint'
#         expires: 2025-03-01T00:00:00.000Z
# patch: {}

# === Custom Policy (Python) ===
#!/usr/bin/env python3
# security_policy.py — Security Policy as Code

import json
import sys
from datetime import datetime

class SecurityPolicy:
    """Define and enforce security policies"""
    
    def __init__(self, policy_file="security_policy.json"):
        self.policy = self._load_policy(policy_file)
    
    def _load_policy(self, filepath):
        default_policy = {
            "name": "Production Security Policy",
            "version": "1.0",
            "rules": {
                "max_critical_vulns": 0,
                "max_high_vulns": 0,
                "max_medium_vulns": 10,
                "max_days_unfixed_critical": 1,
                "max_days_unfixed_high": 7,
                "max_days_unfixed_medium": 30,
                "required_scans": ["sca", "sast", "container", "iac"],
                "blocked_licenses": ["GPL-3.0", "AGPL-3.0"],
                "minimum_test_coverage": 80,
                "required_code_review": True,
                "branch_protection": True,
            },
            "exceptions": [],
            "compliance_frameworks": ["soc2", "iso27001", "owasp"],
        }
        
        try:
            with open(filepath) as f:
                return json.load(f)
        except FileNotFoundError:
            return default_policy
    
    def evaluate(self, scan_results):
        rules = self.policy["rules"]
        violations = []
        warnings = []
        
        # Check vulnerability counts
        critical = scan_results.get("critical", 0)
        high = scan_results.get("high", 0)
        medium = scan_results.get("medium", 0)
        
        if critical > rules["max_critical_vulns"]:
            violations.append(
                f"CRITICAL: {critical} critical vulns (max: {rules['max_critical_vulns']})"
            )
        
        if high > rules["max_high_vulns"]:
            violations.append(
                f"HIGH: {high} high vulns (max: {rules['max_high_vulns']})"
            )
        
        if medium > rules["max_medium_vulns"]:
            warnings.append(
                f"MEDIUM: {medium} medium vulns (max: {rules['max_medium_vulns']})"
            )
        
        # Check blocked licenses
        for dep in scan_results.get("dependencies", []):
            if dep.get("license") in rules["blocked_licenses"]:
                violations.append(
                    f"LICENSE: {dep['name']} uses blocked license {dep['license']}"
                )
        
        # Check required scans
        completed_scans = scan_results.get("completed_scans", [])
        for required in rules["required_scans"]:
            if required not in completed_scans:
                violations.append(f"MISSING SCAN: {required} scan not completed")
        
        passed = len(violations) == 0
        
        result = {
            "policy": self.policy["name"],
            "evaluated_at": datetime.utcnow().isoformat(),
            "passed": passed,
            "violations": violations,
            "warnings": warnings,
            "exit_code": 0 if passed else 1,
        }
        
        return result

# CI/CD integration
policy = SecurityPolicy()
# scan_data = json.loads(sys.stdin.read())  # pipe from snyk
scan_data = {"critical": 0, "high": 2, "medium": 5, "completed_scans": ["sca", "sast"]}
result = policy.evaluate(scan_data)

print(json.dumps(result, indent=2))
# sys.exit(result["exit_code"])

FAQ คำถามที่พบบ่อย

Q: Snyk ฟรีไหม?

A: Snyk มี Free plan ที่รองรับ 200 open source tests ต่อเดือน, 100 container tests และ 300 IaC tests เพียงพอสำหรับ small projects และ individual developers Team plan เริ่มต้นที่ $25/developer/month Business plan สำหรับองค์กรใหญ่ สำหรับ open source projects Snyk ให้ใช้ฟรีไม่จำกัด

Q: Snyk กับ SonarQube ต่างกันอย่างไร?

A: Snyk เน้น security (vulnerabilities, license compliance) ครอบคลุม dependencies, containers และ IaC SonarQube เน้น code quality (bugs, code smells, technical debt) และ security hotspots องค์กรส่วนใหญ่ใช้ทั้งสองร่วมกัน Snyk สำหรับ security scanning และ SonarQube สำหรับ code quality Snyk มี developer experience ที่ดีกว่าและ fix suggestions ที่ดีกว่า

Q: Compliance automation ช่วยลด audit time ได้จริงไหม?

A: ได้มาก จากประสบการณ์ลด SOC 2 audit preparation จาก 2-3 เดือนเหลือ 2-3 สัปดาห์ เพราะ evidence collection อัตโนมัติ (scan results, reports, fix history), policy enforcement อัตโนมัติ (CI/CD blocks non-compliant code), continuous monitoring แทน point-in-time checks และ audit trail ที่ครบถ้วนและ traceable

Q: จะ handle false positives อย่างไร?

A: ใช้ .snyk file เพื่อ ignore vulnerabilities ที่ไม่เกี่ยวข้อง (ต้องระบุเหตุผลและ expiry date) ตั้ง severity threshold ที่เหมาะสม (อาจเริ่มที่ high แล้วค่อยลดเป็น medium) ใช้ Snyk UI เพื่อ mark false positives Review ignored vulnerabilities เป็นประจำ (ทุก quarter) อย่า ignore ทุกอย่าง ควร fix ให้ได้มากที่สุด

📖 บทความที่เกี่ยวข้อง

Cloudflare Low Code No Codeอ่านบทความ → Snyk Code Security Pub Sub Architectureอ่านบทความ → Nginx Plus Compliance Automationอ่านบทความ → Snyk Code Security Security Hardening ป้องกันแฮกอ่านบทความ → Snyk Code Security Hexagonal Architectureอ่านบทความ →

📚 ดูบทความทั้งหมด →