macOS KeychainでAPIキーを安全に管理する — Claude Code向け完全ガイド

Claude Code APIキー管理のイメージ画像

macOS KeychainはAPIキーをAES-256-GCMで暗号化し、.envファイルより安全にClaude Codeから利用できます。

  • 要点1: .envファイルのAPIキーはGit誤コミットやシェル履歴への露出リスクがある
  • 要点2: security コマンド1行でKeychainへの登録・読み出しが可能。アカウント名は $USER で統一するのがポイント
  • 要点3: SSH経由でのアクセス時はKeychainがロックされる問題があり、unlock-keychainコマンドで対処できる

対象: Claude CodeでAPIキーを扱うスキル開発者・AI自動化担当者

今日やること: 既存の.envファイルのAPIキーをsecurity add-generic-passwordでKeychainに移行する

この記事の著者
川島陸

株式会社Nexa 代表取締役川島 陸

一橋大学経済学部卒業後、フォーティエンスコンサルティング株式会社(旧 株式会社クニエ)にて法人向けAI導入支援等を経験。独立後、AI系メディア運営やDify/n8nの導入支援を経て、株式会社Nexaを創業。法人向けAI研修・AI導入支援・AI関連メディア運営を手掛ける。

Claude CodeでAPIキーを管理するなら、.envファイルへの平文保存よりmacOS Keychainを使った管理が正解です。

「スクリプトにAPIキーを直書きしてしまっている」「.envファイルをGitにコミットしてしまいそうで不安」——こうした悩みは、Claude Codeを活用してスキルや自動化ツールを開発しているエンジニア・非エンジニアの両方で共通する課題です。

この記事では、macOS Keychainを使ったAPIキーの登録・読み出し方法から、実際のClaude Codeスキル開発で遭遇したつまずきポイント(アカウント名の不一致・SSH経由でのアクセス問題)の解決策まで、実践的に解説します。

.envファイルのAPIキー管理、実はこんなリスクがある

多くの開発者が最初に選ぶのが、プロジェクトルートに.envファイルを作り、そこにAPIキーを保存する方法です。しかしこのアプローチには、見落としがちなセキュリティリスクが複数あります。

Gitへの誤コミットは誰にでも起こる

.gitignore.envを追記するのを忘れた、あるいは書き方を間違えた——こうした小さなミスが、APIキーの公開につながります。セキュリティサービスのGitGuardian社の調査によると、GitHubには毎年数百万件のシークレットが誤コミットされており、そのうちAPIキーは最も多いカテゴリの一つです。

誤ってコミットされたAPIキーは、たとえすぐに削除しても、Gitの履歴に残ります。完全に無効化するには、APIキー自体の再発行が必要になります。

シェル履歴やログへの意図しない露出

export API_KEY="sk-xxxxx"とターミナルに直接入力する方法も危険です。macOSのzshはコマンド履歴を~/.zsh_historyに保存するため、APIキーがそのまま平文でファイルに残ります。別のユーザーや別のプロセスが読み取ってしまうリスクがあります。

複数のプロジェクトで同じキーを使い回す問題

.envファイルはプロジェクトごとに存在するため、同じAPIキーを複数プロジェクトで使う場合、それぞれのファイルに平文でコピーすることになります。管理すべきファイルが増えるほど、漏洩のリスクも比例して高まります。

macOS Keychainとは — OSレベルのセキュリティ管理

macOS Keychainとは、Appleが提供するOSレベルのパスワード・シークレット管理システムです。SafariのパスワードやWi-Fiのパスフレーズも、内部的にはKeychainで管理されています。

APIキーの管理に使うメリットは、そのセキュリティの仕組みにあります。

Keychainのデータはどこに保存されるか

Keychainのデータは~/Library/Keychains/login.keychain-dbに保存されます。このファイルはmacOSのセキュリティ機能によって保護されており、認証なしに他のプロセスが読み取ることは原則できません。

Apple公式のドキュメントによると、KeychainのデータはAES-256-GCMで暗号化されています。テーブル全体を保護するテーブルキーと、各エントリを個別に保護するper-rowキーの2層構造です。

.envファイルとの4つの違い

項目 .envファイル macOS Keychain
保存形式 平文テキスト AES-256-GCM暗号化
Git誤コミットリスク あり(gitignore設定が必要) なし(ファイルシステム外)
複数プロジェクトでの共有 ファイルのコピーが必要 1箇所の登録で全プロジェクトから参照可能
アクセス制御 なし(読み取り権限があれば誰でも) macOSの認証が必要

