coiai Logo
ホーム記事コラムPodcast会社情報
お問い合わせ
Featured

.env ファイルをやめて Bitwarden Secrets Manager に移行した話

この記事はなに?

私たちcoiaiはモックアップの作成業務がメインで今までの開発は1-2名程度でした。しかし、6名以上で開発を進めていく案件が増えてきたため、開発環境を見直す必要に迫られました。

今まで環境変数は .env ファイルで管理していました。しかしこれからは、平文として秘密情報が確認できない状態にすること、チームで環境変数の共有の際にセキュアな共有方法を確保することを目的とし、環境整備を行いました。

Bitwarden 導入の目的と意義

  • 秘密情報(APIキー・OAuthクライアント等)を .env の平文で持つのをやめ、
    Bitwarden Secrets Manager に移する
  • Bitwarden が推奨する bws run を使うと、秘密は実行の瞬間だけ
    環境変数としてプロセスに注入され、ディスクに平文が残らない
  • 「環境変数 > .env ファイル」の優先順で設定を読む作りにしておけば、
    既存のスクリプトも docker-compose もコード変更ゼロで移行できる
  • チーム共有は「読み取り専用のアクセストークンを渡すだけ」になる

背景: .env の何が問題か

ローカル開発の秘密情報は .env + .gitignore が定番だが、いくつか弱点がある。

  1. 配布が手作業 — 新メンバーや新PCに .env をチャットやUSBで渡すことになりがち。
    渡した瞬間にコピーが増え、ローテーションも「全員に再配布」になる
  2. ディスクに平文で残る — バックアップ・ファイル共有・誤コミットに紛れ込むリスク
  3. AIコーディングエージェントに読まれる — Claude Code や Cursor のように
    シェル/ファイルアクセスを持つエージェントは、悪意がなくても問題解決の過程で
    cat .env や printenv を実行する。Bitwarden 自身がこの点をブログで指摘している
    (Your coding agent can read your .env file)

1 と 2 を解決するのがシークレット管理サービスで、Bitwarden Secrets Manager は
その中でも安価(Password Manager とは別契約)かつ CLI が単体バイナリで導入が軽い。

Bitwarden Secrets Manager で抑えて起きたい概念

注意点としてPassword Manager(個人のパスワード保管)とは別プロダクトです!Password Manager は弊社でも利用していますが、今回Secret Manager を追加で契約した形になります。

概念は3つだけです。

概念役割
プロジェクトシークレットの入れ物。今回は 1 リポジトリ = 1 プロジェクト
シークレットKEY / VALUE / メモ の3つ組。.env の 1 行 = 1 シークレット にする
マシンアカウント人間ではなくプログラム用のアカウント。プロジェクト単位で読み取り/読み書き権限を付与し、アクセストークンを発行する
Secrets Manager プロジェクト「MyProject」
  ├─ GOOGLE_CLIENT_ID     = xxxx.apps.googleusercontent.com
  ├─ GOOGLE_CLIENT_SECRET = GOCSPX-xxxx
  ├─ POSTGRES_PASSWORD    = xxxx
  └─ ...
        ▲ 読み書き: 管理者用マシンアカウント(自分)
        ▲ 読み取りのみ: メンバー用マシンアカウント(チーム配布)

セットアップ手順(Windows)

1. Web Vault 側

  1. Secrets Manager でプロジェクト(例: MyProject)を作成
  2. マシンアカウントを作成 → 「プロジェクト」タブでプロジェクトを追加し、
    権限を 「読み取り可、書き込み可」 にする(メンバー配布用は別アカウントで「読み取り可」)
  3. 「アクセストークン」タブでトークンを発行(0.xxxxxxxx... 形式)

2. bws CLI の導入

bws は Rust 製の単体バイナリ。winget には無いので
GitHub リリースから
bws-x86_64-pc-windows-msvc-<version>.zip を取得し、
%LOCALAPPDATA%\Programs\bws あたりに展開して PATH に追加する。

