クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

APIキーをコードに入れない

このレッスンのあとで: キーを、自分のコードとGitの履歴の外に置ける。

60分のレッスンコマンド3件AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

漏れたAPIキーはお金がかかる

APIキーは、リクエストが自分から来たことを証明する秘密の文字列です。モデルの提供元は、キーのついた呼び出しのたびに、あなたのアカウントへ請求することがよくあります。

開発者は、キーをコードに書き込み、そのままGitに公開して漏らします。自動のスキャナーは、まさにそれを探しています。漏れたキーは、請求とリスクにつながります。

このレッスンのゴール

メモ

キーを、自分のコードとGitの履歴の外に置ける。

キーワード

ことばいみれい
APIキーリクエストが自分のものだと証明する秘密の文字列
環境変数コードの外からプログラムに渡される、名前付きの値MY_API_KEY
.envファイル自分のPC用に NAME=値 の行を並べたテキストファイル
.gitignoreファイルGitに追跡させないファイルの一覧
ローテーション新しいキーを作り、古いキーを無効にすること

学生が入力するセルは、このプレビューでは空白です。

このラボでは、コードにキーがない

スクリプトは authorization: Bearer lab というヘッダーを送ります。lab は仮の値であり、キーではありません。呼び出しが外へ出るとき、プラットフォームがこれを本物のトークンに置き換え、モデルを選びます。

つまり、キーはあなたのコードに入らず、あなたの目にも触れません。本物のプロジェクトでは、キーを自分で守ります。

キーなしでモデルを呼ぶ

コマンド
docker exec -w /home/node/project agent node -e "const u=(process.env.AI_URL||'http://ai:4000')+'/v1/chat/completions';(async()=>{const headers={'content-type':'application/json',authorization:'Bearer lab'};console.log('自分のコードの認証ヘッダー:'+headers.authorization);try{const r=await fetch(u,{method:'POST',headers,body:JSON.stringify({model:'lab',messages:[{role:'user',content:'APIキーをコードに入れてはいけない理由を、一文で答えてください。'}],max_tokens:60})});const j=await r.json();if(r.ok===false)throw new Error(r.status+' '+j.error.message);console.log('モデル:'+j.choices[0].message.content)}catch(e){console.log('応答なし('+e.message+')。記録済みサンプル:');console.log('モデル:コードを読める人は誰でもキーを使えて、あなたのお金を使えてしまうからです。')}})()"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

本物のキーは環境に置く

本物の提供元は、長いキーをくれます。Gitが追跡するファイルに、キーを書き込んではいけません。環境変数に入れて、コードでは process.env.MY_API_KEY で読みます。

自分のPCでは、変数を.envファイルに書き、そのファイルを.gitignoreに入れて、Gitに見せないようにします。

練習用の.envと.gitignoreを書く

コマンド
docker exec -w /home/node/project agent sh -c "mkdir -p demo-keys && printf 'EXAMPLE_API_KEY=not-a-real-key-123\n' > demo-keys/.env && printf '.env\n' > demo-keys/.gitignore"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

.envを読み、値を隠す

コマンド
docker exec -w /home/node/project agent node -e "const fs=require('fs');const nl=String.fromCharCode(10);for(const line of fs.readFileSync('demo-keys/.env','utf8').trim().split(nl)){const i=line.indexOf('=');const v=line.slice(i+1);console.log(line.slice(0,i)+' は設定されています('+v.length+'文字、値は非表示)')}console.log('.env は .gitignore に入っている:'+(fs.readFileSync('demo-keys/.gitignore','utf8').split(nl).includes('.env')?'はい':'いいえ'))"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

本番でも同じ考え方

ホスティングサービスには、秘密を置く場所があります。そこに置いた値は、環境変数としてプログラムに渡されます。コードは、自分のPCでもサーバーでも同じままです。

名前とダミーの値を書いた .env.example を公開しておきましょう。新しい仲間が、何を設定すればよいか分かります。

例:漏れたあとにすること

何が起きたかすること
キーがコードにあるが、コミット前環境変数に移す
コミット済みだが、まだ公開していないキーをローテーションし、コミットを書き換える
公開リポジトリに公開してしまったすぐキーをローテーションし、履歴を掃除する
チャットやプロンプトに貼ってしまったキーをローテーションする

学生が入力するセルは、このプレビューでは空白です。

よくある間違い

注意

新しいコミットでキーを消せば、なくなると考える人が多くいます。しかしGitは古いコミットをすべて残すので、コピーした人にはキーが履歴に残ります。キーはローテーションしましょう。新しいキーだけが、古いキーを使えなくします。

このラボとソースについて: AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。