의존성·이미지 취약점 검사
원천 · framework/evomind/web/workflow-project-evo-service기준 · 릴리스 v0.12.0커밋 · 2e32c6cc파일 · docs/operations/vulnerability-scan.md기준선 · 2026-11-12
CI 가 evo-api·evo-chat·작업 이미지(evo-workspace)와 프론트 npm 잠금 파일의 알려진 취약점(HIGH·CRITICAL)을 Trivy 로 찾고 보고서를 남긴다. 지금은 파이프라인을 막지 않고 알리기만 한다. 통과 기준(차단 조건)은 보고서를 몇 번 본 뒤 사용자가 정한다(§4).
1. 무엇을 검사하나
섹션 제목: “1. 무엇을 검사하나”| 대상 | 방법 | 보고서 |
|---|---|---|
evo-api 이미지 |
backend_build 가 만든 jar 로 Dockerfile.release 를 빌드해(게시하지 않음) 이미지 검사 — 기반 이미지의 OS 패키지와 jar 안 라이브러리 |
reports/trivy-evo-api.txt |
evo-chat 이미지 |
frontend_build 의 dist 로 Dockerfile.web 을 빌드해 이미지 검사(nginx 기반 이미지) |
reports/trivy-evo-chat.txt |
| 프론트 npm 의존성 | package.json·package-lock.json 을 Trivy fs 로 검사(빌드 결과에는 라이브러리 버전이 남지 않으므로 잠금 파일을 본다) |
reports/trivy-npm.txt |
evo-workspace 이미지(workspace-runner 포함) |
scripts/workspace/build.sh 로 빌드해 이미지 검사 |
reports/trivy-evo-workspace.txt |
- 보고서 끝의
--- 검사한 대상 ---목록이 실제로 본 대상(OS 패키지, jar 안 Java 라이브러리, npm 등)이다. 취약점이 0건이어도 이 목록에Java (jar)같은 대상이 있으면 그 라이브러리까지 검사한 것이다. reports/summary.txt에 보고서마다HIGH h, CRITICAL c요약이 있다. 검사기를 실행하지 못한 보고서는결과 없음이다.- job 이름은
vuln_scan(stagerelease)이고 보고서는 파이프라인 아티팩트(30일 보관)로 받는다. 작업 이미지는 MR 의workspace_image_test·develop 의dev_workspace도 같은 스크립트로 검사한다(trivy-report.txt).
2. 언제 도나
섹션 제목: “2. 언제 도나”| 상황 | 동작 |
|---|---|
develop push, 릴리스 태그 |
항상 |
| MR | 의존성·Dockerfile·검사 스크립트·CI 설정이 바뀐 경우에만(백엔드 *.kts·gradle.properties, 프론트 package*.json, Dockerfile*, docker/**, scripts/security/**, scripts/workspace/**, .gitlab-ci.yml) |
| 예약 파이프라인(주 1회) | 코드가 바뀌지 않아도 새로 공개된 취약점을 잡는다. 예약 파이프라인은 게시·배포 job(dev_*·deploy_dev*·cleanup_old_names_*)을 돌리지 않는다 |
- 예약 일정(2026-10-30 등록): 이 프로젝트의 파이프라인 일정
취약점 검사(GH-171) — 주 1회 새벽— 대상 브랜치develop, 주기0 2 * * 1, 시간대Seoul(매주 월요일 02:00 KST). 일정은 만든 사용자의 권한으로 돌고, 일정 시간대 기본값은 UTC 라서 시간대를 지정하지 않으면 9시간 뒤(낮)에 돈다. GitLab 의 일정 확인 주기 때문에 정시가 아니라 몇 분 뒤(예: 02:03)에 시작한다. 새로 만들 때는 프로젝트 빌드 → 파이프라인 일정 에서 같은 값으로 만든다. 한 번 수동으로 실행해 보면 게시·배포 job 이 만들어지지 않는 것을 확인할 수 있다(dev_*·deploy_dev*·sonarqube_*없이 빌드·검증·vuln_scan만 돈다 — 2026-10-30 #4925 로 확인). - 전체 프로젝트가 같은 시간대에 몰리지 않게 새벽 02:00~05:00 안에서 프로젝트마다 30분씩 나눈다(evo-service 02:00, evo-cli 02:30, evo-dispatch 03:00, evo-emulator 03:30, evo-mac 04:00, evo-windows 04:30, evo-docs 05:00).
- 검사가
결과 없음으로 끝나면vuln_scan이 이미지를 다시 빌드해 한 번 더 시도한다. 개발 러너는 다른 프로젝트 CI 와 Docker 를 같이 써서 빌드한 이미지가 검사 직전에 사라진 적이 있다(스케줄 #4925 의 evo-chat, 원인 미확인). 두 번 다 실패하면결과 없음으로 남기고 계속한다. - 검사기(
TRIVY_IMAGE, 기본aquasec/trivy:0.57.1)나 취약점 DB 를 받을 수 없는 환경이면 보고서에결과 없음을 적고 job 은 실패하지 않는다. 폐쇄망은 미러 이미지와 DB 를 준비해TRIVY_IMAGE를 바꾼다.
3. 보고서 읽기와 조치
섹션 제목: “3. 보고서 읽기와 조치”- 표의
Library(라이브러리)·Installed Version·Fixed Version으로 무엇을 올려야 하는지 안다.Fixed Version이 비어 있으면(affected·fix_deferred) 아직 고쳐진 버전이 없다 — 기반 이미지가 갱신될 때까지 기다리거나 그 패키지를 이미지에서 뺄 수 있는지 본다. - 조치는 이슈로 한다: 백엔드는 Gradle 의존성·Spring Boot 버전, 프론트는
npm audit·npm update, 이미지는 기반 이미지 태그 갱신, 바이너리(evo·glab)는 해당 프로젝트에 알린다(작업 이미지의 evo·glab 취약점은 evo-cli 에 알렸다). - Trivy 가 보고한 심각도와 실제 위험은 다를 수 있다(그 코드 경로를 쓰지 않는 경우). 판단 근거를 이슈에 적는다.
4. 통과 기준(차단 조건) 정하기
섹션 제목: “4. 통과 기준(차단 조건) 정하기”- 몇 주 동안 보고서를 모아 어떤 항목이 반복되는지 본다.
- 고칠 수 있는 항목은 이슈로 처리하고, 고칠 수 없는 항목(상위 프로젝트 수정 대기)은 예외 목록(
.trivyignore)에 이유와 함께 둔다. - 사용자가 기준(예: CRITICAL 이 수정 가능하면 실패)을 정하면
scripts/security/의 검사 스크립트에 종료 코드 규칙을 넣고vuln_scan을 차단으로 바꾼다. 그 전에는 차단하지 않는다.
5. 로컬에서 돌리기
섹션 제목: “5. 로컬에서 돌리기”sh scripts/security/test-scan.sh # 스크립트 시험(도커 대역, 도커 없이)sh scripts/security/scan-image.sh <이미지:태그> trivy-image.txt # 이미지 검사sh scripts/security/scan-fs.sh <폴더> trivy-fs.txt # 폴더(npm 잠금 파일 등) 검사검사기 이미지를 받을 수 있는 환경과 Docker 가 필요하다.
Evo에게 묻기문서 근거 안에서만 답합니다
답변은 문서를 근거로 만들지만 틀릴 수 있습니다. 출처 문서를 함께 확인하세요.