開発環境・変更管理の準備学習記事全11節Operate
秘密情報を設定から分離し、外部部品の出所と利用条件を確認する
この記事で身につくことパスワード等を設定から分離する理由と、秘密情報をコード・Git・AIへの入力・公開する実行記録のどれにも混ぜないための確認方法、外部部品の出所・更新・利用条件を確認する理由を説明できる。
記事内目次(22項目)
この記事の会社・人物・設定値はすべて架空の設定です。実在する会社や案件とは関係ありません。本文の演習で使う秘密の値
DRILL-FAKE-KEY-0000は架空で、本物の鍵・パスワード・接続先ではありません。実際の秘密情報は一切使用していません。演習はexamples/06-04-secrets-dependencies/直下の使い捨ての置き場で行い、共有先への送信は行っていません(第7節)。
この記事は何の話か。依頼・承認管理アプリの接続先や鍵といった秘密情報を、プログラム本体やその設定から分離して扱う方法と、その秘密情報が「コード」「Git の履歴」「AIへ渡す資料」「公開する実行記録」の4つのどれにも混ざっていないことを確かめる方法、外部から取り込む部品の出所・更新方針を確認する方法を扱う話です。
なぜ必要か。秘密情報をプログラムに直接書き込むと、変更履歴(06-03)やAIへ渡す資料(07-01)、公開する実行記録に紛れ込み、意図せず外部に漏れる危険があります。一度 Git の履歴に入った秘密情報は、そのファイルを消しても履歴に残り続けます。「設定見本が空欄だから安全」だけでは、この4つの混入先のうち1つしか見ていません。
この記事を読むとできるようになること。
- パスワード等を設定から分離する理由と、実際の値をどこに置き、どこに置かないかを説明できる
- 秘密情報がコード・Git・AIへの入力・公開する実行記録に混ざっていないことを、演習コードで確かめ、検査の限界を言える
- 外部部品を使う利点と、更新・供給停止の負担を比較し、依存を減らす判断基準を書ける
読む順路。この記事は3つの深さで読めます。全部を順に読む必要はありません。
- 基本だけ理解する:第1節→第3節(4つの混入先と、実際の値の置き場所)→第4節(判断すること)→第5.1節(設定見本と
.gitignore)→第6節の結果の読み方→第9節。コードを読まなくても、秘密情報をどこに置き、どこに置かないかが分かります。 - 作って確かめる:上に加えて第5.2〜5.3節(演習コード)→第5.4節(演習の設計:実行前に見るもの・失敗したとき・戻せるか・誰が)→第6節の実行結果→第7節(確かめたこと・確かめていないこと)。
- 設計判断を深める:上に加えて第5.5節(依存部品の一覧)→第8節(外部部品の利点と負担、検査の限界、適用限界)。
1. 今回の業務課題と完成するもの
この記事でやることは、依頼・承認管理アプリの接続先や鍵を置く設定見本を、値を空欄にした形で作り、実際の値を置く .env を Git の対象から外し、秘密情報がコード・Git の履歴・AIへ渡す資料・公開する実行記録に混ざっていないことを確かめる手順を作ることです。あわせて、外部から取り込む部品(依存部品)の出所・版・利用条件を一覧にします。
06-03では変更履歴の残し方を扱いましたが、その履歴に秘密情報が紛れ込まないようにする方法はまだ扱っていません。この記事では、それを扱います。
この記事を読み終えると、次のものが手元にできます。
- 設定見本・秘密情報管理ルール(設定項目、値の置き場所、4つの混入先ごとの確認方法、部品一覧)
- 混入確認の演習コードと、その実行記録
2. 前提知識と読む順路
この記事で使う言葉を先に説明します。
秘密情報
一言でいうと、他人に知られてはいけない情報です。たとえば、保存先へ接続するための鍵(パスワードに相当する文字列)です。
設定の分離
一言でいうと、秘密情報をプログラム本体に直接書かず、別の場所(設定ファイルなど)に分けて置くことです。この記事では、項目名だけを書いた「設定見本(.env.example)」と、実際の値を書く「.env」を分けます。
これがないと、プログラム本体を変更履歴やAIへの資料として渡すときに、秘密情報も一緒に含まれてしまいます。
.gitignore
一言でいうと、Git に「このファイルは履歴に入れない」と伝える一覧です。実際の値を書く .env をここに書いておくと、git add しても保存の対象になりません。
依存部品
一言でいうと、自分たちで作らず、外部から取り込んで使うプログラムの部品です。
読む順路:変更履歴の管理は06-03、社内の制約は03-01が該当します。この記事の管理ルールは、07-01(AIに渡す資料を整える)の除外基準、11-01(公開前チェック)の秘密情報の項目で使います。
3. 理解する:なぜ分離し、4つの混入先を確認するか
3.1 秘密情報が混ざる4つの場所と、置いてよい場所
| 場所 | 混ざるとどうなるか | この記事での対策 |
|---|---|---|
コード(app.js など) | 変更履歴・AIへの資料・配置先のすべてに付いて回る | コードは環境変数(process.env.API_KEY)から読み、値を書かない |
| Git の履歴 | ファイルを消しても履歴に残る。共有先へ送ると回収できない | .env を .gitignore に書き、保存の対象にしない。履歴を全文検索して無いことを確かめる |
| AIへ渡す資料 | 外部のサービスに送られ、こちらで消せない | 渡すのは設定見本(値が空欄)だけ。.env は渡さない(07-01) |
| 公開する実行記録(evidence) | 記事・サイトを通じて公開される | 記録を残す前に検査し、値が写っていないことを確かめる |
実際の値を置いてよい場所は、Git の対象外の .env(作業しているパソコンの中だけ)と、この記事の範囲外の安全な置き場所(組織の秘密情報の管理の仕組み。03-01 の制約に従う)です。この記事の演習では、.env にも架空の値しか置きません。
3.2 このリポジトリの .gitignore との一致
演習で使う gitignore.example.txt(第5.1節)の3行は、この教材のリポジトリ本体の .gitignore に実際に書かれている「Environment variables / secrets」の行と同じ内容です。.env と .env.*(.env.local など)を除外し、!.env.example で設定見本だけを除外の例外にしています。
3.3 よくある誤解
「テスト用の値だから、そのままコードに書いてよい」。テスト用であっても、実際の接続先の情報(形式が本物に近いもの)は、意図せず本物と混同される危険があります。この記事の演習でも、コードには値を書かず、.env に置く値も「架空」と分かる文字列にしています。
「.env を消せば、Git から秘密情報は消える」。一度保存(commit)した内容は、ファイルを消しても履歴に残ります。だから「保存する前に除外する」ことが先で、「履歴に無いことを検索で確かめる」ことが後です(第6節の手順2〜3)。
「機械で検査したから混入していない」。第5.3節の検査は決まった書き方(API_KEY=値 など)しか見つけられません。見つからなかった=混入していない、ではなく、目視の確認を置き換えるものではありません(第8.2節)。
「外部の部品は、使えれば出所を気にしなくてよい」。出所や更新方針が不明な部品は、後で使えなくなったり、意図しない動作をしたりする危険があります(第5.5節)。
4. 判断すること
秘密情報と依存部品について人が判断することは、次の5つです。
| 判断すること | なぜ判断が必要か | 仮置きしてよいか | 間違えた場合の影響 |
|---|---|---|---|
| どの項目が秘密情報か | 接続先の文字列、鍵、パスワードは秘密。項目名(API_KEY)は秘密ではない。分けないと、全部を隠すか全部を晒すかになる | 可(項目が増えたら設定見本に追加する) | 秘密でない項目まで隠して作業が止まる、または秘密の項目を見本に書いてしまう |
| 実際の値をどこに置くか | Git の対象外の .env(作業するパソコンの中)か、組織の管理の仕組み(03-01 の制約)。コード・見本・AIへの資料・公開記録には置かない | 不可。「とりあえずコードに」は後で回収できない | 値が履歴・外部サービス・公開物に残る |
| 保存・送信・公開の前に何を確認するか(止める条件) | 設定見本が空欄か、.env が除外されているか、履歴に値が無いか、AIへの資料と公開記録に値・秘密らしい書き方が無いか。1つでも引っかかれば止める | 不可 | 気づかないまま共有先やAIへ送る |
| 検査に何を任せ、何を目視するか | 決まった書き方は演習コードで検査できる。書き方が違う値、画面の写し、ログの断片は目視が要る | 可(検査の書き方は業務に合わせて増やす) | 検査が通ったことを「安全」と誤解する |
| 外部部品を使うか、標準機能で作るか | 部品は手間を減らすが、出所・利用条件・更新・供給停止の確認が要る(第8.1節) | 可(この教材は標準機能だけで進め、必要になった時点で一覧に載せてから採用) | 出所不明の部品に依存し、更新や供給停止で動かなくなる |
勝手に決めてはいけないこと:実際の秘密情報を、この記事の設定見本・本文・演習・実行記録に含めません。演習の値は架空で、そう明記します。03-01でまだ確認していない事項(利用可能なAIサービス、データ持出しの可否)を、この記事で確定しません。検査が通ったことを「混入していないことの保証」と書きません。
AIに任せる範囲:設定見本の項目の洗い出し、検査コードの下書き、検査結果の整理はAIに任せられます。任せてはいけないのは、実際の値をAIに渡すこと(渡した時点で混入です)、「秘密かどうか」の判断、保存・送信・公開してよいかの判断です。
5. 作って確かめる:設定見本・混入確認・部品一覧を作る
5.1 設定見本と .gitignore(正本)
設定見本 env.example.txt(演習では .env.example としてコピーされます。値は空欄):
# 依頼・承認管理アプリ 設定見本(値は空欄。実際の値はこのファイルに書かない)
DB_CONNECTION_STRING=
API_KEY=
.gitignore の正本 gitignore.example.txt(演習では .gitignore としてコピーされます。このリポジトリ本体の .gitignore の該当行と同じ内容):
# Environment variables / secrets
.env
.env.*
!.env.example
5.2 演習の流れ(4つの混入先の確認)
演習コードは、使い捨ての置き場 work/ に次のものを作ってから、4つの確認を順に行います。
| 作るもの | 内容 |
|---|---|
.env.example | 設定見本(値は空欄) |
.gitignore | 上の正本のコピー |
.env | 実際の値を置く場所。演習では架空の値 API_KEY=DRILL-FAKE-KEY-0000 |
app.js | 値を書かず process.env.API_KEY から読むコード |
ai_input/request.md | AIへ渡す資料の例(渡すもの・渡さないものを書いた依頼文。架空) |
evidence_public/run_log.md | 公開する実行記録の例 |
| 手順 | 確認すること | 期待 |
|---|---|---|
| 1 | 設定見本に値が入っていないか | 値が入っている行 0 |
| 2 | git add -A しても .env が保存の対象にならないか。.env.example は対象になるか | 対象は5ファイル、check-ignore が .gitignore:2:.env を返す |
| 3 | 保存(commit)した後、履歴を全文検索して架空の値が無いか | 見つかった保存単位なし |
| 4 | AIへ渡す資料・公開記録・コードに、値そのもの・秘密らしい書き方(API_KEY=値 など)が無いか。.env 自体にはある(検査が働いている確認) | 3ファイルとも 0 件、.env は 2 件 |
5.3 演習コード(check_secrets.js)
演習コードは examples/06-04-secrets-dependencies/ を正本とします。演習用の名前・メールアドレス・日時を固定するので、個人のGit設定は読みません。
// 教材演習用:秘密情報を「コード・Git・AIへの入力・公開する実行記録」へ混ぜないための確認を、
// このフォルダ直下の work/ に作る使い捨ての置き場で実際に行う。
// [1] 設定見本(.env.example)に値が入っていないか
// [2] 実際の値を置く .env が Git の保存対象から除外されているか(.gitignore)
// [3] Git の履歴に秘密の値が入っていないか
// [4] AIへ渡す資料と、公開する実行記録に、秘密の値・秘密らしい書き方が混ざっていないか
// 秘密の値は架空(DRILL-FAKE-KEY-0000。本物ではない)。実際の接続先・鍵は一切使わない。
// Node.js標準機能(node:fs、node:path、node:child_process)のみ。git は work/ の中でだけ使い、共有先は設定しない。
const fs = require("node:fs");
const path = require("node:path");
const { execFileSync } = require("node:child_process");
const WORK = path.join(__dirname, "work");
const FAKE_SECRET = "DRILL-FAKE-KEY-0000"; // 架空の値。本物の鍵ではない
const gitEnv = { ...process.env, GIT_AUTHOR_NAME: "drill", GIT_AUTHOR_EMAIL: "drill@example.invalid", GIT_COMMITTER_NAME: "drill", GIT_COMMITTER_EMAIL: "drill@example.invalid", GIT_AUTHOR_DATE: "2026-09-21T00:00:00+09:00", GIT_COMMITTER_DATE: "2026-09-21T00:00:00+09:00" };
function git(...args) { return execFileSync("git", ["-c", "commit.gpgsign=false", ...args], { cwd: WORK, env: gitEnv, encoding: "utf8" }).trim(); }
// 秘密らしい書き方:KEY=値、password: 値、Bearer 値 など(値が空でないもの)。架空の値そのものも探す
const SECRET_PATTERNS = [
{ name: "架空の秘密の値そのもの", re: new RegExp(FAKE_SECRET) },
{ name: "API_KEY/SECRET/PASSWORD/TOKEN/CONNECTION_STRING に値が入っている", re: /\b(API_KEY|SECRET|PASSWORD|TOKEN|CONNECTION_STRING)\s*[=:]\s*[^\s;]+/ },
{ name: "Bearer トークン", re: /Bearer\s+[A-Za-z0-9._-]{8,}/ },
];
function scan(file) {
const hits = [];
fs.readFileSync(file, "utf8").split("\n").forEach((line, i) => {
for (const p of SECRET_PATTERNS) if (p.re.test(line)) hits.push({ line: i + 1, pattern: p.name });
});
return hits;
}
const results = [];
const record = (check, expected, actual) => { const ok = JSON.stringify(expected) === JSON.stringify(actual); results.push({ check, expected, actual, ok }); console.log(` ${check}: 期待=${JSON.stringify(expected)} 実際=${JSON.stringify(actual)} 判定=${ok ? "一致" : "不一致"}`); };
// 置き場を作る:設定見本、.gitignore、実際の値を置く .env(架空の値)、コード、AIへ渡す資料、公開する実行記録
fs.rmSync(WORK, { recursive: true, force: true });
fs.mkdirSync(path.join(WORK, "ai_input"), { recursive: true });
fs.mkdirSync(path.join(WORK, "evidence_public"), { recursive: true });
fs.copyFileSync(path.join(__dirname, "env.example.txt"), path.join(WORK, ".env.example"));
fs.copyFileSync(path.join(__dirname, "gitignore.example.txt"), path.join(WORK, ".gitignore"));
fs.writeFileSync(path.join(WORK, ".env"), `# 実際の値を置く場所(この演習では架空の値。本物ではない)\nDB_CONNECTION_STRING=\nAPI_KEY=${FAKE_SECRET}\n`);
fs.writeFileSync(path.join(WORK, "app.js"), `// 秘密の値はコードに書かず、環境変数から読む\nconst apiKey = process.env.API_KEY;\nmodule.exports = { apiKey };\n`);
fs.writeFileSync(path.join(WORK, "ai_input", "request.md"), `# AIへの依頼(架空)\n- 渡す資料: app.js、.env.example(値は空欄)\n- 渡さない資料: .env(実際の値)\n`);
fs.writeFileSync(path.join(WORK, "evidence_public", "run_log.md"), `# 実行記録(公開用の例)\n$ node app.js\n(出力なし)\n終了コード: 0\n`);
console.log("手順1:設定見本(.env.example)に値が入っていないか");
const exampleLines = fs.readFileSync(path.join(WORK, ".env.example"), "utf8").split("\n").filter((l) => l.includes("="));
record("設定見本の中で値が入っている行の数", 0, exampleLines.filter((l) => l.split("=")[1] && l.split("=")[1].trim() !== "").length);
console.log("手順2:実際の値を置く .env が Git の保存対象から除外されているか");
git("init", "-q", "-b", "main");
git("add", "-A");
const staged = git("diff", "--cached", "--name-only").split("\n").filter(Boolean).sort();
record("保存の対象になったファイル", [".env.example", ".gitignore", "ai_input/request.md", "app.js", "evidence_public/run_log.md"], staged);
record(".env が除外されている(check-ignore の結果)", ".gitignore:2:.env\t.env", git("check-ignore", "-v", ".env"));
record(".env.example は除外されない(保存の対象に含まれる)", true, staged.includes(".env.example"));
console.log("手順3:Git の履歴に秘密の値が入っていないか(保存してから履歴の中身を全文検索する)");
git("commit", "-q", "-m", "設定見本とコードを保存(秘密の値は含めない)");
let historyHits = "";
try { historyHits = git("log", "--all", "-p", "-S", FAKE_SECRET, "--oneline"); } catch (e) { historyHits = "(検索エラー)"; }
record("履歴の中で架空の秘密の値が見つかった保存単位", "", historyHits);
console.log("手順4:AIへ渡す資料と、公開する実行記録に、秘密の値・秘密らしい書き方が混ざっていないか");
for (const f of ["ai_input/request.md", "evidence_public/run_log.md", "app.js"]) record(`${f} の検出件数`, 0, scan(path.join(WORK, f)).length);
console.log(" 参考:.env 自体を同じ検査にかけると検出される(検査が働いていることの確認)");
record(".env の検出件数", 2, scan(path.join(WORK, ".env")).length);
console.log("");
const allOk = results.every((r) => r.ok);
console.log(allOk ? `結論:設定見本は空欄、.env は Git の対象外、履歴に秘密の値なし、AIへ渡す資料と公開記録にも混入なし(${results.length} 件すべて一致)` : "結論:不一致がある。混入の可能性を確認する");
process.exit(allOk ? 0 : 1);
5.4 演習の設計
| 項目 | 内容 |
|---|---|
| 何のための操作か | 秘密情報の4つの混入先(コード・Git・AIへの入力・公開記録)を、それぞれ機械的に確認する手順を一度通しで行い、「設定見本が空欄」だけでは足りないことを確かめる |
| 実行前に見るもの | 今いる場所が examples/06-04-secrets-dependencies/ か。node -v・git --version が動くか(06-01)。work/ があれば消して作り直される |
| コマンド | node check_secrets.js |
| 期待結果 | 9件すべて「一致」、終了コード0 |
| 結果の読み方 | 手順2の「保存の対象になったファイル」に .env が無いか。手順3が空文字(履歴に無い)か。手順4で .env だけが検出され、他の3ファイルは0件か |
| 失敗したとき | 手順2で .env が対象に入る→ .gitignore の内容を確認する。手順3で保存単位が見つかる→ その履歴は共有先へ送らず、値を無効化(再発行)してから履歴を扱う。手順4で0件でないファイルがある→ 該当行を目視し、値なら削除・再発行、書き方だけなら書き換える |
| 元に戻せるか | 作るのは work/ の中だけ。work/ を消せば元どおり。このリポジトリ本体の履歴には触れない |
| 業務運用では誰が実施/判断するか | 実施:開発担当。秘密かどうか・置き場所・公開可否の判断:運用管理者と03-01の制約の担当(架空)。この演習ではすべて Claude Code |
5.5 依存部品の一覧(例)
この記事の教材演習ではNode.jsの標準機能のみを使い、外部の依存部品は追加していません。実際の開発で外部部品を使う場合の一覧の形は次のとおりです。
| 部品名 | 出所 | 版 | 利用条件 | 更新方針 |
|---|---|---|---|---|
| (例)外部のワークフロー部品 | 公式の配布元(架空) | 未確定(03-03で選定) | 利用規約の確認が必要(未確認) | 更新の頻度・方法は03-03の選定後に決める |
6. 実行結果(混入確認の実測)
examples/06-04-secrets-dependencies/ で実行した stdout です(整形・省略なし。stderr への出力はありませんでした)。
$ node check_secrets.js
手順1:設定見本(.env.example)に値が入っていないか
設定見本の中で値が入っている行の数: 期待=0 実際=0 判定=一致
手順2:実際の値を置く .env が Git の保存対象から除外されているか
保存の対象になったファイル: 期待=[".env.example",".gitignore","ai_input/request.md","app.js","evidence_public/run_log.md"] 実際=[".env.example",".gitignore","ai_input/request.md","app.js","evidence_public/run_log.md"] 判定=一致
.env が除外されている(check-ignore の結果): 期待=".gitignore:2:.env\t.env" 実際=".gitignore:2:.env\t.env" 判定=一致
.env.example は除外されない(保存の対象に含まれる): 期待=true 実際=true 判定=一致
手順3:Git の履歴に秘密の値が入っていないか(保存してから履歴の中身を全文検索する)
履歴の中で架空の秘密の値が見つかった保存単位: 期待="" 実際="" 判定=一致
手順4:AIへ渡す資料と、公開する実行記録に、秘密の値・秘密らしい書き方が混ざっていないか
ai_input/request.md の検出件数: 期待=0 実際=0 判定=一致
evidence_public/run_log.md の検出件数: 期待=0 実際=0 判定=一致
app.js の検出件数: 期待=0 実際=0 判定=一致
参考:.env 自体を同じ検査にかけると検出される(検査が働いていることの確認)
.env の検出件数: 期待=2 実際=2 判定=一致
結論:設定見本は空欄、.env は Git の対象外、履歴に秘密の値なし、AIへ渡す資料と公開記録にも混入なし(9 件すべて一致)
終了コード: 0
読み方:手順2で git add -A を実行しても、保存の対象は .env.example・.gitignore・ai_input/request.md・app.js・evidence_public/run_log.md の5つで、.env は入っていません。check-ignore の結果 .gitignore:2:.env は「.gitignore の2行目の .env という規則で除外された」という意味です。手順3では、保存した後に履歴を全文検索しても架空の値は見つかりません(空文字)。手順4では、AIへ渡す資料・公開記録・コードは0件で、.env だけが2件(値そのものと API_KEY=値 の書き方)検出されており、検査が働いていることが分かります。
7. 確認結果
実行環境:macOS 26.6.2、Node.js v24.18.0(node:fs・node:path・node:child_process)、git 2.54.0 (Apple Git-157)、2026-09-21に実行。実行場所は examples/06-04-secrets-dependencies/。操作したのは work/ の中の使い捨ての置き場だけで、共有先への送信は行っていません。秘密の値は架空です。stdout・stderr・終了コードは evidence_public/phase5b2c2-2026-09-21/06-04/run_log.md に整形なしで記録し、同じコマンドを2回実行して stdout が同一であることを確認しています。
完了条件との照合:
| 完了条件 | 期待 | 実測 | 判定 |
|---|---|---|---|
| 設定見本に実際の秘密情報が含まれていない | 値が入っている行 0 | 0 | 一致 |
実際の値を置く .env が Git の対象外 | 保存の対象に .env が無く、check-ignore が規則を返す | 対象5ファイルに .env なし、.gitignore:2:.env | 一致 |
| Git の履歴に秘密の値が無い | 検索結果なし | 空文字 | 一致 |
| AIへ渡す資料・公開記録・コードに混入が無い | 3ファイル 0 件 | 0・0・0 | 一致 |
| 検査が働いている | .env で検出される | 2 件 | 一致 |
.gitignore の説明が正本と一致 | 演習の正本=リポジトリ本体の該当行 | 同じ3行 | 一致 |
| 依存部品の一覧に出所と利用条件がある | 第5.5節 | 記載あり(例) | 一致 |
この記事で確かめたこと:架空の値を使って、4つの混入先の確認が機械的に行えること。.gitignore の除外が実際に働くこと。履歴の全文検索で無いことが確かめられること。
この記事で確かめていないこと:
| 範囲 | 理由 | どこで確かめるか |
|---|---|---|
| 実際の秘密の値の管理(発行・保管・再発行) | 架空の値のみ。組織の管理の仕組みは03-01の制約が未確認 | 03-01の確認後、実際の環境で |
| 決まった書き方以外の混入(画面の写し、ログの断片、別名の項目) | 検査は決まった書き方だけ(第8.2節) | 保存・送信・公開のたびに目視 |
| 一度履歴に入ってしまった値の除去 | 演習では入れていない | 入った場合は値を再発行し、履歴の扱いは共有先の管理者と決める |
| 実際に外部部品を追加する場合の出所・利用条件の確認 | この教材は標準機能のみ | 部品を採用する時点で第5.5節の一覧に載せる |
残る制限:この記事の本文と演習コードはClaude Codeが作成したもので、業務担当者による内容確認は行っていません。
8. 設計を判断する
8.1 外部部品を使う利点と依存の負担を比較する
| 選択肢 | 利点 | 負担 |
|---|---|---|
| 外部部品を使う | 自分たちで作る手間を減らせる | 更新への追従、利用条件の確認、供給停止時の対応が必要になる |
| Node.jsの標準機能だけで作る(この記事の演習で採用) | 外部への依存が少なく、更新の追従が不要 | 標準機能でできることの範囲に限られる |
この教材演習の範囲では、Node.jsの標準機能だけで十分に確認できるため、外部部品を追加しない方針を採用しています。実際の開発(08以降)で外部部品が必要になった場合は、第5.5節の一覧に出所・利用条件を記載してから採用します。
8.2 機械の検査と目視の分担
| 方法 | 見つけられるもの | 見つけられないもの |
|---|---|---|
| 機械の検査(この記事の演習) | 決まった書き方(API_KEY=値、Bearer …、既知の値そのもの) | 書き方が違う値、画面の写しに写った値、別名の項目、値が分割されている場合 |
| 目視 | 文脈から「これは秘密だ」と分かるもの | 大量の記録の中の見落とし |
保存・送信・公開のたびに機械の検査を通し、そのうえで目視する、という二重の確認にします。検査が通ったことを「安全」の根拠にしません。
8.3 適用限界
この記事の設定見本・部品一覧は、架空企業「みらい業務サービス」の小規模な開発を前提にした一例です。実際に外部サービス・部品を利用する場合は、03-01の未確認の制約(利用可能なAI、データ持出し)を確認したうえで判断する必要があります。演習は使い捨ての置き場で行っており、実際のリポジトリでは作業フォルダそのものが対象になります。
9. 持ち帰る成果物
| 成果物 | 空欄版 | 記入例 |
|---|---|---|
| 設定見本・秘密情報管理ルールひな形(設定項目、値の置き場所、4つの混入先ごとの確認方法、部品一覧) | templates/06-04-secrets-dependencies_template.md | templates/06-04-secrets-dependencies_example.md |
混入確認の演習コードと正本(設定見本、.gitignore) | examples/06-04-secrets-dependencies/(check_secrets.js、env.example.txt、gitignore.example.txt) | 同上 |
| 実行記録(stdout・stderr・終了コード、整形なし) | — | evidence_public/phase5b2c2-2026-09-21/06-04/run_log.md |
自分の業務に使うときの手順は次のとおりです。
- 前工程(変更管理ルール、制約一覧)を用意する
- 秘密情報が必要な設定項目を洗い出し、値を空欄にした設定見本を作る
- 実際の値を置く場所(Git の対象外の
.envか組織の管理の仕組み)を決め、.gitignoreで除外する - 保存・送信・公開の前に、設定見本・Git の対象・履歴・AIへの資料・公開記録の4つを確認し、目視も行う
- 使用する外部部品があれば、出所・版・利用条件・更新方針を一覧にする
10. 次工程への受渡し
次へ渡すもの:設定見本・秘密情報管理ルール、依存部品の一覧、混入確認の実行記録。
次工程での使われ方:07-01(AIに渡す資料を整える)では、この管理ルールを資料の除外基準にし、.env を渡さないことを前提にします。11-01(公開前チェック)では、この設定見本と確認手順を秘密情報の項目に使います。
前工程へ戻る条件:この管理ルールが06-03の変更管理ルールと食い違う場合は、06-03に戻って確認します。利用可能なAI・データ持出しの制約が変わった場合は、03-01に戻ります。
11. 根拠と更新情報
- この記事の会社・人物・設定値はすべて架空の設定です。演習の秘密の値
DRILL-FAKE-KEY-0000は架空です。 - 秘密情報を設定から分離するという考え方、および外部部品の利用条件を確認する必要性は、一般的なシステム開発の安全対策の考え方に基づく説明であり、特定の製品・サービスを前提にしていません。
.gitignoreの正本は、このリポジトリ本体の.gitignoreの「Environment variables / secrets」の行と同じ内容です。- 制作の来歴:本文はClaude Codeが作成しました。第5.3節・第6節の演習コードは
examples/06-04-secrets-dependencies/を正本とし、2026-09-21にmacOS 26.6.2・Node.js v24.18.0・git 2.54.0の環境で実際に実行し、stdout・stderr・終了コードをevidence_public/phase5b2c2-2026-09-21/06-04/run_log.mdに記録しています。人(ユーザー)による実読・内容確認は未実施です。 - 2026-09-21(Phase 5B-2C2):初版は「設定見本に値が入っていない」ことを1つのコマンドで確かめるだけで、Git の履歴・AIへの入力・公開する実行記録への混入と、実際の値の置き場所を扱っていなかった。本更新で、4つの混入先ごとの確認を演習コードにし、
.gitignoreの除外・履歴の全文検索・資料と記録の検査を実測に置き換え、機械の検査の限界と目視の分担を第8.2節に明記した。 - 未確認事項:実際の秘密の値の管理、決まった書き方以外の混入、履歴に入ってしまった値の除去、実際に外部部品を追加する場合の出所・利用条件の確認は、この記事の時点では行っていません。
