直接回答:Claude Code 可以讀到 .env 嗎

可以。Claude Code 在你的專案目錄中執行,它有權限讀取專案裡的所有檔案,包括 .env、.env.local、config.json 或任何包含 API 金鑰的檔案。如果你沒有做任何防護,Claude Code 在分析你的程式碼時可能會看到你的 API 金鑰、資料庫密碼、第三方服務的 Token。

這不代表 Claude Code 會「偷走」你的金鑰。但它確實會在分析程式碼的過程中讀取這些內容,而這些內容會被傳送到 Anthropic 的伺服器進行處理。即使 Anthropic 承諾不用這些資料訓練模型,減少敏感資訊的暴露面仍然是正確的安全做法。

同樣的問題也存在於 GitHub Copilot、Cursor、Cody 等其他 AI 程式碼工具——它們都會讀取你專案中的檔案來提供建議。

為什麼這很危險

場景一:AI 把金鑰寫進程式碼

你請 Claude Code「幫我寫一個呼叫 OpenAI API 的函式」。Claude Code 看到你的 .env 裡有 OPENAI_API_KEY=sk-proj-abc...,它可能會在生成的程式碼範例中直接引用這個值,或者在解釋中提到金鑰的前幾個字元。如果你沒有檢查就 commit 了這段程式碼,金鑰就進了 Git 歷史。

場景二:對話紀錄包含敏感資訊

你在 Claude Code 的對話中問了「為什麼我的資料庫連不上?」,Claude Code 讀取了你的 .env 裡的資料庫連線字串(包含帳號密碼),然後在回答中顯示出來。如果你在公開的螢幕上操作(例如直播、簡報、螢幕分享),這些資訊就被看到了。

場景三:金鑰被送到第三方

Claude Code 運作時,你的程式碼片段會被送到 Anthropic 的 API 進行處理。如果這些片段包含你的 AWS Secret Key 或 Stripe API Key,雖然 Anthropic 的隱私政策說不會用這些資料訓練模型,但這些金鑰確實離開了你的本機。在安全的思維中,任何不必要的資料傳輸都是風險。

場景四:多人協作的金鑰管理

在團隊中,如果每個人都把金鑰放在本地的 .env,有人可能沒有設定好 .gitignore,不小心把 .env commit 進了共享的 repo。Claude Code 或其他 AI 工具讀到 repo 中的 .env 後,問題就擴大了。

防護層 1:.claudeignore

Claude Code 支援 .claudeignore 檔案,語法和 .gitignore 相同。把敏感檔案加進去,Claude Code 就不會讀取這些檔案的內容。

在專案根目錄建立 .claudeignore

# 環境變數和密鑰
.env
.env.*
.env.local
.env.production

# 金鑰和憑證
*.pem
*.key
*.p12
*.pfx
credentials.json
service-account*.json
secrets/

# SSH 金鑰(如果放在專案裡)
id_rsa
id_ed25519

