複数PCへ設定ファイルを自動配布する仕組みの設計と落とし穴
APIキーや通知先を全PCへ配り続ける仕組みの作り方。既存ファイルがあると更新が永久に届かない罠、秘密ローテーションで全台ロックアウトする事故、設定コピーによるPC識別の混同を、実装コードと検証手順つきで潰す。
約3.7万トークンの節約 (API料金換算で約55円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「複数PCへ設定ファイルを自動配布する仕組みの設計と落とし穴」は、業務自動化カテゴリのAI指示書(MDファイル)です。APIキーや通知先を全PCへ配り続ける仕組みの作り方。既存ファイルがあると更新が永久に届かない罠、秘密ローテーションで全台ロックアウトする事故、設定コピーによるPC識別の混同を、実装コードと検証手順つきで潰す。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.7万トークン(API料金換算で約55円)・88%のトークンを節約できます。
- カテゴリ
- 業務自動化
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約4.2万トークン
- この巻物使用時
- 約5,200トークン
- 節約量
- 約3.7万トークン (約55円)
- 更新日
- 2026-08-27
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/md-62e05c9e/raw を読み込んで、この指示書どおりに実装して"
中身
複数PCへ設定ファイルを自動配布する仕組みの設計と落とし穴
社内の複数PCへ APIキーや通知先などの設定ファイルを配り、以後は人手を介さず更新し続けるための設計。 実運用で踏んだ「静かに壊れる」失敗を先に潰す形で書いてある。
前提の構成
- 配布サーバ:
POST /api/keysが{ files: { "<ファイル名>": "<中身>" } }を返す - 認証: 各PCが持つ共有秘密で
HMAC-SHA256(秘密, unixtime)を送る(時刻ずれ±300秒・timingSafeEqual) - クライアント: 各PCの常駐スクリプトが日次で取得し
~/<設定ディレクトリ>/へ書く
落とし穴 1: 「既存ファイルはスキップ」は値の差し替えを永久に届かなくする
最初の実装はこうなりがち。
if (fs.existsSync(destination)) continue; // ← これが罠
fs.writeFileSync(destination, contents, { flag: 'wx', mode: 0o600 });
新規PCには配れるが、既に配布済みのPCには二度と新しい値が届かない。しかもエラーも出ないので 数日〜数週間気付かない。通知先を差し替えた・キーをローテーションした瞬間に全台が古い値で動き続ける。
対策: キー単位のマージ更新にする
ファイル全体を上書きすると、PC固有の値(そのPCの表示名など)まで潰れる。キー単位で merge する。
export const PRESERVE_LOCAL_KEYS = new Set(['<PC固有キー>']);
export function mergeEnvFile(existingText, incomingText, preserveKeys = PRESERVE_LOCAL_KEYS) {
const incoming = parseEnvText(incomingText);
const existing = parseEnvText(existingText);
const handled = new Set();
const lines = existingText.split(/\r?\n/).map((line) => {
const m = line.match(/^(\s*(?:export\s+)?)([A-Za-z_][A-Za-z0-9_]*)(\s*=\s*)(.*)$/);
if (!m || !Object.prototype.hasOwnProperty.call(incoming, m[2])) return line; // コメント行は素通り
handled.add(m[2]);
if (preserveKeys.has(m[2]) || existing[m[2]] === incoming[m[2]]) return line;
return `${m[1]}${m[2]}${m[3]}${incoming[m[2]]}`;
});
const additions = Object.keys(incoming).filter((k) => !handled.has(k)).map((k) => `${k}=${incoming[k]}`);
return [...lines, ...additions].join('\n'); // 行順・コメントを保つ
}
要件は4つ。配布キーは更新する / ローカル専用キーは消さない / PC固有キーはローカル優先 / 実質変化が無いときは書き込まない(毎回 "updated" ログが出るとノイズで本当の更新が埋もれる)。
落とし穴 2: 「配っているはず」を確認せずに原因を追うと丸ごとズレる
「値が届かない」障害で、クライアント側のコードだけ見て原因を探すと外す。 サーバが実際にそのファイルを配っているかを先に実測すること。 実例では、クライアントのコードにファイル名が出てくるので配布対象だと思い込んでいたが、 そこは配布ではなく旧認証のフォールバック読み取りで、サーバは一度も配っていなかった。
確認は、値を出さずファイル名と生死だけ出す使い捨てスクリプトで足りる。
const ts = Math.floor(Date.now() / 1000).toString();
const auth = crypto.createHmac('sha256', secret).update(ts).digest('hex');
const r = await fetch(url, { method: 'POST', headers: { 'x-ts': ts, 'x-auth': auth } });
const payload = await r.json();
console.log('配布ファイル:', Object.keys(payload.files).join(', ')); // ← 中身は絶対に出さない
落とし穴 3: 秘密のローテーションが全台を恒久ロックアウトする
落とし穴1と組み合わさると事故になる。サーバ側の共有秘密を張り替えた瞬間、 クライアントは古い秘密で叩き続け、新しい秘密を受け取る手段が「配布」しかないのに配布が届かない。 自己回復不能になる。
ローテーション前に必ず順に確認する。
- クライアントは秘密ファイルを上書き更新できるか(落とし穴1が潰れているか)
- 旧秘密を
LEGACYとして一時的に受理する口があるか(複数本を受け付ける) - 切替後、旧秘密で叩いて401・新秘密で叩いて200を実際にHTTPで確認したか
ステータス表示("認証経路: primary")はどのファイルを読んだかを示すだけで、 その中身が現行かは何も保証しない。表示を完了判定に使わない。
落とし穴 4: 設定ファイルのコピーでPCの識別が混ざる
セットアップ時に他PCの設定ファイルをコピーすると、そのPCは他機の名前を名乗り続ける。 集計が別PCへ混ざり、しかも本人も管理者も気付かない。
対策: 名前を「刻んだ機体」に紐付ける
export function resolveReporterLabel({ envText, hostname }) {
const env = parseEnvText(envText);
if (env.HOST_BINDING && env.HOST_BINDING !== hostname) {
// 他機からコピーされた設定。自機名へ戻す
let next = upsertEnvValue(envText, 'HOST_BINDING', hostname);
next = upsertEnvValue(next, 'LABEL', hostname);
return { label: hostname, nextEnvText: next, reason: 'copied-from-other-host' };
}
if (!env.HOST_BINDING) {
// 初回。既存ラベルを尊重して刻印だけ追加する(既存PCの表示名を壊さない)
return { label: env.LABEL || hostname, nextEnvText: upsertEnvValue(envText, 'HOST_BINDING', hostname), reason: 'adopted' };
}
return { label: env.LABEL || hostname, nextEnvText: envText, reason: 'ok' };
}
注意点が3つ。
HOST_BINDINGを配布対象から外す(PC固有の判定基準なので配布値で上書きされてはいけない)- 全呼び出し側が同じ hostname 取得方法を使う。片方が
os.hostname()、片方が Windows のCOMPUTERNAMEだと、両者が互いを「コピー」と判定して毎回名前を書き換え合う(無限フリップフロップ) - 自動修正したときは通知に1行出す。名前が黙って変わると別の混乱になる
- 限界: 刻印前にコピーされたファイルは初回に現ラベルを「正」として採用するので遡って直らない。 通知に hostname を併記しておけば、同一ラベルが別 hostname から届いたときに中央側で検出できる
落とし穴 5: env の末尾改行を落とすと後続の追記が行を壊す
キーを追記するヘルパで末尾改行を落とすと、後から別ツールが1行足したときに
LAST=v と NEXT=w が同じ行に連結して設定ファイルが壊れる。
const endsWithNewline = source.endsWith('\n') || source.endsWith('\r');
const separator = endsWithNewline ? '' : newline;
return `${source}${separator}${replacement}${endsWithNewline ? newline : ''}`;
検証は「本番同等の偽ホーム」で行う
単体テストだけでは配布経路は守れない。環境変数でホームディレクトリを差し替えられるようにしておき、 壊れた状態を再現した偽ホームに対して本物のスクリプトを実行する。
HOME_OVERRIDE=/tmp/fakehome node tools/sync.mjs # 1回目: 期待する更新が出るか
HOME_OVERRIDE=/tmp/fakehome node tools/sync.mjs # 2回目: 書き込みが起きない(冪等)か
rm -rf /tmp/fakehome # 実鍵が降りてくるので必ず破棄する
確認するのは3点。壊れた値が直るか / PC固有の値と無関係なキーが保持されるか / 2回目で書き込みが無いか。
チェックリスト
- 既存ファイルでも配布キーが更新されるか(新規PCだけで試して満足しない)
- PC固有キーは保持されるか
- サーバが実際にそのファイルを配っているか(ファイル名一覧を実測)
- 秘密ローテーション時、旧秘密で401・新秘密で200を実測したか
- 失敗は人の見える場所へ出るか(ログファイルだけだと数日誰も気付かない)
- 偽ホームでの冪等性テストがあるか
- 配布物の取得先はコミットSHAで固定していないか(固定すると改修のたびに全員へ貼り替え依頼が出る)
よくある質問
+「複数PCへ設定ファイルを自動配布する仕組みの設計と落とし穴」とは何ですか?
APIキーや通知先を全PCへ配り続ける仕組みの作り方。既存ファイルがあると更新が永久に届かない罠、秘密ローテーションで全台ロックアウトする事故、設定コピーによるPC識別の混同を、実装コードと検証手順つきで潰す。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約4.2万トークンかかりますが、この巻物を使えば約5,200トークンで済みます。差し引き約3.7万トークン(API料金換算で約55円)・88%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
Google Meet 自動参加&動画配信Bot 開発指示書
指定した時刻に Google Meet へ自動参加し、動画を再生しながら画面共有する Bot を、Claude Code に一発で作らせる開発指示 MD。朝会の定例動画配信・ウェビナーの自動放送に。
受信メール添付を案件フォルダへ自動取込するパイプライン
メールを読むアプリとドライブに書くアプリが別、という現実的な構成で顧客メールの添付を案件フォルダへ無人保存する設計。権限追加を避ける理由、実行時間制限下の予算3本立て、二重の重複防止、base64url/行数上限/変換判定などの実装罠、案件と顧客のマッチング、名寄せは候補提示+人の承認にする型まで。
Gmail 自動仕分け&返信ドラフト生成MD
受信メールを AI が分類 (要返信/情報/営業/スパム) してラベル付けし、要返信メールには返信ドラフトまで自動生成する仕組みを作らせる指示書。DWD (ドメイン全体委任) 設定手順込み。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア