Bối cảnh & Lý do: Bảo mật chuỗi cung ứng phần mềm với SBOM
Các ứng dụng hiện đại hiếm khi chỉ bao gồm mã nguồn do nội bộ tự viết. Giữa các thư viện npm, các base layer của Debian, cùng các Go module bắc cầu (transitive), một service đơn lẻ có thể dễ dàng kéo theo hơn 1.200 dependency từ bên thứ ba. Khi một lỗ hổng CVE chưa được vá xuất hiện trong một dependency gián tiếp sâu tới bốn cấp, các công cụ quét truyền thống thường khiến bạn phải đoán mò xem nó bắt nguồn từ đâu.
Đây là lúc Software Bill of Materials (SBOM) phát huy vai trò. Hãy hình dung SBOM như một bảng thành phần dinh dưỡng chi tiết cho file binary hoặc Docker image của bạn. Nó liệt kê đầy đủ từng package, phiên bản, giấy phép (license) và mã kiểm tra SHA-256 được tích hợp trong bản build. Bản kiểm kê này biến một container bí ẩn thành một bản kê khai (manifest) rõ ràng, giúp bạn dễ dàng truy vết và kiểm toán qua từng bản release lên môi trường production, kết hợp cùng các phương pháp ký và xác thực container image bằng Cosign.
Bộ đôi Syft và Grype của Anchore xử lý bài toán này thông qua quy trình hai giai đoạn tách biệt (decoupled). Đầu tiên, Syft kiểm kê các package trên toàn bộ container, filesystem gốc và file nén thành các định dạng tiêu chuẩn mở như SPDX và CycloneDX. Tiếp theo, Grype tiếp nhận bản kiểm kê đó và đối chiếu với các nguồn cấp dữ liệu lỗ hổng cập nhật nhất từ NVD, GitHub Advisories cùng các hệ thống theo dõi bảo mật của Linux.
Việc tách biệt khâu kiểm kê khỏi khâu quét là một điểm cộng lớn. Cách tiếp cận này giúp dịch chuyển bảo mật sang trái (shift-left) để phát hiện sớm các package độc hại ngay trong pull request mà không làm tốn thêm 10 phút giải nén lại các layer của image trong pipeline.
Cài đặt: Thiết lập Syft và Grype trên máy cá nhân và Build Runner
Cả hai công cụ đều được biên dịch thành các static binary bằng Go và không phụ thuộc vào bất kỳ runtime bên ngoài nào. Bạn có thể triển khai chúng lên laptop hoặc CI runner chỉ trong chưa đầy 10 giây.
Mẹo 1: Dùng script cài đặt chính thức để thiết lập nhanh trên máy local
Bạn đang thử nghiệm trên macOS hay một máy ảo Linux local? Hãy tải trực tiếp các script cài đặt chính thức vào biến môi trường PATH của bạn:
# Cài đặt Syft vào /usr/local/bin
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sudo sh -s -- -b /usr/local/bin
# Cài đặt Grype vào /usr/local/bin
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sudo sh -s -- -b /usr/local/bin
# Kiểm tra cài đặt
syft version
grype version
Mẹo 2: Đóng gói sẵn binary vào Custom CI Base Image
Việc tải binary CLI trong mỗi lần pipeline chạy sẽ tiêu tốn băng thông mạng và tiềm ẩn nguy cơ build thất bại mỗi khi GitHub giới hạn lượt tải (rate-limit). Nếu bạn quản lý các build agent tùy chỉnh trên Kubernetes hoặc self-hosted GitHub runner, hãy đóng gói sẵn các phiên bản cố định vào chính runner image của bạn:
FROM alpine:3.19
ARG SYFT_VERSION=v1.1.0
ARG GRYPE_VERSION=v0.74.0
RUN apk add --no-cache curl ca-certificates bash \
&& curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin ${SYFT_VERSION} \
&& curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin ${GRYPE_VERSION}
Việc cố định (pin) tag phiên bản rõ ràng sẽ bảo vệ CI của bạn khỏi các lỗi do thay đổi schema hoặc các cờ lệnh (flag) bất ngờ bị loại bỏ.
Cấu hình: Tạo SBOM và tự động hóa quá trình quét trong CI/CD Pipeline
Hãy tránh việc quét bảo mật trực tiếp một lần duy nhất trên các container đang chạy. Thay vào đó, hãy tạo SBOM trước như một build artifact bất biến, sau đó để Grype đánh giá file này. Bạn sẽ kiểm tra chính xác bảng thành phần phần mềm chuẩn bị đưa lên production—không thừa, không thiếu.
Tạo SBOM theo tiêu chuẩn bằng Syft
Syft hỗ trợ kiểm kê theo nhiều định dạng tiêu chuẩn. Trong môi trường doanh nghiệp, SPDX JSON (tiêu chuẩn ISO) và CycloneDX JSON (tiêu chuẩn OWASP) là hai lựa chọn phổ biến nhất. Để kiểm kê một app image local, bạn chỉ cần chạy một lệnh duy nhất:
# Tạo SBOM định dạng SPDX JSON từ Docker image local
syft my-app:v1.2.0 -o spdx-json=sbom.spdx.json
# Hoặc kiểm tra trực tiếp một thư mục mã nguồn trong repository
syft dir:./src -o cyclonedx-json=sbom.cdx.json
Quét SBOM bằng Grype
Truyền trực tiếp file sbom.spdx.json vừa tạo vào Grype. Việc quét một image dung lượng 1,2 GB từ đầu có thể tiêu tốn 45 giây disk I/O. Ngược lại, việc quét file SBOM đã tạo sẵn chỉ mất khoảng 2 đến 3 giây vì Grype chỉ cần phân tích cú pháp JSON:
# Quét SBOM đã tạo và báo lỗi nếu phát hiện bất kỳ CVE mức High hoặc Critical nào
grype sbom:./sbom.spdx.json --fail-on high
Quy trình chuẩn tích hợp với GitHub Actions
Quy trình làm việc dưới đây sẽ build container, tạo bản kê khai SPDX, dừng quy trình build nếu phát hiện lỗ hổng nghiêm trọng, và lưu trữ SBOM để phục vụ kiểm toán tuân thủ:
name: Pipeline bảo mật chuỗi cung ứng
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build-and-audit:
runs-on: ubuntu-latest
steps:
- name: Checkout mã nguồn
uses: actions/checkout@v4
- name: Build container image
run: |
docker build -t internal/api-service:${{ github.sha }} .
- name: Tạo SBOM bằng Syft
uses: anchore/sbom-action@v0
with:
image: internal/api-service:${{ github.sha }}
format: spdx-json
output-file: sbom.spdx.json
- name: Quét SBOM bằng Grype
uses: anchore/scan-action@v3
with:
sbom: sbom.spdx.json
fail-build: true
severity-cutoff: high
- name: Tải lên SBOM artifact
uses: actions/upload-artifact@v4
with:
name: sbom-artifact
path: sbom.spdx.json
Mẹo 3: Xử lý cảnh báo giả bằng file cấu hình Grype
Quá trình phân loại cảnh báo CVE khó tránh khỏi việc gặp phải các cảnh báo chưa có bản vá từ upstream hoặc liên quan đến các tính năng binary đã bị vô hiệu hóa. Thay vì làm rối log của pipeline, bạn có thể loại bỏ các cảnh báo giả đã được xác minh bằng cách sử dụng file .grype.yaml được quản lý phiên bản:
# .grype.yaml
ignore:
- vulnerability: CVE-2023-44487
package:
name: golang.org/x/net
version: 0.15.0
reason: "HTTP/2 Rapid Reset: Service chạy phía sau AWS ALB edge kết thúc HTTP/2; runtime không bị ảnh hưởng."
check-for-app-update: false
Hãy commit file này vào thư mục gốc của repository hoặc chỉ định trực tiếp bằng lệnh grype -c .grype.yaml sbom:./sbom.spdx.json.
Kiểm tra & Giám sát: Kiểm toán kết quả, quản lý ngưỡng và duy trì khả năng giám sát liên tục
Tự động hóa kiểm thử trong CI mới chỉ là bước đầu. Giảm thiểu tình trạng quá tải cảnh báo (alert fatigue) cho lập trình viên trong khi vẫn duy trì tuân thủ nghiêm ngặt về bảo mật và giấy phép với các chính sách Kubernetes Policy as Code qua Kyverno mới là bước thứ hai.
Kiểm tra package và giấy phép (license)
Vi phạm giấy phép nguồn mở có thể dẫn đến những rắc rối pháp lý nghiêm trọng. Syft trích xuất mã định danh giấy phép cùng với tên package, giúp việc kiểm toán bản quyền trở nên dễ dàng trước khi mã nguồn được đưa lên staging:
# Xuất bảng tổng quan rõ ràng về các package và license
syft my-app:v1.2.0 -o table
# Lọc các license GPL hoặc AGPL trong toàn bộ SBOM bằng jq
cat sbom.spdx.json | jq '.packages[] | select(.licenseConcluded | test("GPL")) | {name: .name, version: .versionInfo, license: .licenseConcluded}'
Mẹo 4: Kiểm toán định kỳ liên tục mà không cần build lại
Một container image hoàn hảo được build vào thứ Hai hoàn toàn có thể xuất hiện hai lỗ hổng CVE mức Critical vào thứ Năm. Nhưng vì bạn đã lưu trữ artifact SBOM dung lượng 800 KB từ trước, bạn không cần phải tải về và build lại toàn bộ Docker image 2 GB chỉ để kiểm tra mức độ ảnh hưởng.
Hãy thiết lập một cron job định kỳ hoặc GitHub Actions workflow chạy Grype hàng ngày đối với các SBOM của các bản release production trước đây:
# Tải bản cập nhật mới nhất của cơ sở dữ liệu lỗ hổng (tải về khoảng 30-50MB)
grype db update
# Kiểm toán SBOM bản release production đối chiếu với cơ sở dữ liệu CVE hiện tại
grype sbom:./artifacts/prod-v1.2.0.spdx.json --only-fixed
Tùy chọn --only-fixed giúp cô lập những vấn đề đã có sẵn bản vá từ nhà cung cấp. Điều này giúp backlog bảo mật của bạn tập trung vào những bản sửa lỗi có thể deploy ngay lập tức, thay vì mất thời gian vào những cảnh báo chưa có cách khắc phục. Bên cạnh đó, việc kết hợp công cụ này song song với quét lỗ hổng tự động bằng Trivy Operator trên cụm Kubernetes sẽ giúp bạn hoàn thiện hệ thống phòng thủ đa tầng.
Checklist tóm tắt để kiểm toán chuỗi cung ứng
- Tạo SBOM ngay sau khi chạy
docker build. - Lưu trữ các manifest SBOM song song với image tag trong container registry hoặc S3 bucket.
- Cấu hình Grype quét trực tiếp file SBOM nhẹ thay vì phải giải nén tarball image nhiều layer.
- Duy trì file
.grype.yamlđược ghi chép rõ ràng và review kỹ lưỡng để giải trình các cảnh báo được bỏ qua. - Lên lịch kiểm toán SBOM định kỳ ở chế độ offline nhằm kịp thời phát hiện các lỗ hổng zero-day giữa các đợt release production.