# CI/CD 設定中可能包含密鑰的檔案
.github/workflows/*.yml
# 如果 workflow 中用 secrets,把它排除
# 但如果你需要 AI 幫你修 CI,就要取捨

# Terraform state(可能包含密鑰)
*.tfstate
*.tfstate.backup

# Docker 設定(可能包含密鑰)
docker-compose.override.yml

注意事項:

.claudeignore 只在 Claude Code 中有效,其他 AI 工具(Copilot、Cursor)不認這個檔案。Cursor 使用 .cursorignore,Copilot 目前沒有等效的機制。

.claudeignore 不會阻止 Claude Code 看到你在對話中手動貼進去的內容。如果你自己複製了 .env 的內容貼到 Claude Code 的對話中,.claudeignore 幫不了你。

防護層 2:.gitignore 與 pre-commit hook

.gitignore 是防止金鑰進入 Git 歷史的第一道關卡。

.gitignore 設定

# 環境變數
.env
.env.*
!.env.example

# IDE 設定
.idea/
.vscode/settings.json

# 密鑰和憑證
*.pem
*.key
*.p12
credentials.json

!.env.example 的意思是:排除所有 .env 開頭的檔案,但 .env.example 除外。.env.example 是你放在 repo 裡的範本檔案,裡面只有欄位名稱和假值,讓其他開發者知道需要哪些環境變數。

# .env.example
OPENAI_API_KEY=your-api-key-here
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
STRIPE_SECRET_KEY=sk_test_your-key-here

pre-commit hook

即使有 .gitignore,如果有人用 git add -f 強制加入被忽略的檔案,金鑰還是會進入 Git。pre-commit hook 可以在 commit 之前自動掃描暫存區,阻擋包含金鑰的 commit。

用 detect-secrets 工具(Yelp 開發的開源工具):

pip install detect-secrets

在專案中建立 .pre-commit-config.yaml

repos:
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.5.0
    hooks:
      - id: detect-secrets
        args: ['--baseline', '.secrets.baseline']

安裝 hook:

pre-commit install

之後每次 git commit 時,detect-secrets 會自動掃描暫存區的檔案,如果發現像是 API key、密碼、private key 的字串,會阻止 commit 並顯示警告。

其他類似工具:gitleaks、truffleHog。gitleaks 的速度比 detect-secrets 快,適合大型 repo。truffleHog 擅長掃描 Git 歷史中是否已經有洩漏的金鑰。

如果金鑰已經不小心 commit 了

金鑰進了 Git 歷史後,就算你在下一個 commit 刪除檔案,金鑰仍然可以從歷史紀錄中找到。正確的處理步驟:

  1. 立即撤銷(revoke)已洩漏的金鑰。到對應的服務(AWS Console、OpenAI Dashboard、Stripe Dashboard)把那組金鑰作廢,產生新的金鑰。這是第一步也是最重要的一步。
  2. 用 git filter-repo 或 BFG Repo-Cleaner 從 Git 歷史中移除包含金鑰的檔案。
  3. 強制推送(force push)清理後的歷史到遠端。
  4. 通知所有有 clone 這個 repo 的人重新 clone。

光從 Git 歷史中移除是不夠的——如果這個 repo 曾經公開過(例如在 GitHub 上是 public),金鑰已經被爬蟲抓走了。GitHub 自己也說:一旦 secret 被推到公開 repo,就要假設它已經被洩漏,必須撤銷。

防護層 3:環境變數管理

本地開發

.env 檔案搭配 dotenv 套件是最常見的做法。不同語言的 dotenv 實作:

  • Node.js:dotenv 套件
  • Python:python-dotenv 套件
  • Ruby:dotenv gem
  • Go:godotenv 套件

在 Node.js 中:

require('dotenv').config();
const apiKey = process.env.OPENAI_API_KEY;

在程式碼中永遠透過 process.env(Node.js)或 os.environ(Python)讀取金鑰,不要把金鑰值直接寫在程式碼中。

多環境管理

大部分專案至少有三個環境:開發(development)、測試(staging)、正式(production)。每個環境應該有各自的金鑰。

.env                # 開發環境(預設)
.env.staging        # 測試環境
.env.production     # 正式環境

正式環境的金鑰不應該出現在任何開發者的本機上。正式環境的金鑰只存在於部署環境(例如 Cloudflare 的 Environment Variables 設定、AWS Parameter Store)中。

CI/CD 中的密鑰

在 GitHub Actions 中,使用 GitHub Secrets:

env:
  OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

金鑰儲存在 GitHub 的 encrypted secrets 中,只有在 workflow 執行時才能存取,且不會出現在日誌中(GitHub 會自動遮蔽 secrets 的值)。

防護層 4:Secrets Manager

對正式的生產環境,.env 檔案已經不夠用。專業的密鑰管理服務提供:

  • 加密儲存
  • 存取記錄(誰在什麼時候存取了哪個金鑰)
  • 金鑰輪換(自動定期更換金鑰)
  • 細粒度的存取控制(哪個服務或人員可以存取哪些金鑰)

AWS Secrets Manager

AWS 的密鑰管理服務。存取方式:

import boto3, json

client = boto3.client('secretsmanager', region_name='ap-northeast-1')
response = client.get_secret_value(SecretId='prod/openai-key')
secret = json.loads(response['SecretString'])
api_key = secret['OPENAI_API_KEY']

費用:每個 secret 每月 $0.40,每 10,000 次 API 呼叫 $0.05。小型專案可能覺得貴,但對正式環境來說,金鑰洩漏的潛在損失遠超過這個費用。

GCP Secret Manager

Google Cloud 的版本。概念和 AWS 類似,整合在 Google Cloud 的 IAM 權限體系中。

HashiCorp Vault

開源的密鑰管理工具,可以自己架設。功能最完整,但設定和維護的複雜度也最高。適合有專職 DevOps 或 SRE 團隊的企業。

選擇建議

個人開發者和 side project:.env + .gitignore + .claudeignore 就夠了。

小團隊(5 人以下):加上 pre-commit hook(detect-secrets 或 gitleaks),CI/CD 用 GitHub Secrets。

企業環境:上 Secrets Manager(AWS、GCP、或 Vault),正式環境的金鑰永遠不出現在開發者的本機。

實際操作:建立完整的防護

以一個 Node.js 專案為例,從頭建立四層防護:

第一步,建立 .env.example 和 .env:

# .env.example(進 repo)
OPENAI_API_KEY=your-key-here
DATABASE_URL=postgresql://user:password@localhost:5432/mydb

# .env(不進 repo)
OPENAI_API_KEY=sk-proj-actual-key-value
DATABASE_URL=postgresql://admin:[email protected]:5432/prod

第二步,設定 .gitignore:

.env
.env.*
!.env.example

第三步,設定 .claudeignore:

.env
.env.*
*.pem
*.key
credentials.json

第四步,安裝 pre-commit hook:

pip install pre-commit detect-secrets
detect-secrets scan > .secrets.baseline
pre-commit install

第五步,在程式碼中使用環境變數:

require('dotenv').config();

const openaiKey = process.env.OPENAI_API_KEY;
if (!openaiKey) {
  throw new Error('Missing OPENAI_API_KEY environment variable');
}

安全考量

不只是 Claude Code,所有 AI 程式碼工具都有同樣的問題。在決定使用任何 AI 工具之前,確認:

  1. 這個工具的隱私政策如何處理你傳送的程式碼?是否用於訓練?
  2. 你的公司是否允許程式碼被傳到第三方服務?
  3. 你的專案中是否有法規要求的敏感資料(例如醫療資料、金融資料)不能離開特定的環境?

如果你的環境對安全要求很高(金融業、醫療業、政府機關),在使用任何雲端 AI 工具之前,建議先取得資安團隊的評估和核准。

另一個常被忽略的風險:AI 工具可能在生成程式碼時建議你安裝某個套件,而這個套件是惡意的(typosquatting 攻擊——名稱和熱門套件差一個字母)。確認 AI 建議安裝的每個套件都是你認識的、下載量合理的、來自可信來源的。

知識檢測

讀完文章後,測試一下你對這個主題的理解。

常見問題

Claude Code 會把我的金鑰用來訓練模型嗎?

根據 Anthropic 的隱私政策,透過 API 傳送的內容不會被用來訓練模型。Claude Code 使用的就是 API。但這取決於你信任 Anthropic 的隱私承諾到什麼程度。防護措施的意義在於:即使你相信服務商的承諾,減少不必要的敏感資訊傳輸仍然是正確的安全實踐(最小權限原則)。

.claudeignore 和 .gitignore 有什麼不同?

.gitignore 告訴 Git 哪些檔案不要追蹤。.claudeignore 告訴 Claude Code 哪些檔案不要讀取。兩者的目的不同但保護對象可能重疊。建議兩個都設定。

金鑰已經推到 GitHub 了怎麼辦?

第一步是撤銷金鑰(revoke),到對應服務的管理面板把那組金鑰作廢,產生新的。第二步用 git filter-repo 或 BFG Repo-Cleaner 清理歷史。第三步 force push。如果 repo 曾經是 public,金鑰要視為已經洩漏,撤銷是唯一的保障。

團隊成員怎麼取得開發用的金鑰?

不要用 Slack、email 或任何通訊工具傳送金鑰(這些都會留紀錄)。使用密碼管理工具(1Password、Bitwarden)的安全分享功能,或在公司內部的 Secrets Manager 中管理。新成員加入時,由管理員在密鑰管理系統中授權存取,而不是直接把金鑰值傳給他。

我用 Docker 開發,.env 還需要防護嗎?

需要。Docker Compose 通常用 env_file: .envenvironment: 設定來注入環境變數,這些設定檔同樣不應該進 Git。如果你用 Docker Secrets(Swarm 模式)或 Kubernetes Secrets,金鑰的處理已經比 .env 安全,但仍然要注意 Kubernetes Secrets 預設是 base64 編碼而不是加密——需要搭配 RBAC 和 etcd 加密來保護。

延伸閱讀

  • AI 生成的程式碼要怎麼審查?安全檢查清單(ai-generated-code-audit)
  • 用 Cloudflare Pages 部署 AI 生成網站的安全設定(ai-deploy-cloudflare)
  • Prompt Injection 是什麼?一句話駭入 AI 的攻擊手法(what-is-prompt-injection)