【Claude Code】ブログ画像の機密情報を自動マスクするスキルを作った
概要
今回はブログ記事のスクリーンショットに写り込む API キーや個人情報を、Claude Code で自動マスクするスキルを作ったので紹介していきます。
ブログでスクショを貼るとき、「このアカウント名まずいかも」「API キー写ってない?」って毎回チェックしますよね(- -;
でも記事が増えるとだんだん雑になって、うっかり公開してしまう事故が怖くなってきます。
そこで、Claude Code のスキルとして呼び出せる自動マスクツールを作りました。
スクショ追加 → 「マスクして」と依頼 → Claude が画像を見て機密領域を特定 → Node ツールがグレー塗り+白フチで描画、という流れです。
それではやっていきましょう!
目次
作ったもの
before / after はこんな感じです。
Python スクリプトに API キーを直書きしたスクショを入力すると、キー文字列だけがグレー塗り+白フチでマスクされる挙動になります。
SERPAPI_KEY = "..." の文字列部分だけが矩形で覆われて、前後の変数名や末尾のコメントはそのまま読める状態になっていますね。
記事の説明に必要な文脈は壊さず、機密文字列だけを隠すのがポイントです(^^b
なぜ作ったか
手動マスクの限界
スクショ貼る系の記事を書いてると、こんな悩みが出てきます。
- 毎回ペイントや Figma で矩形を描くのが地味に面倒
- 記事が増えると抜け漏れチェックが雑になる
- 過去記事の見直しで「これ残ってた…」となりがち
- マスクの色・線の太さが記事ごとにバラつく
人間のチェックに頼る運用は、どこかで必ず事故るというのが個人的な感覚でした。
要件整理
なので最初にざっくり要件を決めました。
- 検出は自動(目視だと結局抜ける)
- 出力は統一感のある見た目(グレー塗り+白フチ)
- 元画像は上書きで置換(バックアップは残さず、原本の機密情報が git に漏れないようにする)
- 記事生成フローに組み込んで「記事を書いたら自動で動く」
設計:Claude Vision と Node で役割分担
悩んだのが「何で機密情報を検出するか」のところでした。
選択肢
- ・OCR(tesseract.js)+ 正規表現で検出
- ・Claude Vision に画像を読ませて領域を返してもらう
最初はOCRで考えてたんですが、「タイトルバーに写ってる個人名」「ブラウザ右上のアカウント表示」みたいに正規表現では判別できないケースが地味に多いんですよね。
GCP 管理画面の右上に出るアカウント表示名とか、テストユーザー画面の自分のメールアドレスとか、文脈で判断するしかない領域があります。
ということで Claude Vision 方式を採用しました。
Claude なら「ここ個人情報っぽい」をセマンティックに判定できるので、OCR + 正規表現より漏れが少ないと考えたためです。
デメリット
Claude Vision の座標精度はピクセル完璧ではありません。
なので多少の位置ズレは許容しなければなりません。。。
構成
役割を Claude とツールで分担しました。
- Claude:画像を視覚的に解析して「ここをマスクする」を JSON で出す頭脳担当
- Node ツール:JSON を受け取ってひたすら矩形を描く手足担当
こうすると、ロジックが単純な Node ツールは壊れにくく、賢さが必要な検出部分は Claude の判断に任せられるので、全体として保守しやすい構造になります(^^
まぁclaude君が必須なのでお金はかかりますが。。。
実装
ファイル構成
dev_Hexo/tool/mask_image/mask_image.js- 本体の Node スクリプト
dev_Hexo/tool/mask_image/README.md- 使い方メモ
.claude/skills/mask-images/SKILL.md- Claude Code 用のスキル定義
Hexo プロジェクト側の dev_Hexo/node_modules に sharp と canvas が既に入っていたので、個別の package.json は作らず親を参照する方式にしました。
ツール本体
sharp でメタデータ取得と保存、canvas で描画するシンプル構成にしています。
設定は JSON で受け取る形式です。
mask_image.js
1 | import sharp from "sharp"; |
もし使用する際は必ず別の場所にバックアップを取ってからやりましょう!!
片道設計にした理由は下に書いてます。
入力 JSON の形式
座標は画像サイズに対する 0〜1 の正規化値で、かつ矩形の「中心」を cx, cy で指定する形式にしています。
こうしておくと、解像度が違う画像でも同じ config が使えるのと、Claude Vision が「このテキストの真ん中はどこ」を素直に書けば、マスクの中心が機密文字列の中心にそのまま乗るメリットがあります。
config.json
1 | { |
Claude スキル化
ここが今回の肝です。
Claude Code のスキル機構を使って、「画像マスクして」と言うだけで自動で動くようにしました。
SKILL.md の役割
.claude/skills/mask-images/SKILL.md には以下を記述しています。
- いつ発動するか(トリガー)
- 処理手順(Read で画像閲覧 → 領域特定 → config 書き出し → ツール実行 → 再 Read で検証)
- 検出対象(メアド、APIキー、OAuth ID、プロジェクトID、個人名、IP、等)
- マスクしないもの(公開ドメイン、UI ラベル、一般ドキュメント URL)
SKILL.md(冒頭フロントマター)
1 |
|
description にトリガーワードを入れておくと、Claude Code が関連する指示を検知してスキルを自動発動してくれます。
「画像マスクして」「機密情報隠して」といった曖昧な依頼でも拾えるように書きました。
記事生成フローへの組み込み
このブログでは dev_Hexo/.github/prompts/article-format.prompt.md に記事作成のルールをまとめているので、ここから mask-images スキルを参照する一文を追加しました。
article-format.prompt.md(追記部分)
1 | # スクリーンショット画像のマスキング |
これで、記事を書く → 画像追加 → 自動的にスキル発動 → マスク済みの状態でコミット、という流れが回るようになりました(^^b
実行フロー
実際の動きはこんな感じです。
- ユーザが「記事書いて」や「この画像マスクして」と依頼
- Claude が対象フォルダの画像を Glob で列挙
- 各画像を Read ツールで閲覧(Vision)
- 機密領域を特定し、正規化座標で JSON 化
node mask_image.js config.jsonを実行- 元画像は上書き(バックアップは作らない/後述)
- Claude が結果画像を再 Read して、網羅できているか検証
片道設計にした理由
実は最初は originals/ サブフォルダに原本を退避する実装にしていたんですが、途中で気がつきました。
git add . してコミットすると、機密情報つきの原本がそのままリポジトリに乗ります。そもそも機密情報を隠したくて作ったツールなのに、横に原本を置いておいたら意味がない、というジレンマです(- -;
なので元画像を直接上書きして復元不可能にする片道設計に切り替えました。
リカバリの代わりに、「実行前に座標を再確認」「実行後に Read で検証」の 2 ステップをスキル定義に明記する運用で安全性を担保しています。
ただし過剰マスクで UI ラベルまで隠してしまった場合はスクショを撮り直すしかないので、バックアップは必須ですね。。。
ハマったところ
Node 22 の ESM 判定
最初に import sharp from "sharp" のような ESM 構文で書いたら、こんな警告が出ました。
警告メッセージ
1 | MODULE_TYPELESS_PACKAGE_JSON Warning: |
Node 22 以降は import 構文から自動で ESM 判定してくれるので動作自体は問題ないんですが、警告が気になる場合は package.json に "type": "module" を追加すれば消えます。
今回は既存ツール(imgae_text)と挙動を揃えるために package.json を作らず、警告は許容する判断にしました。
座標のズレ吸収
Claude Vision で返ってくる座標は、ピクセル単位で完璧ではないです。
特に密なスクショだと数ピクセル外すことが普通にあるので、ツール側で自動的に領域を外側 5% 拡張する処理を入れました。
paddingロジック
1 | const padX = r.w * width * 0.025; |
この 5% は何度か試して決めた値で、端の 1〜2 文字がうっかり露出するのを防げるサイズ感でした。
コメント
最初はパディングを入れず「Claude が返した座標をそのまま信じる」実装にしてたんですが、本記事の before/after 画像を作るときにキー先頭の「ek」が 3px はみ出す事故がありました(- -;
自動化でやる以上、こういう「人間なら見逃さないけどモデルはズレるポイント」は仕組みで吸収するしかないと実感。
締め
今回はブログ画像の機密情報を Claude Code のスキルで自動マスクする仕組みを紹介しました。
ポイントをおさらいすると以下のとおりです。
- Claude Vision で検出、Node ツールで描画と役割分担
- 正規化座標 + 5% パディングで解像度・ズレを吸収
- バックアップなし片道設計で、原本の git 漏洩リスクを根本的に排除
- SKILL.md + article-format.prompt.md の二段構えで記事生成と連動
「セキュリティは仕組みで担保する」と実感できるツールになって、書いてる側のメンタルもかなり楽になりました。
似たようにスクショ多めのブログを運用してる方は、ぜひ参考にしてみてください!
以上!
機密情報は大事にしましょう!
お疲れさまでした。