|
|
@@ -17,6 +17,8 @@
|
|
|
#
|
|
|
# 不同步:settings/(kiro-cli 自动生成)。
|
|
|
# 安全:顶层 skills/ 不做 --delete,命令安装的 skill 目录不会被误删。
|
|
|
+# 另:禁止把配置同步到用户级 ~/.kiro(B 端不能落在任何真实用户 HOME 下),
|
|
|
+# 命中即报错退出;确需解除请设 KIRO_ALLOW_USER_HOME=y。
|
|
|
#
|
|
|
# 用法:
|
|
|
# ./sync_kiro_config.sh # 执行同步
|
|
|
@@ -32,6 +34,7 @@
|
|
|
# KIRO_AGENT skills CLI 目标 agent (默认 kiro-cli)
|
|
|
# KIRO_SKILLS_INSTALL 是否命令安装 skills.sh skill (默认 y)
|
|
|
# KIRO_DRY_RUN 只打印不落盘 (y/n) (默认 n)
|
|
|
+# KIRO_ALLOW_USER_HOME 解除「禁止同步到用户级 ~/.kiro」保护 (y/n) (默认 n)
|
|
|
# =============================================================================
|
|
|
set -euo pipefail
|
|
|
|
|
|
@@ -194,6 +197,72 @@ replace_placeholders() {
|
|
|
ok "占位符替换完成"
|
|
|
}
|
|
|
|
|
|
+# ---------------------------------------------------------------------------
|
|
|
+# 安全守卫:禁止把配置同步到「用户级目录」
|
|
|
+# 本脚本是 A→B 的部署同步,B 端应为服务账户的部署目录(如
|
|
|
+# /var/www/fwh-toolbox/server/.kiro),绝不能指向某个真实用户的 HOME
|
|
|
+# 下的 ~/.kiro,否则 rsync --delete 会覆盖/删除用户自己的 steering、
|
|
|
+# agents、skills(曾因此丢失用户级配置)。
|
|
|
+#
|
|
|
+# 判定规则(任一命中即拒绝):
|
|
|
+# * B_DIR 解析后正好等于 “<某 HOME>/.kiro”,或位于其下;
|
|
|
+# * 该 HOME 来源:当前执行用户 $HOME、KIRO_RUN_AS_USER 的 HOME、
|
|
|
+# 以及常见用户家目录前缀 /home/*、/Users/*、/root。
|
|
|
+# 用物理路径比较,避免 ..、软链接、结尾斜杠绕过。可用
|
|
|
+# KIRO_ALLOW_USER_HOME=y 显式解除(仅限明确知道后果时)。
|
|
|
+# ---------------------------------------------------------------------------
|
|
|
+abspath() {
|
|
|
+ # 输出物理绝对路径;路径可能尚不存在,故对父目录逐级回退解析
|
|
|
+ local p="$1"
|
|
|
+ if command -v realpath >/dev/null 2>&1; then
|
|
|
+ realpath -m -- "${p}" 2>/dev/null && return 0
|
|
|
+ fi
|
|
|
+ if command -v readlink >/dev/null 2>&1; then
|
|
|
+ readlink -f -- "${p}" 2>/dev/null && return 0
|
|
|
+ fi
|
|
|
+ # 兜底:去掉结尾斜杠,原样返回
|
|
|
+ echo "${p%/}"
|
|
|
+}
|
|
|
+
|
|
|
+guard_not_user_home() {
|
|
|
+ if [[ "${KIRO_ALLOW_USER_HOME:-n}" == "y" ]]; then
|
|
|
+ warn "已设置 KIRO_ALLOW_USER_HOME=y,跳过用户级目录保护(请自行确认后果)"
|
|
|
+ return 0
|
|
|
+ fi
|
|
|
+
|
|
|
+ local b_abs; b_abs="$(abspath "${B_DIR}")"
|
|
|
+
|
|
|
+ # 收集需要保护的 HOME 列表
|
|
|
+ local -a homes=()
|
|
|
+ [[ -n "${HOME:-}" ]] && homes+=("${HOME}")
|
|
|
+ local run_home
|
|
|
+ run_home="$(getent passwd "${KIRO_RUN_AS_USER}" 2>/dev/null | cut -d: -f6)"
|
|
|
+ [[ -n "${run_home}" ]] && homes+=("${run_home}")
|
|
|
+
|
|
|
+ local h h_abs
|
|
|
+ for h in "${homes[@]}"; do
|
|
|
+ [[ -z "${h}" || "${h}" == "/" ]] && continue
|
|
|
+ h_abs="$(abspath "${h}")"
|
|
|
+ # B_DIR 恰为 <HOME>/.kiro,或位于 <HOME>/ 之下
|
|
|
+ if [[ "${b_abs}" == "${h_abs}/.kiro" || "${b_abs}" == "${h_abs}/.kiro/"* ]]; then
|
|
|
+ err "拒绝同步:B 端目标 ${b_abs} 位于用户 HOME(${h_abs})下,属于用户级 .kiro 目录。"
|
|
|
+ err "本脚本只允许同步到服务部署目录。若确需覆盖用户级目录,请设 KIRO_ALLOW_USER_HOME=y。"
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
+ done
|
|
|
+
|
|
|
+ # 额外拦截:B_DIR 直接落在常见「用户家目录」前缀下(覆盖非当前用户的情况)
|
|
|
+ case "${b_abs}" in
|
|
|
+ /home/*/.kiro|/home/*/.kiro/*|/Users/*/.kiro|/Users/*/.kiro/*|/root/.kiro|/root/.kiro/*)
|
|
|
+ err "拒绝同步:B 端目标 ${b_abs} 看起来是用户级 .kiro 目录(位于 /home、/Users 或 /root 下)。"
|
|
|
+ err "本脚本只允许同步到服务部署目录。若确需覆盖用户级目录,请设 KIRO_ALLOW_USER_HOME=y。"
|
|
|
+ exit 1
|
|
|
+ ;;
|
|
|
+ esac
|
|
|
+
|
|
|
+ ok "用户级目录保护检查通过:B 端 ${b_abs} 非用户级 .kiro"
|
|
|
+}
|
|
|
+
|
|
|
# ---------------------------------------------------------------------------
|
|
|
# main
|
|
|
# ---------------------------------------------------------------------------
|
|
|
@@ -207,6 +276,9 @@ main() {
|
|
|
|
|
|
if [[ ! -d "${A_DIR}" ]]; then err "A 端不存在:${A_DIR}"; exit 1; fi
|
|
|
|
|
|
+ # 写操作前的安全守卫:禁止同步到用户级 ~/.kiro
|
|
|
+ guard_not_user_home
|
|
|
+
|
|
|
sync_config_dirs
|
|
|
sync_custom_skills
|
|
|
install_skills_sh
|