$dir = "$env:LOCALAPPDATA\Programs\bws"
New-Item -ItemType Directory -Force $dir | Out-Null
Invoke-WebRequest "https://github.com/bitwarden/sdk-sm/releases/download/bws-v2.1.0/bws-x86_64-pc-windows-msvc-2.1.0.zip" -OutFile "$env:TEMP\bws.zip"
Expand-Archive "$env:TEMP\bws.zip" $dir -Force
# PATH への追加(ユーザー環境変数)
[Environment]::SetEnvironmentVariable("Path",
  [Environment]::GetEnvironmentVariable("Path","User") + ";$dir", "User")

3. アクセストークンの保存

トークンはファイルに書かず、ユーザー環境変数として保存する。

setx BWS_ACCESS_TOKEN "0.xxxxxxxx-xxxx-...."

EU サーバー契約の場合はサーバー URL の設定も必要:
bws config server-base https://vault.bitwarden.eu

4. 既存 .env の一括登録

bws secret create KEY VALUE <プロジェクトID> を繰り返せばよい。
手元の .env から一括登録するならこんなワンライナーでも足りる
(本プロジェクトでは push/pull/diff できる補助スクリプトにした):

$pid_ = (bws project list | ConvertFrom-Json)[0].id
Get-Content .env | Where-Object { $_ -match "^\s*[^#].*=" } | ForEach-Object {
  $k, $v = $_ -split "=", 2
  bws secret create $k.Trim() $v.Trim() $pid_
}

登録が終わったら .env は削除する。ここがこの移行のゴール。

日常の使い方: bws run

秘密が必要なコマンドに bws run -- を前置するだけ。プロジェクト内の全シークレットが
KEY 名の環境変数としてそのプロセス(とその子プロセス)にだけ注入される。

bws run -- py scripts/drive_sync.py       # Google API を使うスクリプト
bws run -- docker compose up -d db        # compose の ${VAR} 展開にも効く

値の確認・変更は Web Vault の GUI か CLI で:

bws secret list <プロジェクトID>          # 一覧(値も表示されるので注意)
bws secret edit --value "新しい値" <シークレットID>

既存プロジェクトを無変更で移行できる条件

bws run は「環境変数を注入する」だけなので、アプリ側が環境変数を読めれば動く。

  • 自作スクリプト: 設定読み込みを「環境変数があれば優先、なければ .env」の順に
    しておく(dotenv 系ライブラリの標準挙動もこれ)。こうすると Bitwarden を使わない
    メンバーは従来どおり .env でも動く、という逃げ道が残る
  • docker-compose: ${POSTGRES_USER:-default} 形式の変数展開は、.env ファイルが
    無ければプロセスの環境変数にフォールバックするので bws run -- docker compose up で
    そのまま動く。全キーにデフォルト値を書いておくと Bitwarden なしでも起動できて便利
  • シークレットの KEY 名: 環境変数名として使うので英数字とアンダースコアに
    限定しておく(POSIX 制約)。日本語などマルチバイトの値は問題なく通る(実測)

ハマりどころ(実際に踏んだもの)

setx した環境変数が見えない

setx は「これから新しく開くシェル」にしか効かない。設定後に同じウィンドウで
実行して「未設定です」と言われたら、ターミナルを開き直すか、現在のシェルに手で読み込む:

$env:BWS_ACCESS_TOKEN = [Environment]::GetEnvironmentVariable("BWS_ACCESS_TOKEN","User")

書き込みで 404 Not Found

bws secret create が [404 Not Found] Resource not found. で失敗する場合、
シークレットやプロジェクトが無いのではなく、マシンアカウントに書き込み権限が無い
のが原因のことが多い。Bitwarden は権限不足を(リソースの存在を隠すため)404 で返す。
bws project list が通るのに create が 404 なら、まず権限を疑う。

bws run の引用符問題(Windows)

bws run は受け取ったコマンドをシェル経由で再実行するため、
bws run -- py -c "import os; ..." のような複雑な引用符は途中で剥がれて壊れる。
ワンライナーではなくスクリプトファイルにしてから bws run -- py script.py とするのが確実。

