1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

開発チームのセキュリティ意識を高めるため、GitHub ActionsでDockerイメージのセキュリティスキャンを行い、その結果をプルリク(PR)のコメントとして自動的に追加するような仕組みをCIに組み込みました。

スクリーンショット 2024-07-14 9.23.34.png

scan-and-commentジョブの概要

このジョブは、コードのチェックアウト、Dockerイメージのビルド、セキュリティスキャン、結果の整形、そしてPRへのコメント投稿までの一連のステップを自動化します。Dockerイメージの脆弱性スキャンにはTrivyを使用しています。Trivyについての詳細は別記事で触れています。

scan-and-commentジョブの詳細

以下が、scan-and-commentジョブを追加した後のCIワークフロー全文です。

name: backend-ci
on:
  push:
    branches:
      - main
      - staging
      - develop
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
    paths:
      - "backend/**"
  workflow_dispatch: #手動動作確認用

jobs:
  setup:
    ...略...

  test:
    ...略...

  lint:
    ...略...

  tsc:
    ...略...

  scan-and-comment:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request' && github.event.action == 'opened'
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      # 本番環境で使用されるDockerイメージをビルドし、その後のステップで脆弱性スキャンを行う
      - name: Build Docker Image
        run: docker build --build-arg ENV=prod -t local-image:latest -f ./backend/Dockerfile.ecs ./backend

      - name: Scan image with Trivy
        uses: aquasecurity/trivy-action@0.24.0
        with:
          image-ref: local-image:latest
          format: "table"
          severity: "CRITICAL,HIGH"
          output: trivy-result.txt

      - name: Check Trivy result file
        run: cat trivy-result.txt

      - name: Format Trivy Scan Result
        run: |
          if [ -s trivy-result.txt ]; then
            echo -e "## Vulnerability Scan Results\n<details><summary>Details</summary>\n\n\`\`\`\n$(cat trivy-result.txt)\n\`\`\`\n</details>" > formatted-trivy-result.md
          else
            echo -e "## Vulnerability Scan Results\nNo vulnerabilities were detected." > formatted-trivy-result.md
          fi

      - name: Comment PR with Trivy scan results
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          path: formatted-trivy-result.md

      - name: Clean up Trivy result file
        run: rm -f trivy-result.txt formatted-trivy-result.md

1. コードのチェックアウト

if: github.event_name == 'pull_request' && github.event.action == 'opened'により、このジョブはPRが新しく作成されたときにのみ実行されます(PRの同期や再開時にはジョブがトリガーされません)。

また、チェックアウトで最新のコードを取得します。

scan-and-comment:
  runs-on: ubuntu-latest
  if: github.event_name == 'pull_request' && github.event.action == 'opened'
  steps:
    - name: Checkout code
      uses: actions/checkout@v4

2. Dockerイメージのビルド

本番環境と同じ設定でDockerイメージをビルドします。これにより、本番環境で発生する可能性のある脆弱性を検出できます。

- name: Build Docker Image
  run: docker build --build-arg ENV=prod -t local-image:latest -f ./backend/Dockerfile.ecs ./backend

以下がビルドに使用するDockerfileです。本番環境でプロダクションビルドを行なうようにしているため、ビルド時に本番環境用のパラメータENV=prodを指定して、セキュリティスキャンの精度を高めています。

また、local-image:latestは脆弱性スキャンのみに使用するDockerイメージで、任意の名前をつけています。

FROM node:20.15.0 AS builder

WORKDIR /app

COPY package*.json ./
COPY yarn.lock ./

# Huskyを無視して依存関係をインストール
# yarn buildのためにこちらでproductionモードは使用しない
RUN yarn install --frozen-lockfile --ignore-scripts

COPY . .

RUN yarn build

ARG ENV

# stg環境とprod環境の場合はnode_modulesを削除してproductionモードで再インストールする
RUN if [ "$ENV" = "prod" ] || [ "$ENV" = "stg" ]; then \
        rm -rf node_modules && yarn install --frozen-lockfile --ignore-scripts --production; \
    fi

FROM node:20.15.0-slim

WORKDIR /app

COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

EXPOSE 8080

CMD ["node", "dist/main"]

3. Trivyによるイメージスキャン

Trivyを使用してイメージのセキュリティスキャンを実施し、結果をテキストファイルに保存します。

以下が使用するアクションです。

- name: Scan image with Trivy
  uses: aquasecurity/trivy-action@0.24.0
  with:
    image-ref: local-image:latest
    format: "table"
    severity: "CRITICAL,HIGH"
    output: trivy-result.txt

- name: Check Trivy result file
  run: cat trivy-result.txt

4. スキャン結果の整形

スキャンの結果に基づき、詳細な情報を含むコメントフォーマットを作成します。

- name: Format Trivy Scan Result
  run: |
    if [ -s trivy-result.txt ]; then
      echo -e "## Vulnerability Scan Results\n<details><summary>Details</summary>\n\n\`\`\`\n$(cat trivy-result.txt)\n\`\`\`\n</details>" > formatted-trivy-result.md
    else
      echo -e "## Vulnerability Scan Results\nNo vulnerabilities were detected." > formatted-trivy-result.md
    fi

5. PRへのコメント投稿

フォーマットされたスキャン結果をPRにコメントとして投稿します。

- name: Comment PR with Trivy scan results
  uses: marocchino/sticky-pull-request-comment@v2
  with:
    path: formatted-trivy-result.md

6. クリーンアップ

最後に使用したファイルを削除し、環境をクリーンな状態に保ちます。

- name: Clean up Trivy result file
  run: rm -f trivy-result.txt formatted-trivy-result.md
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?