向AI交代「不要使用删除指令」很重要,但光靠这段文字,无法保护正式网站。因为对委托的理解有误、输入错误,或后来追加的指示等,都可能让AI选择非预期的指令。
因此,我们不让AI直接执行WP-CLI,而是在中间设置一个只接受少量、经管理者核准操作的入口。这个入口就是「受限制的指令包装器」。
本文旨在解释运作机制。导入前,请通过将WP-CLI交给AI之前的准备确认权限、备份与测试环境。变更服务器用户或权限的工作,应委托服务供应商或服务器管理者处理。
什么是受限制的指令包装器
一般WP-CLI不只可查看文章,也有删除、更新、数据库操作与执行任意PHP代码等功能。官方指令列表中也包含wp db、wp eval、wp search-replace、wp user等需要谨慎处理的指令。
受限制的指令包装器不会把AI输入的字符串直接传给wp。例如,只接受以下三个自订操作名称。
site-status:确认WordPress的版本与状态plugin-status:确认插件列表post-list:确认已发布文章或草稿列表
包装器内部将各项操作转换成管理者已确认的WP-CLI指令。不符合的操作名称会返回错误,不予执行。
文字规则与技术限制的用途不同
在AGENTS.md或CLAUDE.md中,写下「一开始只进行读取」「发布、删除与更新须经人核准」等作业规则,有助于AI与人共享判断标准。
另一方面,受限制的指令包装器会在执行路径上阻挡未获允许的操作。
旅宿经营者的委托
↓
Codex・Claude Code
↓
受限制的指令包装器 ── 拒绝未获允许的操作
↓
固定的WP-CLI指令
↓
WordPress
基本做法是结合文字规则、指令包装器、OS与WordPress权限,以及人工确认。单靠一个包装器,并不能保证安全。
安全设计原则
1. 从允许清单开始
不要只禁止危险指令,而应采用只允许已核准操作的方式。WP-CLI也有来自额外软件包或插件的指令,因此禁止清单可能漏掉未知操作。
一开始只确认状态,再逐项新增有需要的操作。
2. 不直接接收WP-CLI指令字符串
如果能向包装器传入像wp post list ...这样的自由指令字符串,检查就容易出现漏洞。应接收post-list等自订操作名称,并在包装器内固定实际指令与参数。
不得用eval重新执行输入字符串,也不得把整段输入传给shell。
3. 固定目标网站
WP-CLI有可变更目标的全局参数。不要让外部自由传入--path、--url、--ssh、--require、--exec等参数;WordPress位置与目标URL应由管理者固定。
4. 使用专用执行用户
不要与AI共享平常的管理者账号或root。应准备一个只具备确认WordPress所需权限的专用用户,并移除交互式shell、文件写入与传输等不必要的权限。
即使指定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时,也要固定入口
若让AI通过SSH连接至VPS,应分开使用AI专用密钥与用户,并考虑采用连接后不允许开启自由shell的设计。OpenSSH的ForceCommand能以固定指令取代客户端指定的指令。
不过,单靠ForceCommand并不会阻止端口转发或代理转发。OpenSSH官方手册也说明,不需要这些功能时,必须通过DisableForwarding等设置另外停用。
SSH设置有误,可能让管理者自己也无法连接。应保持现有连接,进行设置检查与另一个工作阶段的连接测试,并由网站制作公司或管理者设置。
允许建立草稿时的额外条件
读取之后,若要允许制作文章,也不要开放自由使用wp post create,而应另设一个「建立一篇新文章草稿」的专用入口。
- 将
post_type固定为post - 将
post_status固定为draft - 每次只处理一篇
- 检查slug的字符种类与长度
- 将可读取正文文件的位置限制在专用目录内
- 从已核准的候选项目中选择分类ID
- 建立后回报文章ID与预览位置
- 将变更为
publish的操作分成另外须经核准的程序
WP-CLI的wp post create可以指定文章状态,因此能在包装器端固定为draft。不过,即使是草稿,也可能存储不适当的内容或个人资料。创建草稿后,务必由人在管理界面确认。
不应制作的指令包装器
以下这类实现,即使名为「安全包装器」,仍无法提供充分限制。
# 将任何外部输入都传给WP-CLI
wp "$@"
# 把字符串再次当作shell解读
eval "$SSH_ORIGINAL_COMMAND"
也应避免「没有包含delete这个字就允许」之类的检查方式,因为这会漏掉其他更新路径、缩写或额外指令。
导入前的确认清单
- 执行用户与管理者不同
- 已核准操作名称以外的名称会返回错误
- 拒绝额外参数、未知选项与多笔操作
- WP-CLI可执行文件与WordPress位置已固定
- 没有使用
eval或自由shell - 无法调用PHP执行、数据库操作、设置显示、更新或删除
- SSH的shell与各种转发已受限制
- AI端无法改写包装器与配置文件
- 留有不包含秘密信息的审计日志
- 已在测试环境确认「允许」与「拒绝」两种情况
- 不只确认备份,也确认复原方法
- 发布、更新与删除,会停在由人核准的阶段
给AI的委托示例
在这个网站,不要直接执行WP-CLI,只能使用管理者准备的
受限制指令包装器。
请先确认可用的操作名称,这次只使用只读的
site-status、plugin-status、post-list。
不要进行未获允许的操作、使用额外参数、变更设置、更新、删除或
发布。请回报已执行的操作名称与结果,
不要在回答中显示个人资料或秘密信息。
这段委托文字是协助判断的规则,应搭配执行路径端的限制使用。
总结
让AI协助使用WP-CLI时,不只要用文字禁止危险操作,也要准备一个只有已核准操作才能实际通过的入口。
一开始从大约三项只读操作开始,也要测试确实能拒绝操作。之后,再视需要逐项新增「建立一篇草稿」「确认公开页面的HTTP响应」等专用操作。实际流程请见从备份到文章发布、HTTP与画面确认的步骤。
若第一次接触WP-CLI,请先阅读什么是WP-CLI?让AI协助WordPress前应知道的基础与安全入门。AI作业整体规则整理于使用AI管理WordPress的安全规则,文章列表请见给旅宿经营者的网站营运指南。
如何在实际运作中组合这些方法,并将失败经验纳入规则,请见猫宿研究所的AI与WP-CLI运作案例。
参考资料
- WordPress Developer Resources:WP-CLI指令列表
- WordPress Developer Resources:WP-CLI全局参数
- WordPress Developer Resources:wp post create
- OpenBSD manual pages:sshd_config
※服务器、SSH与WordPress配置依服务供应商而异。修改设置前,请确认官方手册与维护合约,并准备失去连接时的复原方法。