セキュリティ上の限界も理解しておく

この構成で無くなるのは「秘密のディスク上の平文コピー」と「配布の属人化」。
一方で残るものもある:

  • BWS_ACCESS_TOKEN 自体はユーザー環境変数(レジストリ)に平文で残る。
    同一マシン内の攻撃者には結局シークレットを取得されうる。ただし漏洩時の対処が
    「該当トークンを失効して再発行」だけで済むのが .env との決定的な違い
  • OAuth のトークンキャッシュ(token_drive.json 等)のように、
    アプリが自前でディスクに書く認証情報は別途残る
  • bws run は実行のたびに API へ取りに行くためオフラインでは動かない。
    オフライン作業が必要なら一時的に .env を生成して、済んだら消す運用にする

公式のベストプラクティスとしては、さらに
「マシンアカウントは用途(人・エージェント・CI)ごとに分ける」
「短命な用途のトークンには有効期限を付ける」が挙げられている。

まとめ

  • .env の役割は「シークレット管理サービス + 実行時注入」で置き換えられる
  • Bitwarden Secrets Manager なら bws run -- を前置するだけで、
    既存コードほぼ無変更・チーム配布はトークン1本で済む
  • 移行の実作業は Web Vault での 3 クリックと、CLI の zip 展開、setx 1回だけ

参考リンク

  • Secrets Manager CLI | Bitwarden — bws run の仕様・認証方法
  • Developer Quick Start | Bitwarden — 開発ワークフローの推奨手順
  • Your coding agent can read your .env file | Bitwarden Blog — .env 廃止を推す背景とベストプラクティス
  • bitwarden/sdk-sm Releases — bws CLI のバイナリ配布

投稿日: 2026年7月10日
カテゴリ: Windows, work, コラム, 自動化
タグ: セキュリティ, プログラミング
coiai

coiai

この記事もおすすめ

FSD v2.1 Feature-Sliced Design を導入する

FSD v2.1 Feature-Sliced Design を導入する

この記事は何? 公式のドキュメントやチュートリアル、exsample を読んで理解するのが一番いいですが、備忘録として残しておきます。特に後述の Skills, Steiger については開発する際にあった方が便利なので、それについても記事にします。 FSDとは? FSD (Feature-Sliced Design) はフロントエンドのアーキテクチャの一つです。 FSDとは責務で分けていくアーキテクチャと違い、ページやエンティティで分けていくアーキテクチャというとわかりやすいと思います。 コードの分離の仕方について話す前に、FSDで前提となる この3つについて理解する必要があります。 レイヤー より細かく分けていく方法がありますが、この記事では導入だけ触れたいので、3つのレイヤーのみ説明します。 です。この流れは上(app)に向かえば向かうほどアプリケーション固有、下(shared)に向かうほど汎用的になります。 原則として上位レイヤーは下位レイヤーを利用できるが、下位レイヤーから上位レイヤーへ依存できません。 始め方としては小さく初めて、必要になったらレイヤーを増やしてくようです。 スライス ブログアプリであればレイヤーの pages には といったページに分けられるため、このような構成になります。このblog-list, blog-detail, user がスライスです。これらはページやエンティティによって分けられます。 セグメント これらのmodel, ui といった部分がエンティティです。これらは責務にあたります。sharedに関しては直下にスライスではなくセグメントが入ります。 FSD 2.1 で重要なのは Pages First です。とにかくPagesから作って、細分化の必要ができたら、下位レイヤーに抽出します。 Steiger Steiger とはアーキテクチャリンターです。以下でインストールできます。 AIコーディングのために Claude Skills https://github.com/feature-sliced/skills?utm_source=chatgpt.com このリポジトリが公式に公開されています。 これで Skills を追加できるので、claude にFSDの設計知識を共有できます。

フロントエンドのアーキテクチャについて最初から考える

フロントエンドのアーキテクチャについて最初から考える

