Files
MailUI4Agents/scripts/verify-l2.sh
JianFeeeee c7cb88d9aa chore(security): 轮换 verify-l2.sh 里那把曾进 git 历史的 user key
旧值(jianf 的 user key,1759666 起在历史里)已从库里删除,实测
`/auth/me` → **401**,即暴露在历史中的那串现在无效。新值只存在
/root/gotmp/verify-l2-token.txt(600),脚本 6/6 通过。

- 只删当前行**不等于**作废:git 历史里的密钥必须靠轮换才能失效。
- 轮换前先核对过使用面:全仓库只有这一处,/root 下的脚本与运行进程环境里都没有。
- 生产库里临时建的留档表已 DROP,那行旧记录挪到
  /root/gotmp/user-keys-rotation-backup-20260912.json(600)。
- 轮换过程本身也踩了一个小坑:sqlite3 CLI 里没有 gen_random_uuid()
  (那是网关 Go 驱动注册的函数),插入必须显式给 key_id —— 而当时旧行已经删掉了,
  于是出现了一小段「无可用 key」的空档(立刻补上并双向验证过)。
2026-09-12 23:58:10 +08:00

63 lines
3.1 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# L2 端到端验证脚本
set -euo pipefail
# 管理员 user key。**不要把它写进这个文件**。
#
# 2026-09-12本文件原来硬编码了一把 jianf 的 user key自 1759666 起在 git 历史里)。
# 已轮换作废(旧值实测 /auth/me → 401新值只存在 /root/gotmp/verify-l2-token.txt600。 —— 仓库是会被看到的地方,
# 而写进 git 历史的密钥只能靠轮换作废(删掉当前行不能把它从历史里拿掉)。
#
# 取法(任一):
# VERIFY_L2_TOKEN=<key> bash scripts/verify-l2.sh
# echo <key> > /root/gotmp/verify-l2-token.txt && chmod 600 该文件
TOKEN="${VERIFY_L2_TOKEN:-}"
if [ -z "$TOKEN" ] && [ -r /root/gotmp/verify-l2-token.txt ]; then
TOKEN=$(tr -d '\n' < /root/gotmp/verify-l2-token.txt)
fi
if [ -z "$TOKEN" ]; then
echo "需要管理员 user key设 VERIFY_L2_TOKEN或写到 /root/gotmp/verify-l2-token.txt600" >&2
exit 2
fi
BASE="http://127.0.0.1:8180/api/v1"
H=(-H "Authorization: Bearer $TOKEN")
PASS=0 FAIL=0
ok() { echo "$1"; PASS=$((PASS+1)); }
bad() { echo "$1"; FAIL=$((FAIL+1)); }
echo "=== L2 端到端验证 ==="
# ── 1. PUT /sessions/:id/permission
SID=$(sqlite3 /opt/agentmail/data/agentmail.db "SELECT session_id FROM sessions ORDER BY updated_at DESC LIMIT 1;")
echo "1. PUT /sessions/:id/permission ($SID)"
# 改 plan
R=$(curl -s -X PUT "$BASE/sessions/$SID/permission" -H 'Content-Type: application/json' "${H[@]}" -d '{"permission_mode":"plan"}')
if echo "$R" | grep -q '"permission_mode":"plan"'; then ok "plan 写入成功"; else bad "plan 写入失败: $R"; fi
# 改 full
R=$(curl -s -X PUT "$BASE/sessions/$SID/permission" -H 'Content-Type: application/json' "${H[@]}" -d '{"permission_mode":"full"}')
if echo "$R" | grep -q '"permission_mode":"full"'; then ok "full 写入成功"; else bad "full 写入失败: $R"; fi
# 脏值 → 回落到 workspace
R=$(curl -s -X PUT "$BASE/sessions/$SID/permission" -H 'Content-Type: application/json' "${H[@]}" -d '{"permission_mode":"bogus"}')
if echo "$R" | grep -q '"permission_mode":"workspace"'; then ok "脏值回落到 workspace"; else bad "脏值未回落: $R"; fi
# 复原
curl -s -X PUT "$BASE/sessions/$SID/permission" -H 'Content-Type: application/json' "${H[@]}" -d '{"permission_mode":"workspace"}' > /dev/null
# ── 2. calendar_events.permission_mode 列
echo "2. calendar_events.permission_mode 列"
COL=$(sqlite3 /opt/agentmail/data/agentmail.db "PRAGMA table_info(calendar_events);" | grep permission_mode || true)
if [ -n "$COL" ]; then ok "列存在: $COL"; else bad "列不存在"; fi
# ── 3. 建会话检查 schema 两列
echo "3. sessions permission_mode/enforcement 列"
PM=$(sqlite3 /opt/agentmail/data/agentmail.db "PRAGMA table_info(sessions);" | grep permission_mode || true)
PE=$(sqlite3 /opt/agentmail/data/agentmail.db "PRAGMA table_info(sessions);" | grep permission_enforcement || true)
if [ -n "$PM" ]; then ok "permission_mode 列存在"; else bad "permission_mode 列缺失"; fi
if [ -n "$PE" ]; then ok "permission_enforcement 列存在"; else bad "permission_enforcement 列缺失"; fi
echo ""
echo "=== 结果: $PASS 通过, $FAIL 失败 ==="