Techouse Developers Blog

テックハウス開発者ブログ|マルチプロダクト型スタートアップ|エンジニアによる技術情報を発信|SaaS、求人プラットフォーム、DX推進

こんにちは。わたしはDocker build --secrets。あなたのクレデンシャルを守ります。

ogp

はじめに

 この記事は、Techouse Advent Calendar 2024 16日目です。昨日は keima さんによる GitHub Actionsのガードを高くする でした。
 こんにちは。2024年5月からエンジニアインターンとしてTechouseに入社しました、harashunnnと申します。先日、技術責任者のY氏から次のようなお話がありました。

技術責任者のY氏「次にやってもらうタスクは、Dockerfile での秘密情報の渡し方を環境変数から secret に移行することだよ」
技術責任者のY氏「ここで言う秘密情報というのは、Railsのクレデンシャルに使う鍵(RAILS_MASTER_KEY)や、Sidekiqの認証情報(BUNDLE_ENTERPRISECONTRIBSYSCOM)などだね」
技術責任者のY氏「Dockerfile内で秘密情報を扱う際には、Docker Secrets を利用するべきだよ」

 現在環境変数を使って秘密情報を渡す手法は非推奨となっており、Docker Secretsを利用してコンテナに秘密情報を渡す手法が推奨されています。これはなぜでしょうか。  本記事では、Docker Secretsを活用して機密情報を安全に受け渡す方法について解説します。そしてなぜこの取り組みが必要なのか、どのような理由でDocker Secretsを用いる手法が推奨されるのかを説明していきます。

環境変数で秘密情報を渡す方法の問題点

 まず、環境変数を使って秘密情報をコンテナに渡す方法にはいくつかの問題点が存在します。

環境変数が露出してしまうリスク

 生成された子プロセスは環境変数に対するアクセスが可能です。そのため、サードパーティのツールを呼び出す際など、予期せぬ子プロセスが秘密情報にアクセスする可能性があります。

ログに平文で秘密情報が保存されるリスク

 エラーやトラブルが発生した場合、アプリケーションが環境変数を含んだ情報をログ出力することがあります。これにより、秘密情報が漏洩する可能性があります。

環境変数へのアクセス制御が困難

 環境変数はコンテナ全体で共有されており、どのプロセスがアクセスし、どのように利用されたかを確認する事が困難です。

Docker Secretsとは

 Docker Secretsは、コンテナに対して秘密情報(APIトークンや鍵など)を安全に渡すためのDockerの機能です。秘密情報をファイルとしてコンテナに渡すことができます。主なメリットは以下の通りです。

イメージに秘密情報を残さない

 秘密情報がイメージに永続化されないため、情報漏洩のリスクを低減できます。

秘密情報のアクセス制限

 秘密情報はコンテナ内の特定のディレクトリ(/run/secrets/)に保存され、利用を制限できます。またデフォルトでパーミッションは0444に設定され、読み取り専用となっています。これにより機密情報の改竄も防ぐことが出来ます。

具体的な実装について

 コンテナにRAILS_MASTER_KEYを渡すコードを例に説明します。
 以前の弊社プロダクトでは、以下のように環境変数を使用して秘密情報を渡していました。

version: "x.x"
services:
  rails: &rails_base
    build:
      context: .
      dockerfile: ./Dockerfile.dev
      args:
        - RAILS_MASTER_KEY=${RAILS_MASTER_KEY}

 この実装ではRAILS_MASTER_KEYをDockerのargsパラメタでコンテナに渡しています。しかし、この方法には以下のリスクがあります。

  • RAILS_MASTER_KEYが意図せずログに出力される可能性
  • Dockerイメージのビルド履歴から、RAILS_MASTER_KEYが読み取られる可能性

 これらのリスクを軽減するために、Docker Secretsを利用した以下のような実装に変更します。

# その他のビルドステップ

RUN --mount=type=secret,id=RAILS_MASTER_KEY \
    RAILS_MASTER_KEY=$(cat /run/secrets/RAILS_MASTER_KEY) \

 この実装では、--mount=type=secretオプションを使用して、ビルド時にのみ/run/secrets/RAILS_MASTER_KEYに秘密情報をマウントします。そして、そのファイルから直接RAILS_MASTER_KEYを読み取り、特定のステップ内でのみ使用します。

 これを実装することにより、以下のメリットがありました。

  • Dockerイメージのビルド履歴にRAILS_MASTER_KEYが残らないため、情報漏洩のリスクを低減できる
  • 秘密情報はビルド時の特定のステップ内でのみアクセス可能となるため、意図しないアクセスを防止できる

最後に

 今回は、秘密情報を安全にコンテナで取り扱うための機能であるDocker Secretsについて紹介しました。このような取り組みによって、ソフトウェアのユーザビリティが大きく向上したり、事業に直接的なインパクトが生まれたりすることは無いかもしれません。

 しかし、長期的にはセキュアなシステム基盤がプロダクトの安定性を支え、結果として事業全体の信頼性向上につながると思います。

 Techouseのプロダクトでは、このような非機能要件についても高い基準で開発を進めています。

 明日のTechouse Advent Calendar 2024は ReLU さんによる メカニカルシンパシーを体感せよ!キャッシュラインが明かす高速化の真髄 です。


Techouseでは、社会課題の解決に一緒に取り組むエンジニアを募集しております。 ご応募お待ちしております。

jp.techouse.com