Dev Container
1 件の記事
Why Dev Container?
- AIを隔離してセキュリティを維持(権限最小化)
- AIが閲覧できるのはマウントしたディレクトリだけ
- 利用できるツールやネットワークも限定
- GithubやAWSなどの権限もAI専用に
- 環境統一が容易
- 設定ファイルをリポジトリに保存しておけばワンクリックで環境再現
- たとえWindows/Mac混在チームでもDevContainerなら対応可能
- CI/CD(Linux)との環境統一も視野に入れられる
- エディタ連携もある
- Visual Studio Codeとの連携も便利
- VS ホスト起動
- AIがユーザーの権限を利用できてしまう。これは通常広すぎるし強すぎる
- e.g., 機密情報を含んだファイルが閲覧できる権限、データを消せる権限、AWSの重要リソースを停止・破壊できる権限など
- チーム間の環境統一も手間がかかる
- ホストのOS自体WindowsだったりMacだったり
- CI/CDとの連携も加えるとさらに難儀に
- ホスト環境も汚れるしセットアップも面倒
Setup
設定ファイルの保存場所
<Gitのルートリポジトリ>/.devcontainer/
単一コンテナ VS docker compose
- 開発のためミドルウェアなどの別コンテナが必要ならdocker-compose
- それ以外は単一コンテナで十分(YAGNIの精神)
- あとからdocker-compose対応にするのもAIを使えばさほど手間ではない
バージョン指定
- 環境統一のため、ベースイメージや主要ツールはバージョンを明記する
- 原則フルバージョン(X.Y.Z)を記載する
- マイナーバージョンまで(X.Y)でも可
- 固定ではなく指定。バージョンアップは積極的に
- latest運用は避ける
ベースイメージ管理
- ビルド済イメージを活用
- ゴールデンイメージを作って主要部分は確実に共通化
- 開発用とCI/CD用の違いはそれぞれのDockerfileで吸収
- 管理の手間がかかるため、これ自体も自動化
セキュリティ維持の取り組み
- AIエージェントは100%安全なシステムではない
- prompt injection、クラウドAIなら運営側の事故による漏洩などなど
- リスクマネジメントが必要
- 権限付与の基本は
短命トークン + 最小権限- ExpireなしのAPIキーは原則として利用させない
- AWSならIdentity Center + 妥当な範囲の権限 + Service control policies (SCPs)
- 妥当な範囲の権限 ≒ 機密情報を含まない範囲の読取権限 + 最小限の更新権限
- 完璧主義で最小化を目指すと実用性が損なわれるため、「妥当な」権限縮小を
- 重要リソースの更新など責任を伴う業務は原則として人間を絡めることを推奨(ヒューマンインザループ)
- GitHubの
ghはExpireを短めにしたFine-grained PATで妥協(最短のExpireでも長いので期待しすぎないこと)- 権限管理の仕組みが今のところAWSほどうまくかみ合わせられない
- 読み取り禁止設定もやらないより良い
- これでは利用できないほど重要なリポジトリでは、DevContainer + AIでリポジトリごと預けるのを潔く避ける
- リポジトリ内の設定ファイル(e.g., .envなど)に機密情報を平文で保存しておかない
- たとえ動作設定でDenyしても閲覧されるリスクがゼロにはならない
- SSM Parameter Storeなど外部に出す
- リポジトリへの保存がどうしても必要なら暗号化する
- ただし、この場合AIが復号できてしまわないようにする
- 復号した後のファイルを放置してうっかりAIに読まれてしまわないようにもする
- 環境変数で受け渡す方式はリポジトリに保存しないで済むが、AIエージェント相手の隠ぺいとしては不徹底
- そもそも論、AIが関係なくともリポジトリに平文で機密情報を保存すべきでない
Claude Codeの動作設定
- 権限設定
- まず危険な内容をDeny
- 機密情報を含むファイルの閲覧(e.g.,
.env, ~/.aws/credentials) - 危険なコマンドの利用(e.g.,
sudo、rm -rf)
- 次に効率優先でよい内容をAllow
- コードを保存したディレクトリ(e.g.,
src/)でのファイル編集
- それ以外は手動確認
- ネットワーク設定
- 通常必要なドメインは許可
- 任意ドメインは禁止
- アタッカーのドメインにつなげられてしまうので
- もし任意ドメインの調査がしたいなら、リポジトリに紐づいたDev Containerを使わないで別のコンテナを使う