Mini Shai-Huludの話を「npmのサプライチェーン怖い」で終わらせると、たぶん見落とします。
面白いというと語弊がありますが、今回の嫌なところはdependencyだけではありません。AI coding agentが読む設定、agentが実行するコマンド、VS Codeのtask、そういう「開発環境の補助ファイル」にまで攻撃面が伸びているところです。
これからのrepo reviewでは、package.json とlockfileだけ見ていても足りない。
.claude/、.cursor/、.vscode/、AGENTS.md、CLAUDE.md。このへんは単なるメモではなく、agentやeditorが実際に動くための設定資産として扱った方がいいです。
npm install の外側にも実行面がある
フロントエンドのセキュリティレビューでは、だいたい最初にここを見ます。
package.json
pnpm-lock.yaml / package-lock.json / yarn.lock
postinstall
prepare
GitHub Actions
これは今でも大事です。新しいpackageが増えたら、名前、maintainer、publish時刻、install script、lockfile diffは見るべきです。
ただ、AI agentを日常運用に入れると、もう一段増えます。
.claude/settings.json
.claude/commands/
.cursor/rules/
AGENTS.md
CLAUDE.md
.vscode/tasks.json
.vscode/settings.json
ここに書かれた内容は、人間が読むREADMEより強い場合があります。agentが毎回読む。editorがコマンドを実行する。workspace単位で権限や挙動が変わる。
つまり、攻撃者から見ると「dependencyを入れる」以外にも、開発者の手元で何かを実行させる入口が増えています。
agentが触るrepoでは、設定ファイルがコードに近づく
たとえば、PRにこういう変更が入ったとします。
+ .claude/settings.json
+ .claude/commands/release.md
+ .vscode/tasks.json
package.json
pnpm-lock.yaml
以前なら「開発環境の便利設定かな」で流していたかもしれません。
でもAI coding agent前提だと、これはかなり強い差分です。
.claude/commands/ にあるコマンドは、agentにとって再利用しやすい実行単位になります。AGENTS.md や CLAUDE.md はrepo内での振る舞いを変えます。.vscode/tasks.json は、開発者が何気なく実行するtaskを定義します。
極端な話、次のような変更は普通にレビュー対象です。
{
"version": "2.0.0",
"tasks": [
{
"label": "dev",
"type": "shell",
"command": "pnpm install && pnpm dev"
}
]
}
これだけなら見慣れた内容です。
でも、command が長くなったり、外部URLからscriptを取ってきたり、環境変数をdumpしたり、postinstall と組み合わさったりすると、急に話が変わります。
AI agentが生成した差分は、見た目が妙に自然です。だからこそ、設定ファイルを「コードではないから軽く見る」運用は危ないと思っています。
package hallucinationは笑い話ではなく入口になる
LLMが存在しないpackage名を提案する問題は、以前からありました。
昔は「また変なpackage名を作ってる」くらいの笑い話に見えたかもしれません。今は少し違います。agentにdependency追加まで任せるなら、存在しないpackage名や紛らわしいpackage名は、そのままslopsquattingやtyposquattingの入口になります。
たとえばagentがこう提案したとします。
pnpm add react-image-resizer-pro
本当に存在するのか。いつpublishされたのか。maintainerは誰か。急にdownloadが伸びていないか。似た名前の有名packageと紛らわしくないか。
この確認を毎回人間が手でやるのは続きません。なので、自分ならdependency追加を含むPRには、最低限このくらいの確認を固定で入れます。
npm view react-image-resizer-pro \
name version time maintainers repository dist.tarball
npm view react-image-resizer-pro scripts
pnpmを使っていても、metadata確認は npm view が手軽です。
もちろんこれだけで安全にはなりません。ただ、「agentが入れたpackageを雰囲気で通す」よりはかなりましです。
まず差分の入口をCIで拾う
全部をCIで判定しようとすると破綻します。設定ファイルの意味やagent instructionの妥当性は、最終的には人間が読まないと分からない。
ただし、「危ない種類の差分が入った」ことは機械的に拾えます。
たとえばGitHub Actionsなら、まずは対象ファイルの変更を検出するだけでも役に立ちます。
name: agent-surface-check
on:
pull_request:
jobs:
detect-agent-surface:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect agent/editor/security-sensitive files
run: |
git diff --name-only origin/main...HEAD \
| rg '(^package.json$|lock$|lock\\.yaml$|^\\.claude/|^\\.cursor/|^\\.vscode/|AGENTS\\.md|CLAUDE\\.md|\\.github/workflows/)'
これだけだと落ちません。まずはPR上で見えるようにするだけです。
もう少し強くするなら、ラベルやPR本文のチェックリストと組み合わせます。
- name: Require manual review note
run: |
changed="$(git diff --name-only origin/main...HEAD \
| rg '(^package.json$|lock$|lock\\.yaml$|^\\.claude/|^\\.cursor/|^\\.vscode/|AGENTS\\.md|CLAUDE\\.md)' || true)"
if [ -n "$changed" ]; then
echo "Security-sensitive development-surface files changed:"
echo "$changed"
echo "Add a reviewer note for dependency / agent / editor config changes."
exit 1
fi
実際の運用では、CODEOWNERSやlabel、Danger、GitHub Actionsのコメント投稿と組み合わせた方が使いやすいです。いきなり全PRを落とすと嫌われます。
でも方向性はこれです。
「全部読む」ではなく、「読むべき差分を見逃さない」。
PR templateに入れるなら、このくらいでいい
agentを使うrepoでは、PR templateに短いチェックリストを入れておくのが一番効きます。
長いセキュリティ規約より、レビュー時に目に入る5行の方が強いです。
## Agent / dependency review
- [ ] 新しいnpm packageを追加していない
- [ ] lockfile diffは意図したdependency追加だけ
- [ ] `postinstall` / `prepare` / npm scriptsを増やしていない
- [ ] `.claude/` / `.cursor/` / `.vscode/` / `AGENTS.md` / `CLAUDE.md` を変更していない
- [ ] agentやeditorから実行できる新しいshell commandを増やしていない
変更している場合は、チェックを外すのではなく説明を書かせます。
## Agent / dependency review note
- added package: `@example/foo`
- reason: existing implementation duplicated parser logic
- checked:
- `npm view @example/foo time maintainers repository`
- lockfile diff
- no install scripts
- agent/editor config changes: none
ここで大事なのは、AIに完璧な判断をさせることではありません。人間が見るべき情報をPRに残すことです。
agentに実装を任せても、review boundaryまでagent任せにしない。
人間が読むものと、機械で止めるものを分ける
自分なら、機械で止めたいものはこのあたりです。
- lockfileが変わったのにdependency追加の説明がない
-
postinstallやprepareが追加された -
.vscode/tasks.jsonに新しいshell commandが増えた -
.claude/commands/や.cursor/rules/が変わった - secretっぽい文字列が追加された
- workflowのpermissionが広がった
逆に、人間が読むべきものもあります。
-
AGENTS.mdやCLAUDE.mdの指示内容 - agentに許可するコマンドの粒度
- dependency追加の必要性
- sandboxやnetwork accessを広げる理由
- 「便利だから」で入ってきたeditor taskの妥当性
ここを混ぜるとつらいです。
CIで文章の意味まで判定しようとすると、だいたい変なルールになります。一方で、人間に「毎回全部注意して読んでください」と言っても続きません。
機械は入口を拾う。人間は意味を読む。
この分担に寄せた方が、agent運用は長持ちします。
sandboxの話はprompt安全論ではない
Codexのsandbox設計の記事を読んでいても、同じ方向を感じます。
agent safetyは「モデルに悪いことをさせないpromptを書く」だけの話ではありません。workspaceのどこに書けるのか。networkへ出られるのか。子プロセスをどう扱うのか。OSの境界で何を止めるのか。
この視点で見ると、Codex、Claude Code、Cursorの比較も少し変わります。
単に「どれが賢いか」ではなく、次を見た方が実務的です。
- permission modelは分かりやすいか
- 実行前にコマンドを確認できるか
- workspace外へのwriteを止められるか
- network accessを制御できるか
- agent用のrepo instructionをレビューできる形で置けるか
- 生成されたdiffをCIとPR reviewに自然に流せるか
モデル性能はもちろん大事です。でも、強いagentほど危ない差分も自然に作れます。
「賢いから安全」ではなく、「賢いから境界が必要」と考えた方がいいです。
ローカルでまず見るコマンド
自分がPRを見るなら、最初にこのへんを叩きます。
# 触ったファイルをざっと見る
git diff --name-only origin/main...HEAD
# dependencyとagent/editor configだけ抜く
git diff --name-only origin/main...HEAD \
| rg '(^package.json$|pnpm-lock.yaml|package-lock.json|yarn.lock|^\\.claude/|^\\.cursor/|^\\.vscode/|AGENTS\\.md|CLAUDE\\.md)'
# scriptsの変更を見る
git diff origin/main...HEAD -- package.json \
| rg 'scripts|postinstall|prepare|preinstall|install'
# VS Code taskのcommandだけ見る
git diff origin/main...HEAD -- .vscode/tasks.json \
| rg 'command|args|dependsOn|label'
新しいpackageがあるならmetadataを見ます。
npm view <package-name> name version time maintainers repository
npm view <package-name> scripts
余裕があればOSVやOpenSSF Scorecardも見る。ただ、最初から完璧な仕組みにしようとすると導入されません。まずは「変な差分を見逃さない」ところから始めた方がいいです。
agentを止めるためではなく、安心して使うためにやる
ここまで書くと、AI coding agentに厳しすぎるように見えるかもしれません。
でも、逆です。
agentを実務で使うなら、毎回「大丈夫かな」と祈る運用をやめたい。dependency updateも、小さい修正も、設定変更も、任せられるものは任せたい。そのために、危ない差分を見つける線をrepo側に置く。
AI agent時代のレビューは、コードの正しさだけでは足りません。
- 何を実行できるようになったか
- どのdependencyが増えたか
- どの設定がagentの振る舞いを変えたか
- どの境界が広がったか
この4つを見落とさないようにするだけで、かなり現実的になります。
.claude/ と .vscode/ は、もう「各自の開発環境」だけの話ではありません。agentが読むなら、editorが実行するなら、CIと同じくらいレビュー対象にした方がいい。
AIが賢いかどうかより、AIが触った危ない差分を見逃さないか。
実務では、こっちの方が効く場面が増えていくと思います。