
cocoapods‑keys を使ってシークレット情報をソースコードと分離して安全に扱う
はじめに
API キーやシークレットをソースコードにハードコーディングすると、GitHub を公開した際に流出リスクが生じる。
cocoapods‑keys は key の名前だけを Podfile に記述し、値は開発者のローカル Keychain に格納する CocoaPods プラグインだ。プロジェクト内へは難読化された stub だけが生成されるため、比較的安全にバイナリへ埋め込める。
この記事では cocoapods‑keys を導入し、アプリ起動直後に Text でAPI キーの値を表示するところまでを解説する。
動作環境
- macOS 15.4.1(24E263)
- Xcode 16.2
- Homebrew 4.4.31
- CocoaPods 1.16.2
- cocoapods‑keys
'818f9d2'- 注意:
'818f9d2'はバージョンではなくコミット ID 固定
- 注意:
1. CocoaPods と cocoapods‑keys をインストール
bundle init で Gemfile を生成し、下記を追記してインストールする。
# frozen_string_literal: true
source "https://rubygems.org"
# gem "rails"
gem "cocoapods"
gem "cocoapods-keys", ref: '818f9d2'
bundle install 後に bundle exec pod --version と bundle exec pod keys --help が通れば準備は完了だ。
2. Xcode プロジェクトを CocoaPods 対応にする
bundle exec pod init で Podfile を生成し、次のように編集する。
platform :ios, "18.0"
plugin "cocoapods-keys", {
:project => "SampleCocoaPodsKeys",
:keys => [
"ApiKey",
"ApiBaseUrl"
]
}
target "SampleCocoaPodsKeys" do
use_frameworks!
# Pods for SampleCocoaPodsKeys
end
post_install do |installer|
installer.pods_project.targets.each do |t|
t.build_configurations.each do |c|
c.build_settings["IPHONEOS_DEPLOYMENT_TARGET"] = "18.0"
end
end
end
:keys に列挙した文字列が環境変数名となる。ハイフン付きキーは避け、API-KEY ではなく ApiKey のように記述する。
3. pod install でキー値を入力
bundle exec pod install の初回実行時、Podfile へ書いたキーごとに値の入力を求められる。入力した値は、ローカルPCのKeychainに保存される。

値をあとから変更したい場合
bundle exec pod keys set ApiKey "abcd1234"
bundle exec pod keys set ApiBaseUrl "https://api.example.com"
保存済みの値は bundle exec pod keys get ApiKey で確認できる。
4. 生成物を確認
Pods/ 配下に CocoaPodsKeys モジュールが追加される。

生成された SampleCocoaPodsKeysKeys.m は難読化済みソースだ。シークレットとソースを分離する意味が薄れるため、このファイル群は Git へコミットしないよう .gitignore に追加する。
# cocoapods‑keys stub
Pods/CocoaPodsKeys/**
5. SwiftUI からキーを読む
Keys フレームワークを import し、生成クラスからプロパティを取得する。デバッグビルドのみキーを表示する場合は #if DEBUG を使う。
import SwiftUI
import Keys
struct ContentView: View {
private let keys = SampleCocoaPodsKeysKeys() // 自動生成されたクラス名
var body: some View {
VStack {
#if DEBUG
Text("API KEY: \(keys.apiKey)")
Text("BASE URL: \(keys.apiBaseUrl)")
#endif
}
.padding()
}
}
#Preview {
ContentView()
}
アプリを実行した結果は以下の通り。

トラブルシューティング
rsync の Sandbox エラーが出る
以下のようなエラーが発生した場合は、Build SettingsのUser Script Sandboxingを No に変更すると解決する。
Sandbox: rsync(58413) deny(1) file-write-create /Users/ch3cooh/Library/Developer/Xcode/DerivedData/SampleCocoaPodsKeys-cfrvgzlpnlcswcaspcgbzzumdzyd/Build/Products/Debug-iphonesimulator/SampleCocoaPodsKeys.app/Frameworks/Keys.framework/_CodeSignature
CI で Keychain が使えない
ローカルPCではKeychainにシークレットの値を保存した。CIではKeychainを使えない。CI環境では、シークレットの環境変数を設定することで、そちらの値を使ってくれるようになる。
まとめ
- Podfile の cocoapods‑keys へ Key 名だけを列挙する
pod install時に Keychain へ安全に保存される- Swift からは
ProjectNameKeys().apiKeyの形式で参照できる
これでリポジトリへシークレットをコミットせずに済む。
(2025/05/14追記) CocoaPodsの終了に備えて Arkana+SPMの構成へ移行する
2026年12月にCocoaPodsがアーカイブ化されてしまう。CocoaPodsの終了に備えて、cocoapods-keys から Arakana+SPM へ移行する記事を書いた。
(2025/05/14追記) Xcode Cloudで最新のArkanaを使うためにビルド環境のRubyをアップデートする
Arkana最新版はRuby 2.7以上が必要だ。Xcode Cloudでも任意のバージョンのRubyをインストールできることがわかったので別途記事を書いた。この方法を利用すればArkanaの最新版を導入できた。