これは何? この記事は基本に立ち戻りアーキテクチャの選定を試みた際の備忘録です。Feature-Sliced Design(FSD)や Vertical Slice Architecture など、モダンなアーキテクチャがありますが、どのような判断をもとに選定するのかを考え直します。 アーキテクチャの地図 アーキテクチャを理解するために、以下のような学習のための地図を作りました。設計原則、アーキテクチャ、個別の設計パターンへと詳細になっていきます。 そもそも、、、 このコードは何を担当しているのかを考えるのが最初の問です。 商品一覧画面を作るときに といったタスクを書き出します。 これら全てを一つの巨大なコンポーネントとして作ることもできますが、管理が大変になるのは皆さんもお分かりだと思います。参考:https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html?utm_source=chatgpt.com ここからどこまでを同じモジュールとして管理するのか?という設計の問題が始まります。 Cohesion と Coupling CohesionとCouplingはそれぞれ、凝集度、結合度というようです。https://qiita.com/dsudo/items/ee3fee1f558c7f1b359f Cohesionは関係するコードがまとまっているか? Couplingは別のコードにどれだけ依存しているか? です。 例えば以下のようなコードがあります。 技術的な種類ごとに整理されていますが、商品一覧のコーディングをするのにそれぞれ別のディレクトリを行き来する必要があります。一方で、以下のように書いた場合はどうでしょうか? この書き方なら、商品に依存するコードがまとまっています。 この書き方が Feature-based Architecture, Vertical Slice Architecture に繋がっていきます。 コロケーションについて colocation Place code as close to where it&#8217;s relevant as possible 同じ種類のコードを集めることではなく、一緒に変更されるコードを近くに置くことです。 https://kentcdodds.com/blog/colocation?utm_source=chatgpt.com Layered Architecture について ここからアーキテクチャの話です。 Layered Architectureでは、技術的責務でアプリケーションを分離します。 これのメリットは責務がわかりやすいところです。 しかし、この方法では前述までとは変わり、機能を変更するときに、横断して変更する可能性があります。 つまり、技術的には分かれている一方で、機能は複数に分散するわけです。 [&hellip;]

デフォルトサムネイル

【WSL入門】Ubuntu on WSL2 に開発ツールを一式そろえる — Git / nvm / pnpm / AWS CLI / Terraform

前回の記事では、Windows に WSL2 を導入して Ubuntu が動くところまでを扱いました。ただ、素の Ubuntu はあくまで「まっさらな Linux」です。ここから実際に開発を始めるには、バージョン管理・ランタイム・クラウド操作のツールを自分で入れていく必要があります。 この記事では、すべて公式ドキュメントに載っている手順だけを使って、次のツールを順番にセットアップします。 各セクションの末尾に出典 URL を置いてあるので、手順が古くなったと感じたらそこを見に行ってください。記事末尾には出典一覧もまとめています。 検証環境Windows 11 / WSL2 / Ubuntu 24.04 LTS(x86_64)確認日:2026年7月28日 バージョン番号は執筆時点のものです。インストールコマンド自体は基本的に「常に最新を取ってくる」形になっているので、そのまま実行して問題ありません。 はじめに:WSL開発の大原則 コマンドに入る前に、ひとつだけ。Microsoft の公式ドキュメントが繰り返し書いている重要な原則があります。 使う予定のツールと同じ OS 側にファイルを置く。Linux ツールで Linux コマンドラインから作業しているなら、最速のパフォーマンスを出すためにファイルは WSL ファイルシステムに格納します。 具体的には、プロジェクトは次の場所に置きます。 /mnt/c/ 配下はファイルシステムをまたぐため、npm install や git status が体感でわかるほど遅くなります。第2弾でこれから入れるツールも、すべて Linux 側のホームディレクトリを前提に使ってください。 出典:WSL 開発環境を設定する — Microsoft Learn 1. まずは基本ツール Ubuntu を起動したら、最初にやることはパッケージの更新です。Microsoft の公式ドキュメントにもこう書かれています。 ディストリビューションの優先パッケージ マネージャーを使用して、パッケージを定期的に更新およびアップグレードすることをお勧めします。Windows [&hellip;]

