场景
工具装好了,一跑就报权限错:Docker 容器读写挂载目录被拒、git 报 dubious ownership、npm 全局安装 EACCES、SSH 私钥权限过宽、Codex 沙盒 setup refresh 报错。报错都指向文件权限/属主/安全设置,但修复面分属不同工具域(容器 uid 映射 / git 白名单 / npm prefix / 私钥权限 / 沙盒 ACL),单篇教程只讲一个域,报错时不知道走哪条链。
本组合包按「先通用定位、再逐工具修复」编排成套:先分清是「权限错」还是「环境错」,再按 系统层(SSH/挂载盘特判)→ 工具层(git/npm/沙盒)→ 容器层(Docker uid)逐域修。git、SSH、挂载盘三条本环境真实实测;Docker、npm 因环境限制如实标注未实测。
组合成员 (6)
通用定位(先分清「权限错」与「环境错」)
下载:无(诊断方法,非工具)
版本要求:无
# 权限错的特征:报错关键字 Permission denied / EACCES / too open / dubious ownership;
# 与「环境错」(daemon 不可达 / 端口冲突,见 combo-docker-wsl-env)区分开,走不同排查链。
# 先看工具自己的日志定位(Codex 沙盒示例,Windows 侧):
# C:\Users\<user>\.codex\.sandbox\sandbox.<date>.log
# 本环境实证:C:\Users\<user>\.codex\.sandbox\ 下存在按日期命名的多份沙盒日志
Docker 容器(uid 对齐)
下载:Docker Engine/Docker Desktop(见 combo-docker-wsl-env)
版本要求:>= 20.10(与 combo-docker-wsl-env 一致)
# 容器 uid 对齐宿主(推荐):
docker run -u "$(id -u):$(id -g)" -v "$PWD/data:/data" ...
# compose:user: "${UID}:${GID}"(${UID} 需在 shell 里导出)
# 一次性修正宿主目录属主:
sudo chown -R 1000:1000 ./data
# 临时应急(破坏最小权限原则,仅本机调试):
docker run -u 0:0 ...
Git(safe.directory 白名单)
下载:无(git 自带配置)
版本要求:git >= 2.35(白名单报错提示机制;本机实测 2.53.0)
# 白名单按目录登记、不递归——同盘其他仓库还要再 add:
git config --global --add safe.directory <仓库绝对路径>
# 仓库很多时才考虑全局信任(共享机器不推荐):
git config --global --add safe.directory '*'
# Linux 文件系统可直接改属主(NTFS/exFAT 挂载盘无效,见下方 drvfs 警告):
sudo chown -R $(id -u):$(id -g) <仓库路径>
npm(全局 prefix 改到用户目录)
下载:无(npm 自带配置)
版本要求:无(任意 npm 版本;本机 node v22.22.1,npm prefix 默认 /usr/local——正是 EACCES 高发默认值)
# 形态 1(推荐,一劳永逸):
npm config set prefix ~/.npm-global
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
# 形态 2:把 ~/.npm 所有权还给自己:
sudo chown -R $(whoami) ~/.npm
# 国内网络:npm 全局包走 npmmirror(见 combo-mirror-setup):
npm config set registry https://registry.npmmirror.com
SSH(私钥权限收紧)
下载:无(OpenSSH 自带)
版本要求:无
# Linux/macOS/WSL 侧:
chmod 600 ~/.ssh/id_ed25519 # 私钥
chmod 644 ~/.ssh/*.pub # 公钥
chmod 700 ~/.ssh # 目录
# Windows 原生 OpenSSH(chmod 不适用):
icacls "私钥路径" /inheritance:r /grant:r "%USERNAME%:R"
# WSL 访问 /mnt/c 上的密钥:drvfs 不支持 chmod(实测 chmod 600 后 ls 仍 777)——
# 复制到 WSL 内再 chmod,或在 Windows 侧用 icacls 修
Codex 沙盒(日志定位 + 属主/ACL 修复)
下载:无(Codex 自带)
版本要求:无
# 1) 先看日志定位(比瞎猜快),搜 setup refresh had errors / write ACE:
# C:\Users\<user>\.codex\.sandbox\sandbox.<date>.log(旧版路径 .codex.sandbox)
# 2) 改 owner(最常见修复):
takeown /f <目录> /r /d y
# 3) 补 ACL(owner 正确仍缺权限时):
icacls <目录> /grant <user>:(OI)(CI)F /T
# 4) 验证:重开会话触发 setup refresh,日志 errors=[] 即恢复(幂等,无需重装)
方案总览
| 修复面 | 管什么 | 关键手段 |
|---|---|---|
| 通用定位 | 分清权限错 vs 环境错 | 报错关键字区分(Permission denied/EACCES vs daemon/端口) |
| 系统层 | SSH 私钥权限 / WSL 挂载盘特判 | 私钥收紧;挂载盘不支持 chmod(实测) |
| 工具层 | git 白名单 / npm prefix / Codex 沙盒 ACL | 白名单登记 / 用户级 prefix / 日志定位 + 授权 |
| 容器层 | Docker 容器 uid 对齐 | 容器 uid 对齐宿主 |
顺序逻辑:先定位(权限错 vs 环境错)→ 系统层(最通用,先排除)→ 工具层 → 容器层(依赖 daemon 可达,排最后)。
快速开始
一键脚本由本文档自动生成(渲染后位于 pages/combos/combo-permission-security.sh),逐条执行:
bash pages/combos/combo-permission-security.sh
- 配完你会得到:五条权限修复的命令模板(git/SSH/npm/Codex/Docker),按序逐域排完。
- 预计耗时:5-10 分钟(大部分是配置命令,无大下载)。
- 前置条件:按报错域准备——git >= 2.35(白名单提示);Docker >= 20.10(容器层);Windows 侧权限操作用系统自带授权命令。
想弄明白每一步在干什么、修错了怎么恢复 → 看「逐步教学」。一键脚本出问题 → 按逐步教学手动执行定位。
逐步教学
第 1 步:通用定位(权限错 vs 环境错)
先分清报错类型,走对排查链:权限错的特征关键字 = Permission denied / EACCES / too open / dubious ownership;环境错 = daemon 不可达 / 端口冲突(走 combo-docker-wsl-env)。确认是权限错后,看工具自己的日志定位(Codex 沙盒示例:Windows 侧用户目录下的沙盒日志目录,本环境实证有 3 份日志)。
# 权限错的特征:报错关键字 Permission denied / EACCES / too open / dubious ownership;
# 与「环境错」(daemon 不可达 / 端口冲突,见 combo-docker-wsl-env)区分开,走不同排查链。
# 先看工具自己的日志定位(Codex 沙盒示例,Windows 侧):
# C:\Users\<user>\.codex\.sandbox\sandbox.<date>.log
# 本环境实证:C:\Users\<user>\.codex\.sandbox\ 下存在按日期命名的多份沙盒日志
预期输出: 定位到具体报错域(git/SSH/npm/docker/codex 之一)
装好确认:
- 报错关键字匹配权限错特征;
- 日志文件存在(Codex 示例:3 份日期日志,实测)。
卡住怎么办:
- 关键字模棱两可 → 两个链都走:先环境链(daemon/端口)后权限链。
- 日志路径不对 → 搜索日志文件名找实际路径。
第 2 步:git 白名单登记(dubious ownership)
git 2.35+ 对属主不一致的仓库报 fatal: detected dubious ownership。白名单按目录登记、不递归——同盘其他仓库还要再登记;仓库很多才考虑全局信任(共享机器不推荐)。Linux 文件系统可直接改属主(NTFS/exFAT 挂载盘无效,见第 4 步挂载盘警告)。
# 白名单按目录登记、不递归——同盘其他仓库还要再 add:
git config --global --add safe.directory <仓库绝对路径>
# 仓库很多时才考虑全局信任(共享机器不推荐):
git config --global --add safe.directory '*'
# Linux 文件系统可直接改属主(NTFS/exFAT 挂载盘无效,见下方 drvfs 警告):
sudo chown -R $(id -u):$(id -g) <仓库路径>
预期输出: 报错仓库里 git status 正常(实测:nobody 用户访问 root 属主仓库报错 → 登记后正常)
装好确认:
- git status 不再报 dubious ownership。
卡住怎么办:
- 登记后仍报错 → 确认路径是绝对路径;确认 git >= 2.35。
- 不想逐个登记(仓库很多)→ 全局信任(共享机器不推荐)。
第 3 步:npm 全局 prefix 改到用户目录(EACCES)
npm 全局安装 EACCES 的根因通常是 prefix 默认在系统目录(/usr/local),普通用户没写权限。推荐形态 = 把 prefix 改到用户目录(一劳永逸),或把 npm 用户目录所有权还给自己。
# 形态 1(推荐,一劳永逸):
npm config set prefix ~/.npm-global
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
# 形态 2:把 ~/.npm 所有权还给自己:
sudo chown -R $(whoami) ~/.npm
# 国内网络:npm 全局包走 npmmirror(见 combo-mirror-setup):
npm config set registry https://registry.npmmirror.com
预期输出: npm 全局安装不再报 EACCES
装好确认:
- npm config get prefix 输出用户目录;
- 新终端里全局装一个小包成功。
卡住怎么办:
- PATH 没生效 → 重载 shell 配置或重开终端;确认 export 行加对了。
- 不想改全局 → 用 npx(免全局安装)形态。
第 4 步:系统层(SSH 私钥权限 + 挂载盘特判)
SSH 私钥权限过宽(too open)就收紧:Linux/macOS/WSL 用 chmod;Windows 原生 OpenSSH 走系统授权命令(chmod 不适用)。WSL 访问 Windows 挂载盘上的密钥有坑:挂载盘不支持 chmod——实测 chmod 600 后权限位仍不变,密钥必须复制到 WSL 内再 chmod,或在 Windows 侧用系统授权命令修。
# Linux/macOS/WSL 侧:
chmod 600 ~/.ssh/id_ed25519 # 私钥
chmod 644 ~/.ssh/*.pub # 公钥
chmod 700 ~/.ssh # 目录
# Windows 原生 OpenSSH(chmod 不适用):
icacls "私钥路径" /inheritance:r /grant:r "%USERNAME%:R"
# WSL 访问 /mnt/c 上的密钥:drvfs 不支持 chmod(实测 chmod 600 后 ls 仍 777)——
# 复制到 WSL 内再 chmod,或在 Windows 侧用 icacls 修
预期输出: 私钥权限位收紧(Linux/WSL 侧)
装好确认:
- 私钥 600 / 公钥 644 / 目录 700;
- SSH 连接不再报 too open。
卡住怎么办:
- 挂载盘上 chmod 无效(权限位不变)→ 复制密钥到 WSL 内再 chmod;或 Windows 侧系统授权命令。
- Windows OpenSSH 报权限错 → 系统授权命令重跑,确认用户授权。
第 5 步:Docker 容器 uid 对齐(挂载目录被拒)
容器读写挂载目录被拒,根因是容器内用户 uid 与宿主目录属主不一致。推荐 = 容器 uid 对齐宿主;compose 用用户 uid 变量;临时应急用 root(破坏最小权限原则,仅本机调试)。
# 容器 uid 对齐宿主(推荐):
docker run -u "$(id -u):$(id -g)" -v "$PWD/data:/data" ...
# compose:user: "${UID}:${GID}"(${UID} 需在 shell 里导出)
# 一次性修正宿主目录属主:
sudo chown -R 1000:1000 ./data
# 临时应急(破坏最小权限原则,仅本机调试):
docker run -u 0:0 ...
预期输出: 容器内对挂载目录读写不再 Permission denied
装好确认:
- 容器内创建测试文件成功;
- 宿主侧文件属主符合预期。
卡住怎么办:
- uid 对齐后仍报错 → 确认挂载路径权限(宿主侧看目录属主);或一次性改属主。
- daemon 不可达 → 先走 combo-docker-wsl-env 环境链。
note: 本步未实测(本机 daemon 不可达);命令为 Docker 官方标准形态。
第 6 步:Codex 沙盒日志定位 + 授权修复(setup refresh 报错)
Codex 沙盒 setup refresh 报错先看日志定位(比瞎猜快,搜报错关键字),再改属主/补授权——属主正确仍缺权限时补授权。修复幂等,无需重装。
# 1) 先看日志定位(比瞎猜快),搜 setup refresh had errors / write ACE:
# C:\Users\<user>\.codex\.sandbox\sandbox.<date>.log(旧版路径 .codex.sandbox)
# 2) 改 owner(最常见修复):
takeown /f <目录> /r /d y
# 3) 补 ACL(owner 正确仍缺权限时):
icacls <目录> /grant <user>:(OI)(CI)F /T
# 4) 验证:重开会话触发 setup refresh,日志 errors=[] 即恢复(幂等,无需重装)
预期输出: 重开会话后沙盒日志无报错
装好确认:
- 日志里无 setup refresh 报错;
- 沙盒功能恢复正常。
卡住怎么办:
- 日志找不到 → 搜索日志文件名(Windows 侧沙盒日志目录,本环境实测 3 份日志路径与问题条目一致)。
- 补授权还报错 → 先改属主再补授权(顺序不能反)。
装完验收(一步到位)
作用:修完跑下面一条命令块,逐域复跑原报错命令,不再报权限错 = 该域验收通过;仍报错 → 回「逐步教学」对应步骤。
git -C <原报错仓库> status
npm config get prefix
ls -l ~/.ssh/id_ed25519
id # docker 组已加入(重开终端后生效)
预期输出: git status 正常;npm prefix 指向用户目录(非 /usr/local);私钥权限 600/400 级;用户已在 docker 组。git/SSH/npm/docker 四域实测过;Codex 沙盒域:重开会话后日志无报错
注:各域命令按你实际报错场景选跑;容器 uid 对齐用组合包第 5 步命令(挂载目录读写不再 Permission denied,实测)。
日常使用
启动与入口
- 无服务无进程:全部是配置/权限修复,改完即生效(沙盒需重开会话验证)。
常用操作
- 新仓库报 dubious ownership → 第 2 步白名单登记。
- 新密钥 too open → 第 4 步收紧权限(挂载盘特判)。
- npm 全局装 EACCES → 第 3 步 prefix 改用户目录。
- 沙盒 setup refresh 报错 → 第 6 步日志定位 + 授权修复。
数据与目录
- git:用户级 gitconfig(白名单);npm:用户级 npmrc + 用户 npm-global 目录;SSH:~/.ssh/;Codex:Windows 侧沙盒日志目录。
卸载与清理
本组合包是权限修复方案(无安装物),还原项按需:
# git:移除白名单登记
git config --global --unset-all safe.directory
# npm:还原 prefix
npm config delete prefix
# SSH:还原权限(一般不需要)
# Codex:授权还原(一般不需要;授权不是卸载)
提示:白名单与 prefix 是配置,删除即还原,无副作用。
安装顺序
- 通用定位先行:确认是权限错(Permission denied/EACCES/too open/dubious ownership)而非环境错(daemon/端口,走 combo-docker-wsl-env)。
- 系统层权限修复:SSH 私钥与目录权限、WSL 挂载盘特判——这两个最通用,先排除。
- 工具层逐域修复:git 白名单 → npm prefix → Codex 沙盒授权 → Docker 容器 uid(docker 依赖 daemon 可达,排最后)。
依赖警告
- 冲突:本组合包 5 条修复彼此独立、无共享面,不与任何插件冲突;与 combo-docker-wsl-env(环境排查)互补,同一报错先走环境链、再走权限链。
- 版本:git 白名单提示需 git >= 2.35(本机实测 2.53.0);Docker 与 combo-docker-wsl-env 版本要求一致(>= 20.10)。
- 环境:WSL 挂载盘(/mnt/c)不支持 chmod——实测 chmod 600 后权限位仍不变,密钥必须复制到 WSL 内或 Windows 侧系统授权命令;Windows 原生 OpenSSH 走系统授权命令不走 chmod。
- 国内网络:本组合包几乎不涉及下载;唯一下载面是 npm 全局包,走 npmmirror 镜像(见 combo-mirror-setup)。
FAQ
- 怎么判断是权限错还是环境错? → 看报错关键字:Permission denied / EACCES / too open / dubious ownership = 权限链;daemon 不可达 / 端口冲突 = 环境链(combo-docker-wsl-env)。
- WSL 里 chmod 600 密钥还是 too open? → 挂载盘(/mnt/c)不支持 chmod(实测权限位不变);复制密钥到 WSL 内(~/.ssh/)再 chmod,或 Windows 侧系统授权命令。
- npm 全局装 EACCES 一劳永逸的办法? → prefix 改用户目录 + PATH(第 3 步推荐形态)。
- 这套排查实测过吗? → git/SSH/挂载盘三条实测(复现+修复);docker(daemon 不可达)与 npm(避免污染本机)如实标注未实测。
验证证据
每份组合包在隔离环境实测(冒烟 + 写面检查),未实测项在文中如实标注;实测日期见下方验证证据。
验证于 2026-08-29 · TTL 到期 —(180 天)
- 2026-08-29 实测(WSL Ubuntu,git 2.53.0 / node v22.22.1 / npm prefix=/usr/local):
- git-dubious-ownership 完整复现+修复:nobody 用户访问 root 属主仓库报 dubious ownership → 白名单登记后正常 ✅
- ssh-key-permissions 权限位:chmod 600 生效(644 → 600);挂载盘反例:/mnt/c 文件 chmod 600 后权限位不变 ✅
- codex-sandbox 日志定位步骤:Windows 侧沙盒日志目录存在 3 份日志(08-17/20/21),路径与问题条目一致 ✅
- docker-volume-permission 未实测:本机 daemon 不可达(见 combo-docker-wsl-env 组合包实测记录)
- npm-global-eacces 未实测修复(避免污染本机 npmrc);只读证据:npm prefix 默认 /usr/local(EACCES 高发默认值)
- 证据文件:实测复现日志(2026-08-29)