\ Claude Codeの導入、何から始めればいいかわかります /

法人向けClaude Code個別指導の無料相談はこちら

APIキーをKeychainに登録する(security add-generic-password)

では実際に、securityコマンドを使ってAPIキーをKeychainに登録する方法を解説します。securityコマンドは、macOSに標準搭載されているKeychainを操作するためのCLIツールです。

基本コマンド構文

security add-generic-password \  -s "サービス名(APIキーの識別名)" \  -a "$(whoami)" \  -w "APIキーの値" \  -U

オプションの意味を解説します。

オプション 意味
-s サービス名(Service)。APIキーを識別するための名前 GEMINI_API_KEY
-a アカウント名(Account)。誰のキーかを示す $(whoami)(= riku など)
-w パスワード(APIキーの値) AIzaSyXXXXXXXX
-U 同名のエントリがあれば上書き更新(Update)

具体的な登録例をいくつか示します。

# Gemini API Keysecurity add-generic-password -s "GEMINI_API_KEY" -a "$(whoami)" -w "AIzaSyXXXXXXXX" -U# X(Twitter)Bearer Tokensecurity add-generic-password -s "X_BEARER_TOKEN" -a "$(whoami)" -w "AAAAAAAAAAAAAXxxx..." -U# OpenAI API Keysecurity add-generic-password -s "OPENAI_API_KEY" -a "$(whoami)" -w "sk-proj-XXXXXXXXX" -U

アカウント名(-a)は $USER で統一する理由

ここは 実際のスキル開発で最も多くのつまずきが発生するポイントです。

あるプロジェクトで、Gemini APIキーをKeychainに登録した際に-a "gemini"と設定してしまったことがありました。スクリプト側では-a "$(whoami)"(= riku)でKeychain検索しているため、キーが見つからずエラーになり続けました。

このトラブルを防ぐために、アカウント名は常に$(whoami)または$USERで統一することを強く推奨します。

# NG: アカウント名をサービス名で登録してしまうsecurity add-generic-password -s "GEMINI_API_KEY" -a "gemini" -w "AIzaSyXXX" -U# OK: アカウント名をシステムユーザー名で統一security add-generic-password -s "GEMINI_API_KEY" -a "$(whoami)" -w "AIzaSyXXX" -U

上書き更新(-U フラグ)と削除・再登録

APIキーを更新する際は-Uフラグで上書きできます。ただし、アカウント名を変更したい場合は、一度削除してから再登録が必要です。

# 誤ったアカウント名で登録したエントリを削除security delete-generic-password -s "GEMINI_API_KEY" -a "gemini"# 正しいアカウント名で再登録security add-generic-password -s "GEMINI_API_KEY" -a "$(whoami)" -w "AIzaSyXXX" -U

Claude Codeの導入や活用方法について、個別にご相談いただけます。「どのAPIキーをどう管理すればいいか」「スキルの設計から始めたい」という段階から対応しています。

Claude Code個別指導の無料相談はこちら →


Keychainのキーをスクリプトから読み出す

登録したAPIキーをスクリプトから読み出すには、security find-generic-passwordコマンドを使います。

シェルスクリプトからの読み出し(bash/zsh)

# APIキーを読み出して変数に代入API_KEY=$(security find-generic-password -s "GEMINI_API_KEY" -a "$(whoami)" -w)# 環境変数として設定してからツールを実行export GEMINI_API_KEY=$(security find-generic-password -s "GEMINI_API_KEY" -a "$(whoami)" -w)python3 my_script.py

-wオプションを付けることで、パスワード(APIキーの値)のみをstdoutに出力します。これをコマンド置換$()で変数に代入する形が定番パターンです。

Pythonスクリプトからの読み出し(subprocess)

Claude Codeのスキル内でPythonスクリプトを使う場合は、subprocessモジュールでこのコマンドを呼び出します。

import subprocessdef get_keychain_secret(service_name: str) -> str:    """macOS KeychainからAPIキーを取得する"""    import os    result = subprocess.run(        ["security", "find-generic-password",         "-s", service_name,         "-a", os.getenv("USER", "riku"),         "-w"],        capture_output=True,        text=True    )    if result.returncode != 0:        raise ValueError(f"Keychainに {service_name} が見つかりません。登録してください。")    return result.stdout.strip()# 使用例api_key = get_keychain_secret("GEMINI_API_KEY")

