AIに安全にWP-CLIを使わせる制限付きラッパーの作り方

宿主とAIからWordPressへ向かう操作を門が選別し、安全な操作だけを通すイラスト AIサイト管理

「削除コマンドを使わないで」とAIへ指示することは大切ですが、その文章だけで本番サイトを守ることはできません。依頼の解釈違い、タイプミス、後から追加した指示などにより、想定外のコマンドが選ばれる可能性があるからです。

そこで、AIからWP-CLIを直接実行できないようにし、管理者が許可した少数の操作だけを受け付ける窓口を間に置きます。この窓口が「制限付きラッパー」です。

この記事は仕組みを理解するための解説です。導入前にAIへWP-CLIを渡す前の準備で、権限、バックアップ、テスト環境を確認してください。サーバーの利用者や権限を変更する作業は、契約先またはサーバー管理者へ依頼します。

制限付きラッパーとは

通常のWP-CLIには、記事の確認だけでなく、削除、更新、データベース操作、任意のPHPコード実行などの機能があります。公式のコマンド一覧にも、wp dbwp evalwp search-replacewp userなど、扱いに注意が必要なコマンドが含まれます。

制限付きラッパーでは、AIが入力した文字列をそのままwpへ渡しません。たとえば、次の三つだけを独自の操作名として受け付けます。

  • site-status:WordPressのバージョンと状態を確認する
  • plugin-status:プラグインの一覧を確認する
  • post-list:公開記事または下書きの一覧を確認する

ラッパーの内部で、それぞれを管理者が確認済みのWP-CLIコマンドへ変換します。一致しない操作名は、実行せずエラーにします。

文章のルールと技術的な制限は役割が違う

AGENTS.mdCLAUDE.mdには、「最初は読み取りだけ」「公開・削除・更新は人の承認が必要」といった運用ルールを書きます。これはAIと人が判断基準を共有するために役立ちます。

一方、制限付きラッパーは、許可されていない操作を実行経路で止めます。

宿主の依頼
  ↓
Codex・Claude Code
  ↓
制限付きラッパー ── 許可されていない操作は拒否
  ↓
固定されたWP-CLIコマンド
  ↓
WordPress

文章のルール、ラッパー、OSとWordPressの権限、人による確認を重ねるのが基本です。ラッパー一つで安全が保証されるわけではありません。

安全な設計の原則

1. 許可リストから始める

「危険なコマンドだけを禁止する」のではなく、「使ってよい操作だけを許可する」方式にします。WP-CLIには追加パッケージやプラグイン由来のコマンドもあるため、禁止リストでは未知の操作を見落とす可能性があります。

最初は状態確認だけにし、必要になった操作を一つずつ追加します。

2. WP-CLIの文字列をそのまま受け取らない

ラッパーへwp post list ...のような自由なコマンド文字列を渡せると、検査の抜け道が生まれやすくなります。post-listのような独自の操作名を受け取り、実際のコマンドと引数はラッパー内で固定します。

evalで入力文字列を再実行したり、入力全体をシェルへ渡したりしてはいけません。

3. 対象サイトを固定する

WP-CLIには対象を変えられるグローバル引数があります。--path--url--ssh--require--execなどを外部から自由に渡さず、WordPressの場所と対象URLは管理者側で固定します。

4. 専用の実行ユーザーを使う

普段の管理者アカウントやrootをAIと共有しません。WordPressの確認に必要な範囲だけを持つ専用ユーザーを用意し、対話シェル、ファイル書き込み、転送機能など、不要な権限を外します。

WordPress側のユーザーを指定する場合も、管理者ではなく作業に必要な権限へ絞ります。

5. 記録して、件数を制限する

実行日時、操作名、成否、対象IDを記録します。ただし、記事本文、設定値、認証情報はログへ残しません。一回の実行件数や取得件数にも上限を設けます。

読み取り専用ラッパーの最小例

次は、仕組みを説明するための架空環境用サンプルです。実際のWordPressの場所や実行ユーザーは含めていません。このまま本番へ設置せず、管理者が環境に合わせて所有者、権限、ログ、実行方法を設計してください。

#!/usr/bin/env bash
set -euo pipefail

readonly PATH=/usr/local/bin:/usr/bin:/bin
readonly WP=/usr/local/bin/wp
readonly SITE=/srv/example/wordpress

action=${1:-}
shift || true

# 想定外の追加引数はすべて拒否する
if (( $# != 0 )); then
  echo "追加の引数は使用できません" >&2
  exit 64
fi

case "$action" in
  site-status)
    "$WP" --path="$SITE" core version
    "$WP" --path="$SITE" core is-installed
    ;;
  plugin-status)
    "$WP" --path="$SITE" plugin list \
      --fields=name,status,version --format=table
    ;;
  post-list)
    "$WP" --path="$SITE" post list \
      --post_type=post \
      --post_status=publish,draft \
      --fields=ID,post_title,post_status \
      --posts_per_page=20 \
      --format=table
    ;;
  *)
    echo "許可されていない操作です" >&2
    exit 64
    ;;
