第10章:設定と秘密情報(APIキーをコードに書かない)🗝️🧯
この章は「事故りやすい秘密情報の扱い」を最初に固めて、次章以降の Slack通知 や AI連携(Genkit / Gemini API) を安全に進める土台を作ります😊✨
この章でできるようになること 🎯
- ✅ 「秘密情報」をGitに入れない習慣がつく
- ✅ Functionsで Secret Manager(シークレット) を使える
- ✅ Slack Webhook URL を “秘密” として登録して、関数から参照できる
- ✅ ローカル検証(Emulator)でも秘密を扱える
1) まず「秘密情報」って何?🧨

秘密情報は、こういうの👇
- 🔑 APIキー(例:Gemini API / 外部SaaS)
- 🧾 Webhook URL(SlackのIncoming Webhooksなど)
- 🪪 トークン / パスワード / 署名用シークレット
- 🧪 “開発用だけど流出したら困る値”(例:社内Webhook、管理者用の隠しURL)
特に Webhook URLは「URLそのものが秘密」 です。公開すると悪用されるので、絶対に貼らないのが鉄則です😱 (Slack側も「Webhook URLは秘密、漏れたら無効化されるよ」系の注意を強く出しています) (Slack Developer Docs)
2) 2026の正解:Secrets + params を使う🧠✨

昔の functions.config() は 非推奨 で、2027年3月に廃止予定(その後は functions.config を含むデプロイが失敗)と明記されています。なので今からは「Secret Manager / params」寄せが安全です。 (Firebase)
今どきの基本はこれ👇

- 🌱 “ただの設定値”(公開しても致命傷じゃない) →
.env系でOK - 🔥 “秘密”(漏れたらアウト) → Secret Manager(Firebase CLIで登録)
- 🧷 秘密は 関数ごとに「使うよ」ってバインドする(不要な関数に渡さない) (Firebase)
3) ハンズオン:Slack Webhook URL を Secret にする 🔔🗝️
ここでは、次の名前で行きます👇
- Secret名:
SLACK_WEBHOOK_URL
3-1) SlackでIncoming Webhookを作る(準備)🧩
Slack側で Incoming Webhooks を作って URL を取得します。 そのURLは秘密なので、メモ帳に貼ってもOKだけど、Git管理のファイルに書かないでね! (Slack Developer Docs)
3-2) Firebase CLIでSecret登録(Windows / PowerShell)🪟⚙️
プロジェクト直下で👇(値の入力を促されるので、Webhook URLを貼るだけ)
firebase functions:secrets:set SLACK_WEBHOOK_URL
Secret管理コマンドの一覧も公式にまとまってます(set / access / destroy / prune など)。 (Firebase)
⚠️大事:Secretの値を変えたら、それを参照している関数は再デプロイが必要です(反映の仕組みがそうなってる)。 (Firebase)
3-3) 「Secretを使う関数」を1つ作る(TypeScript)🧪

ポイントは2つだけ👇
defineSecret()で Secret を定義- 関数定義のオプションで
secrets: [...]を指定(これが “バインド”) (Firebase)
例:HTTP関数(Slackへテスト投稿)
import { onRequest } from "firebase-functions/v2/https";
import { defineSecret } from "firebase-functions/params";
const slackWebhookUrl = defineSecret("SLACK_WEBHOOK_URL");
export const slackTest = onRequest(
{ secrets: [slackWebhookUrl] },
async (req, res) => {
// Secretの値を取り出す(これが “秘密”)
const url = slackWebhookUrl.value();
// Node 20+ なら fetch が使える前提でOK(小さく書ける✨)
const r = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text: "✅ Functionsからテスト投稿できたよ!" }),
});
const text = await r.text();
res.status(200).send({ ok: true, slackResponse: text });
}
);
よくある事故ポイント 🚑

- ❌
console.log(url)しない(ログは漏えい経路になりがち) - ❌ レスポンスに秘密を返さない(デバッグのつもりでやりがち)
- ✅ 使う関数だけに
secretsを付ける(付けない関数だとundefinedになる、が仕様) (Firebase)
3-4) デプロイして動作確認 🧯➡️✅
firebase deploy --only functions:slackTest
叩いてみて、Slackに投稿されれば成功🎉
(レスポンスには slackResponse が返ります)
4) ローカル(Emulator)で秘密を扱う🧪🛡️

Emulatorは、状況によっては本番のSecretを読みに行こうとします。で、権限がないとコケます😵 そこで .secret.local でローカルだけ上書きできる、と公式に書かれています。 (Firebase)
(中身は KEY=VALUE の形で揃えると運用しやすいです👌)
5) AI連携の“鍵”も同じ考え方 🔥🤖

AI系って「APIキーをうっかり貼る事故」が起きやすいんですが、ここでやったのと同じでOKです。
公式ページにも、defineSecret('GOOGLE_API_KEY') を使って Gemini API クライアントを初期化する例が載っています。 (Firebase)
つまり AIほどSecrets必須です🧠✨
6) Gemini CLI / MCPで「手順の抜け」を減らす🛸💻
ターミナルの Gemini CLI にFirebase拡張を入れると、Firebase向けのプロンプトやツール連携(MCP含む)を使えるようになります。インストール手順・/firebase:init や /firebase:deploy みたいな例も公式にあります。 (Firebase)
さらにFirebase CLIのリリースノートには、AIアシスタント連携向けの MCPサーバー起動コマンド追加も書かれています。 (Firebase)
この章でのおすすめ使い方はこれ👇
- 🤖「Secretsを使うときのチェックリスト作って」
- 🤖「このFunctionsコード、秘密がログやレスポンスに混ざってない?」
- 🤖「
secrets: [...]を付け忘れてない?」(付け忘れはマジで多い😇)
7) 寄り道:Python / .NET だとどうなる?🐍🧩
Python(Firebase Functions)
Pythonでも secrets=[...] を指定して、環境変数として読む形が公式にあります。 (Firebase)
Pythonランタイムは 3.10〜3.13(デフォルト3.13) がサポート、と明記されています。 (Firebase)
C#(.NET)はどうする?
FirebaseのFunctions本体はNode/TSが主役なので、C#を“関数ランタイム”でやるなら Cloud Run 側(Cloud Run functions)に置くのが現実的です。 Cloud RunでSecretを環境変数として参照する公式手順もあります。 (Google Cloud Documentation) (.NETランタイム選択の話も公式にまとまってます) (Google Cloud Documentation)
✅ チェック(ここまでできた?)📝
- ✅
SLACK_WEBHOOK_URLをfirebase functions:secrets:setで登録できた (Firebase) - ✅
defineSecret()+secrets: [...]を付けた関数が書けた (Firebase) - ✅ Slackへテスト投稿できた 🔔
- ✅ Secret更新は 再デプロイが必要だと理解できた (Firebase)
- ✅ Emulator用に
.secret.localの存在を知った (Firebase) - ✅
functions.config()は将来詰むので避ける、と腹落ちした (Firebase)
次章(Firestoreイベント)に進むと、**「データが作られた瞬間に自動で動く」**が始まって楽しくなります⚡ その前に、この章の「秘密を守る型」だけはガチで身につけちゃいましょ😊🛡️