このパターンは、実際に複数のClaude Codeスキル(nano-banana画像生成スキル、X APIスキルなど)で採用している実装です。

環境変数として設定してからツールを実行するパターン

外部CLIツールがAPIキーを環境変数から読み取る場合は、subprocessにenvパラメータを渡す方法が便利です。

import subprocess, os# Keychainから読み取って環境変数に渡すapi_key = get_keychain_secret("OPENAI_API_KEY")env = {**os.environ, "OPENAI_API_KEY": api_key}result = subprocess.run(["openai", "api", "completions.create", ...], env=env)

\ 業務自動化のお悩み、プロが30分で整理します /

法人向けClaude Code個別指導の無料相談はこちら

Claude Code スキルでの実践パターン

実際に50個以上のClaude Codeスキルを開発した中で確立した、Keychain管理のベストプラクティスを紹介します。

Claude Code Skillsの設計パターンの詳細はこちら →

推奨命名規則(サービス名は ALL_CAPS、アカウント名は $USER)

項目 推奨ルール 理由
サービス名(-s) GEMINI_API_KEY のようにALL_CAPS 環境変数名と統一し、混乱を防ぐ
アカウント名(-a) 常に $(whoami) スクリプト側との不一致を防ぐ
複数アカウントの場合 -a "riku_work" のようにサフィックスを付加 同一サービスの複数キーを区別できる

スキル内でのKeychain読み出しテンプレート(Python版)

import subprocess, osdef get_api_key(service_name: str, account: str | None = None) -> str:    """    macOS KeychainからAPIキーを読み出す    Args:        service_name: -s オプションに渡す値(例: "GEMINI_API_KEY")        account: -a オプションに渡す値。Noneの場合は$USERを使用    Returns:        APIキーの文字列    Raises:        SystemExit: Keychainにキーが見つからない場合    """    if account is None:        account = os.getenv("USER", os.getenv("LOGNAME", ""))    result = subprocess.run(        ["security", "find-generic-password", "-s", service_name, "-a", account, "-w"],        capture_output=True, text=True    )    if result.returncode != 0:        print(f"エラー: Keychainに '{service_name}' が見つかりません。")        print(f"以下のコマンドで登録してください:")        print(f'security add-generic-password -s "{service_name}" -a "$(whoami)" -w "YOUR_API_KEY" -U')        raise SystemExit(1)    return result.stdout.strip()

macOS Keychainアクセスアプリで確認・管理する

コマンドラインが苦手な方や、登録済みのキーを確認したい場合は、Keychainアクセスアプリ(GUIツール)が便利です。

Spotlightで「キーチェーンアクセス」と検索して起動します。左サイドバーで「ログイン」を選択し、検索バーにサービス名(例: GEMINI_API_KEY)を入力すれば、登録済みのエントリが確認できます。

補足Keychainアクセスアプリからも新規エントリの追加が可能です。メニューバー → ファイル → 新規パスワード項目 から、項目名(サービス名)・アカウント名・パスワードを設定できます。

SSH経由でKeychainにアクセスする場合の注意点

Claude Codeを別のMacにSSHで接続して使う場合(例: Mac miniをサーバーとして使う場合)、Keychainへのアクセスに追加の設定が必要になることがあります。

VSCode Remote SSHでMac miniのClaude Codeを遠隔操作する方法はこちら →

なぜSSH経由ではKeychainにアクセスできないのか

macOSのKeychainは、セキュリティ上の理由から、ユーザーがGUIでログインしているセッションでのみ自動アンロックされます。SSHでリモートログインしたセッションは、GUIログインとは別セッションとして扱われるため、Keychainがロックされた状態のままになります。

実際の開発セッションでも、SSHで別のMacに接続してClaude Codeを操作した際に、security find-generic-passwordコマンドが次のようなエラーを返すことがありました。

security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.

security unlock-keychain でアンロックする方法

SSH接続したターミナルから、以下のコマンドでKeychainをアンロックできます。

security unlock-keychain ~/Library/Keychains/login.keychain-db

実行するとパスワードの入力が求められます。Macのログインパスワードを入力することでアンロックされ、その後はsecurity find-generic-passwordが正常に動作します。