デフォルトサムネイル

WindowsでWSL2をセットアップしてUbuntuを使えるようにする

TerraformやAWS CLI、Dockerを快適に使うために、WindowsにWSL2を導入しました。 この記事では、実際に行ったセットアップ手順と、途中で遭遇したエラーへの対処方法をまとめます。 なぜWSLを使うのか? WSL(Windows Subsystem for Linux)は、Windows上でLinux環境を動かすための仕組みです。 AWSやTerraform、Dockerなど、多くの開発ツールはLinux環境との相性が良いため、Windowsで開発する場合でもWSL2を利用するのが一般的です。 今回の開発環境では以下のような構成を想定しています。 1. WSLをインストール PowerShell(管理者)を開き、以下を実行します。 2. Ubuntuの初回セットアップ Ubuntuを起動すると、Linuxユーザー名とパスワードの設定を求められます。 例 好きなユーザー名を入力します。 続いてパスワードを設定します。 ※入力中は文字が表示されませんが正常な動作です。 3. パッケージを更新 Ubuntuを起動したら、まず最新状態へ更新します。 4. エラーが表示された アップグレード中に次のようなメッセージが表示されました。 一見エラーに見えますが、今回は最後まで と表示され、更新自体は正常に完了していました。 WSLではsystemd関連の処理で、このような警告が表示されることがあります。 5. WSLの状態を確認 PowerShellで以下を実行します。 今回は となっていました。 6. Docker DesktopとUbuntuの違い ここで少し混乱しやすいポイントがあります。 Docker Desktopをインストールすると、docker-desktopというWSLディストリビューションが作成されます。 しかし、これはDockerが内部で利用するためのもので、普段の開発を行う場所ではありません。 おすすめの構成は次の通りです。 開発はUbuntuで行い、Docker Desktopはコンテナ実行基盤として利用します。 7. Ubuntuを既定のディストリビューションに変更 現在登録されているWSLを確認します。 Ubuntuがインストールされていることを確認したら、 を実行します。 これで だけでUbuntuが起動するようになります。 今後インストール予定 WSL環境では今後以下を導入していきます。 この環境をベースに、AWS Organizations、IAM [&hellip;]

この記事を書いた会社

株式会社coiaiは、「想像できることを美しく実現」を掲げ、XR・Web・アプリ・システム開発およびDX支援を行う会社です。 創業2022年、東京都練馬区に本社を置き、要件のヒアリングからPoC(概念実証)、本番運用まで一貫して伴走します。 まずはお気軽にご相談ください。

商号株式会社 coiai創業2022年1月設立2025年1月23日資本金1,500,000円(設立時点)本社所在地東京都練馬区関町北 3-6-9代表者代表取締役 竹村 啓佑 / 代表取締役 服部 陽良

主なご相談内容

  • Webサイト・Webアプリの設計・開発
  • スマートフォンアプリ(iOS / Android)の開発
  • XR・AR・VRを活用した体験設計・開発
  • DX推進・業務システムの企画・開発
  • PoC(概念実証)から本番運用までの伴走支援
  • マーケティング・コンサルティング
会社概要・役員紹介を見る

詳しい会社情報は会社概要ページでご覧いただけます。

資料請求・無料相談

導入要件のヒアリングからPoC、本番運用まで伴走します。まずはお気軽にご相談ください。

フォームで問い合わせメールで相談

お問い合わせの前に 個人情報保護方針 をご確認ください。

株式会社coiai株式会社coiai

XR, Web, システム開発, DX — 想像できることを美しく実現

メールでお問い合わせ

サービス

on-premise AI

基幹システム Anchor

XR開発

会社情報

会社概要

ブログ

お問い合わせ

法務

プライバシーポリシー


所在地

〒177-0051 東京都練馬区関町北3-6-9

営業時間

平日 10:00-18:00

土日祝 休み

info@coiai.net

© 2023–2026 株式会社coiai. All rights reserved.