esac

ポイントは、wp "$@"のように外部入力を丸ごとWP-CLIへ渡していないことです。実行ファイル、WordPressの場所、サブコマンド、オプションをラッパー側で固定しています。

SSH経由なら入口も固定する

VPSへSSH接続させる場合は、AI専用の鍵とユーザーを分け、接続後に自由なシェルを開かせない設計を検討します。OpenSSHのForceCommandは、クライアントが指定したコマンドの代わりに固定コマンドを実行できます。

ただし、ForceCommandだけではポート転送やエージェント転送までは止まりません。OpenSSHの公式マニュアルも、不要な場合はDisableForwardingなどで別途無効化する必要があると説明しています。

SSHの設定を誤ると、管理者自身が接続できなくなることがあります。現在の接続を残したまま設定検査と別セッションでの接続試験を行い、制作会社や管理者が設定してください。

下書き作成を許可するときの追加条件

読み取りの次に記事作成を許可する場合も、自由なwp post createを渡すのではなく、「新規投稿を下書きで一件作る」専用の入口を別にします。

  • post_typepostに固定する
  • post_statusdraftに固定する
  • 一回につき一件だけにする
  • slugの文字種と長さを検査する
  • 本文ファイルを読み込める場所を専用ディレクトリ内に限定する
  • カテゴリIDを許可済みの候補から選ぶ
  • 作成後に投稿IDとプレビュー先を報告する
  • publishへの変更は別の承認付き処理に分ける

WP-CLIのwp post createは投稿状態を指定できるため、ラッパー側でdraftへ固定できます。ただし、下書きでも不適切な内容や個人情報を保存する可能性はあります。登録後は必ず人が管理画面で確認します。

作ってはいけないラッパー

次のような実装は、名前が「安全ラッパー」でも十分な制限になりません。

# 外部入力を何でもWP-CLIへ渡してしまう
wp "$@"

# 文字列を再びシェルとして解釈してしまう
eval "$SSH_ORIGINAL_COMMAND"

また、「deleteという単語が含まれていなければ許可」のような検査も避けます。別の更新経路、短縮表現、追加コマンドを見落とすためです。

導入前のチェックリスト

  • 管理者とは別の実行ユーザーになっている
  • 許可した操作名以外はエラーになる
  • 余分な引数、未知のオプション、複数件操作を拒否する
  • WP-CLI本体とWordPressの場所が固定されている
  • evalや自由なシェルを使っていない
  • PHP実行、DB操作、設定表示、更新、削除を呼び出せない
  • SSHのシェルと各種転送を制限している
  • ラッパーと設定ファイルをAI側から書き換えられない
  • 秘密情報を含めない監査ログが残る
  • テスト環境で「許可」と「拒否」の両方を確認した
  • バックアップだけでなく復元方法も確認した
  • 公開、更新、削除は人の承認で止まる

AIへの依頼例

このサイトではWP-CLIを直接実行せず、管理者が用意した
制限付きラッパーだけを使用してください。

最初に利用可能な操作名を確認し、今回は読み取り専用の
site-status、plugin-status、post-listだけを使用してください。

許可されていない操作、追加引数、設定変更、更新、削除、
公開は行わないでください。実行した操作名と結果を報告し、
個人情報や秘密情報は回答に表示しないでください。

この依頼文は判断を助けるルールです。実行経路側の制限と組み合わせて使います。

まとめ

AIにWP-CLIを手伝わせるときは、危険な操作を文章で禁止するだけでなく、許可した操作しか物理的に通らない入口を用意します。

最初は読み取り専用の三つ程度から始め、拒否できることもテストしてください。その後、必要に応じて「下書きを一件作る」「公開済みページのHTTP応答を確認する」といった専用操作を、一つずつ追加します。実際の工程はバックアップから記事公開・HTTP・表示確認までの手順で解説しています。

WP-CLIそのものが初めての場合は、先にWP-CLIとは?AIにWordPressを手伝わせる前に知りたい基礎と安全な始め方をご覧ください。AI運用全体のルールはAIでWordPressを管理する安全ルール、記事一覧は宿主さん向けWeb運営ガイドにまとめています。

これらを実際の運用でどう組み合わせ、失敗をルールへ反映しているかは、ねこ宿研究所のAI・WP-CLI運用事例で紹介しています。

参考資料

※サーバー、SSH、WordPressの構成は契約先ごとに異なります。設定変更は公式マニュアルと保守契約を確認し、接続を失った場合の復旧手段を準備してから行ってください。

タイトルとURLをコピーしました