トークン、APIキー、シークレットの保護
公開?非公開?何?
トークンを保護すべきタイミングは?
API キーやトークンの保護は 極めて重要 です!
たった一つのミスで、サーバーやデータの制御権がハッカーに奪われます!
公式ドキュメントを参照すれば、特定のトークンを隠すべきかどうかを判断するのはそれほど難しくありません。
しかし、tokens, keys, credentials, secrets, private, public といった関連用語が混在すると、状況はさらに複雑になります。
ここでは secret と non-secret に分類して考え直しましょう。
- 🔒
Secret keysは必ず隠す必要があります。基本的に、プライベートサーバー(または Heroku、Netlify、Travis‑CI などのサービス)から外部に出してはいけません。 - 🌍
Non-secret keysはブラウザリクエストに自由に組み込んでも問題ない文字列を指します。
🔒 Secret keys
** ‼️ 重要:** Secret keys は Git から 除外 され、ブラウザコードにも 含めてはいけません。 dotenv の使い方
「Secret key」かどうかはどうやって判断するのか?
👍 経験則: CORS エラー を返すサーバーはブラウザから直接呼び出せません。これはそのサービスを プロキシ すべきであり、secret と同様に扱うべきことを強く示唆します。
👍 経験則: コストがかかるサービスは (ほぼ) 常にプロキシ化または隠蔽すべきです。
👍 経験則: 書き込み操作(ファイルアップロード、DB 行の挿入)を行う場合、secret keys を扱っている可能性があります。
利用ケースと特徴: Secret キー
- 長期的な認可(認証情報、アクセストークン、JSON Web Token)
- 短期的な認可(OAuth トークン、セッションストア)
- 有料/高コストサービスへのアクセス(認証、ジオコーディング、ファイル保存など)
- 公開/非公開ペアの非公開側(RECAPTCHA、Stripe、Auth0)
- サービス認証情報(Email/SMTP、LDAP/ディレクトリサービス)
- データ暗号化および整合性チェック
チェックリスト: シークレットの安全な取り扱い
クイック概要
以下の手順を実行して コードからシークレットを排除 してください。
- ハードコードされたキーを環境変数に置き換える。例:
process.env.API_SECRET -
dotenvなどのライブラリと.envファイルを併用する。以前ハードコードしていたシークレットを.envファイルに移す。 -
.gitignoreに.env行を追加する!
DON’T デプロイ先サーバーで
.envファイルを作成しないこと。ホスティングサービス(例: Heroku、Netlify、AWS EC2)で提供されている環境変数管理ツール(ダッシュボードまたは CLI)を利用してください。
Related Article: Using dotenv securely in NodeJS
🌍 Non-secret keys
👍 経験則: キーをコードやインラインでブラウザに送る必要がある場合(例: <script src="https://my-api/?apiKey=123-abc-456"> タグ)、それは確実に non-secret です。典型的な例として Google Maps が挙げられます。
利用ケースと特徴: Non-secret キー
- 短期的なアクセス(ユーザーセッション ID、JSON Web Token)
- アプリ/開発者単位での API アクセス制限(認証、ジオコーディングなど)
- 公開/非公開ペアの公開側(RECAPTCHA、Stripe、Auth0)
- アナリティクス ID
✅ 非シークレットの取り扱い:
非シークレット(公開)キーはハードコードしても安全です!
長期的に管理しやすくするため、アプリ全体で共有する config.js を用意します。
例:
module.exports = { googleMapsKey: '123-abc'};const config = require('./config.js');const key = config.googleMapsKey;const src = `//maps.googleapis.com/maps/api/js?key=${key}`;// ...注: 環境変数の他の ユースケース もあります。ここで取り上げていないものとしては、CI/CD/テスト、機能フラグ、特定環境向けのランタイム設定などがあります。