注意security unlock-keychainの効果は一時的なもので、次回のSSH切断・再接続後は再度アンロックが必要になります。自動化スクリプトでの利用には向いていないため、後述の代替戦略も検討してください。

SSH接続時のAPIキー管理の代替戦略

SSH経由でのKeychain利用が困難な場合、以下の代替方法を検討します。

方法 適するケース 注意点
SSH接続先のMacにKeychainを使ってコンソールから手動アンロック 作業開始時に毎回手動操作できる場合 ログインパスワードの入力が必要
環境変数ファイル(~/.zshenv)に書いてSSH経由で渡す セキュリティ要件が低い開発環境 セキュリティは.envと同レベル
.plistでlaunchd環境変数として設定 常時稼働のサーバー用途 設定が複雑だが自動化しやすい

ローカルのMacBook上でスクリプトを動かす場合は、Keychainが最も簡単で安全です。SSH経由の利用が多い場合は、使用する環境に合わせて設計することをお勧めします。

\ AI活用の「次の一手」を一緒に考えませんか /

法人向けClaude Code個別指導の無料相談はこちら

よくある質問

Q. security コマンドで登録したAPIキーは再起動後も残りますか?

はい、残ります。macOS Keychainはログインキーチェーン(login.keychain-db)に保存されるため、再起動後もsecurity find-generic-passwordでいつでも取り出せます。

Q. Keychain Access(GUIアプリ)でキーを確認・追加する方法は?

Spotlightで「キーチェーンアクセス」と検索して起動します。左サイドバーで「ログイン」を選択し、一覧から登録済みのエントリを確認できます。ダブルクリックで詳細を開き、「パスワードを表示」にチェックを入れるとAPIキーの値が確認できます(ログインパスワードの入力が必要です)。

Q. 複数のMacでAPIキーを同期するには?

現在のmacOS Keychainは基本的にデバイスローカルのものです。複数のMacでAPIキーを使う場合、それぞれのMacでsecurity add-generic-passwordコマンドを実行して個別に登録する必要があります。なお、iCloud Keychainを使えばデバイス間の同期も可能ですが、コマンドラインからの操作はやや複雑になります。

MacBookとMac miniでClaude Code環境を同期する方法はこちら →

Q. Keychainのキーを削除するコマンドは?

# 削除コマンドsecurity delete-generic-password -s "サービス名" -a "$(whoami)"# 例: GEMINI_API_KEYを削除security delete-generic-password -s "GEMINI_API_KEY" -a "$(whoami)"

削除に成功するとpassword has been deleted.と表示されます。

Q. 登録済みのAPIキー一覧を確認するには?

# サービス名で検索(部分一致)security find-generic-password -s "GEMINI"# 全エントリの一覧(非常に多いのでgrepで絞る)security dump-keychain | grep "svce" | grep "API"

まとめ

本記事では、macOS Keychainを使ったAPIキー管理の方法を解説しました。要点を整理します。

  • .envファイルへの平文保存は、Git誤コミット・シェル履歴への露出・複数プロジェクト管理の困難さという3つのリスクがある
  • macOS KeychainはAES-256-GCMで暗号化し、OSレベルのアクセス制御を提供する安全な選択肢
  • security add-generic-passwordで登録、security find-generic-password -wで読み出す。アカウント名(-a)は$(whoami)で統一することが重要
  • PythonスクリプトからはsubprocessモジュールでKeychainにアクセスできる
  • SSH経由での利用時はKeychainがロックされる問題があり、security unlock-keychainでアンロックする

今日からできることとして、まずsecurity add-generic-passwordコマンドで、最もよく使うAPIキー(OpenAI, Gemini等)をKeychainに登録してみてください。.envファイルへの依存を一つずつ減らしていくことで、セキュリティリスクを大幅に下げられます。


Claude Codeの導入・活用をサポートします

株式会社Nexaでは、Claude Codeを活用した業務自動化の個別指導・企業研修を提供しています。APIキー管理のような細かいつまずきも含め、スキル設計から実際の業務自動化まで、実践的にサポートします。「何から始めればいいかわからない」という段階からご支援いたします。

Claude Code個別指導の詳細・無料相談はこちら →




関連記事

AIの力で、ビジネスを次のステージへ

まずはお気軽にご相談ください。貴社に最適なAI活用プランをご提案します。

Claude Codeのプロに無料相談 30秒で日程調整完了