ビルド時のシークレットをクリーンアウトし、引数にシークレットを含めることを避ける
一段落説明
Docker イメージは単なるファイルの束ではなく、ビルド時に何が起こったかを明らかにする、複数のレイヤーを持っています。非常によくあるシナリオとして、開発者がビルド時に(主にプライベートレジストリのために)npm トークンを必要とする場面があります - ビルド時の引数としてこのトークンの値を渡すことでは、安全性を保つことはできません。無垢で安全のように思われますが、このトークン値は、開発者のマシン上の Docker 履歴や Docker レジストリ、CI から取り出すことができます。トークンを取得した攻撃者は、組織のプライベート npm レジストリに書き込むことができるよ うになります。これには、より安全な代替手段が2つあります: 申し分ない手段として、ビルド時にのみファイルをマウントすることができる、Docker の --secret 機能(2020年7月時点で実験的機能)を利用する方法があります。2つ目の方法は引数と共にマルチステージビルドを行う方法で、ビルドを行い、そしてプロダクションに必要なファイルのみをコピーするというものです。この2つ目の方法はイメージと一緒にシークレットをデプロイしてしまうことはありませんが、ローカルの Docker 履歴には現れます - これは多くの組織にとって十分に安全であると考えられています。
コード例 – Docker mounted シークレットを利用する(実験的機能だが、安定している)
Dockerfile
# syntax = docker/dockerfile:1.0-experimental
FROM node:12-slim
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN --mount=type=secret,id=npm,target=/root/.npmrc npm ci
# 残りの部分がここに来ます