berylliumsec/safe-galaxy

GitHub: berylliumsec/safe-galaxy

一款基于Rust的包安装时行为检测工具,通过沙箱化重放、AST能力提取和语义分析在依赖安装阶段实现实时安全干预与审批。

Stars: 0 | Forks: 0

# safe-galaxy ![safe-galaxy](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/e3b7f08ec5151641.png) ![safe-galaxy 营销视频](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/68ed297f38151707.gif) 实际运行中的交互式安装审查与运行时批准。请参阅 [`docs/demo/terminal-recording.md`](docs/demo/terminal-recording.md) 以了解 录制工作流和源脚本。 致谢 首先我要感谢全知全能的上帝,祂是一切知识的源泉;没有祂,这一切都不可能实现。 ## 概述 该 CLI 暴露了两个等效的入口点: - `safe-galaxy` - `sg` `safe-galaxy` 是一个以 Rust 为基础的包安装防护工具,侧重于: - 元数据驱动的包检查 - AST 能力提取 - 跨静态分析和运行时审计的第一方语义推理 - 面向开发者的、安装期间的实时行为审查 - 为 `pip`、`uv` 和 `pnpm` 生成安装计划 - 在每个包管理器阶段通过 `bubblewrap` 执行防护安装,并在最终重放时加上 Landlock - 为沙箱阶段提供可选的 syscall 追踪 - 为敏感的宿主机根目录提供可选的运行时路径批准提示 - 在受防护的安装重放之前进行分阶段的构件分析 许多依赖安全工具主要依赖于历史信号,例如 公告、声誉或预计算的包风险。`safe-galaxy` 增加了实时 安装干预:它在重放前暂存并分析构件,在受防护的执行下运行 真实的包管理器阶段,展示实际发生的具体 行为,并在安装 发生时推荐或执行决策。目标不仅是说“这个包看起来有风险”, 而是帮助开发者了解包在安装时做了什么, 在上下文中展示该行为,并让他们在相关 证据已显示在屏幕上的情况下阻止或允许它。 `safe-galaxy` 以 Linux 为优先,现在默认采用严格的、失败即关闭的行为。 每个安装阶段都在受防护的执行路径下运行,获取阶段只有在计划明确 要求时才可能使用网络,并且重放/安装阶段 在命令级别必须是离线的。下载的存档文件在 最终重放运行之前会被暂存并 扫描。暂存的发现随后可以映射到 `allow`、`warn`、`ask` 或 `block`,持久的交互式批准存储在 托管的用户状态中,使用按管理器、版本和语义风险范围划分的键。 重复安装会重用 来自本地缓存的以构件哈希为键的分析结果,前提是存档 内容和分析配置文件没有发生改变。 ## 安装 使用 Cargo 从源码安装: ``` cargo install --git https://github.com/berylliumsec/safe-galaxy --locked ``` 验证二进制文件: ``` sg --help ``` 如果你更倾向于在检出目录中运行而不是全局安装,请使用: ``` cargo run -- --help ``` Linux 发布版 tarball 还附带提供了 `sg` 和 `safe-galaxy` 二进制文件以及 基准测试入门资产。 ## 快速开始 分析当前目录树: ``` sg analyze . ``` 检查本地包路径: ``` sg assess path tests/fixtures/corpus/suspicious-js ``` 针对包管理器运行安装计划: ``` sg install -m pip -p ./.venv/bin/python requests==2.32.3 ``` 如果你想要基准测试页面,请访问 `https://safe-galaxy.berylliumsec.com`。 ## 功能特性 - 分析包或项目目录树的元数据信号: - `package.json` 安装钩子和入口点 - `pyproject.toml` 构建后端和脚本 - 原生构件,如 `.so`、`.dll`、`.dylib`、`.node` 和 `.exe` - 解析轻量级的原生二进制元数据以获取 ELF 优先的语义信息: - 导入和导出 - 节和构造函数/init-array 标记 - 动态加载器引用 - 有界的可打印字符串 - 使用 Tree-sitter 解析 Python、JavaScript、TypeScript 和 TSX 源码 - 使用 AST 访问器和全文件规范化匹配扫描 JavaScript/TypeScript 源码,这样即使是经过压缩或重新格式化的成员链访问也能浮现出来 - 在能力提取之前,当明显的嵌入式 JavaScript 十六进制/base64 载荷、`atob(...)` 和 `String.fromCharCode(...)` 载荷与动态执行接收器或混淆标记配对时,对其进行解码 - 将 `package.json` 元数据视为第一类证据,用于: - 生命周期钩子 - 直接 URL 支持的依赖项 - 发布自动化 - 面向持久化的命令 - 浮现面向能力的信号,例如: - 进程执行 - Shell 执行 - 网络访问 - 环境访问 - 携带敏感信息的认证或环境素材访问 - 宿主机指纹识别 - 直接 URL 依赖检索 - 混淆的加载器行为 - 动态代码执行 - 原生库加载 - 文件系统写入 - 敏感路径访问 - 派生语义发现,例如: - 安装钩子执行 - 出站网络能力 - 回传意图 - 凭证窃取意图 - 混淆的执行链 - 原生二进制进程或网络能力 - 本地 IPC 活动 - 重放/安装阶段期间归因于包的外部网络活动 - 敏感文件读写 - 已确认的跨源运行时行为 - 为以下项生成安装计划: - `pip` - `uv` - `pnpm` - 无需安装重放即可评估确切的依赖版本,适用于: - 使用 `npm pack` 获取的 Node 包 - 使用 `python -m pip download --no-deps` 获取的 Python 包 - 执行受防护的安装流程: - 沙箱化的 `resolve` - 沙箱化的 `prefetch` - 暂存的存档提取及分析 - 可选的终端审计审查 - 沙箱化的离线 `install` - 运行操作检查和维护: - `sg doctor` - `sg gc` - `sg mcp` ## 命令参考 分析源码目录树: ``` sg analyze . ``` 从源码分析: ``` cargo run -- analyze . ``` 输出 JSON: ``` sg --format json analyze . ``` 评估本地包路径或存档: ``` sg assess path . sg -f json assess path tests/fixtures/corpus/suspicious-js ``` 在不重放安装的情况下评估确切的依赖版本: ``` sg assess dependency --ecosystem python --name requests --version 2.32.3 sg assess dependency --ecosystem node --name kleur --version 4.1.5 ``` 选择特定的 Python 解释器进行包获取: ``` sg assess dependency -e python -p ./.venv/bin/python -n requests -v 2.32.3 ``` 构建安装计划: ``` sg plan -m pip requests==2.32.3 sg plan -m uv requests==2.32.3 sg plan -m pnpm -r . ``` 在没有配置文件的情况下运行受防护的安装: ``` sg install -m pip -p ./.venv/bin/python requests==2.32.3 ``` 在没有配置文件的情况下运行交互式受防护的安装: ``` sg -i install -m pip -p ./.venv/bin/python requests==2.32.3 ``` 最常用的标志提供了常见的短别名: `-i` = `--interactive`,`-c` = `--config`,`-b` = `--best-effort`, `-f` = `--format`,`-m` = `--manager`,`-p` = `--python`,`-a` = `--audit`, `-s` = `--allow-scripts`。 安装命令垫片(shims),以便正常的包管理器安装命令通过 `safe-galaxy` 进行路由: ``` sg -i shim install export PATH="$HOME/.local/bin:$PATH" ``` `sg shim install` 会将当前的 `--config`、`--interactive` 和 `--best-effort` 设置固化到生成的包装器中,因此在安装垫片时,请使用你希望正常的 `pip`、`uv` 或 `pnpm` 使用所继承的默认值。 当 Python virtualenv 处于活动状态时,`sg shim install` 会定位到该环境的 `bin/` 目录,因此 `pip` 拦截可以在活动环境内工作,并且 它会保留原始启动器,以便在执行 `sg shim uninstall` 时进行恢复。 之后,正常的安装命令就会被拦截: ``` pip install requests==2.32.3 uv pip install requests==2.32.3 pnpm install ``` 垫片可包装: - `pip install ...` - `pip3 install ...` - `uv pip install ...` - `pnpm install ...` 非安装命令(例如 `pip list`、`uv venv` 或 `pnpm run`)会被委派 给垫片背后的真实工具。 移除已安装的垫片: ``` sg shim uninstall ``` 在垫片移除后,卸载已安装的 `sg` / `safe-galaxy` 二进制文件: ``` sg uninstall ``` 为当前宿主机运行严格的预检: ``` sg doctor ``` 清理临时缓存状态: ``` sg gc sg gc --all ``` 通过 syscall 追踪运行受防护的安装: ``` sg --interactive install --audit --manager pip --python ./.venv/bin/python requests==2.32.3 ``` 对于 `pip`,目标解释器必须支持 `pip install --dry-run`。如果 系统 Python 附带的是较旧版本的 `pip`,请将 `--python` 指向更新的环境,或者 先在那里升级 `pip`。 当高级配置定义了运行时批准路径时,为受防护的安装启用运行时批准: ``` sg --config ./examples/advanced-config.yaml install --manager pip --runtime-approval --python ./.venv/bin/python requests==2.32.3 ``` 从 YAML 或 JSON 加载高级策略: ``` sg --config ./examples/advanced-config.yaml analyze . sg --config ./examples/advanced-config.yaml install --manager pip --python ./.venv/bin/python requests==2.32.3 ``` 当你希望在本地开发期间绕过严格的失败即关闭 检查时,显式允许尽力而为(best-effort)模式: ``` sg --best-effort install --manager pip --python ./.venv/bin/python requests==2.32.3 ``` 运行 stdio MCP 服务器: ``` sg mcp sg -c ./examples/advanced-config.yaml mcp ``` 向 Codex 或 Claude Code 注册 MCP 服务器: ``` sg mcp register codex sg mcp register claude-code sg -c ./examples/advanced-config.yaml mcp register codex ``` ## 评估契约 `sg assess` 在 JSON 模式下发射 schema 版本 `safe-galaxy.assessment-result.v2`。 `report` 载荷包含: - `subject` - `risk_level`:`low`、`medium` 或 `high` - `recommended_action`:`allow`、`review` 或 `block` - `attention_level` - `posture` - `summary` - `reasons` - `evidence` - `environment_variables`:在静态可恢复时的确切环境变量名 - `network_endpoints`:字面 URL 或观察到的运行时端点 - `sensitive_paths`:在可恢复时的确切敏感路径字符串 - `secret_indicators`:确切的无值秘密标识符,如环境变量名或认证标记 - `semantic_ids` - `artifact_count` - 请求 `include_raw_report` 时的 `raw_report` `risk_level` 是有意从现有的语义关注级别 和策略决策中派生出来的,而不是一个单独的不透明分数: - `low-attention` 加 `allow` => `low` - `review` 关注级别或 `warn`/`ask` => `medium` - `high-attention` 或 `block` => `high` 确切的依赖评估是非变异的。它获取包存档, 暂存它们,分析它们,并在不运行受防护的 安装重放的情况下应用策略阈值。 ## MCP 接口 `sg mcp` 提供两个 stdio MCP 工具: - `assess_dependency` - 输入:`ecosystem`、`name`、`version`、可选的 `python_path`、可选的 `include_raw_report` - `assess_path` - 输入:`path`、可选的 `include_raw_report` 这两个工具都返回与 `评估契约` 形状相同的结构化 JSON。 服务器级别的策略在进程启动时通过正常的全局 `--config` 标志加载一次。 ## 客户端入门 `safe-galaxy` 是 MCP 优先的。标准用户流程是: 1. 使用 `cargo install --git https://github.com/berylliumsec/safe-galaxy --locked` 安装 `sg`,或使用 Linux 发布版 tarball。 2. 验证 `sg --help` 是否有效。 3. 使用 `sg mcp register ` 注册服务器,或手动复制匹配的模板。 4. 重启客户端或编辑器。 5. 要求代理调查一个包。 在安装后,AI 代理可以执行的最快且最简单的路径 是让 `sg` 为你编写客户端配置: ``` sg mcp register codex sg mcp register claude-code ``` `sg mcp register codex` 会更新 `~/.codex/config.toml`。 `sg mcp register claude-code` 会更新当前项目中的 `.mcp.json`。 这两个命令都会写入一个 `safe-galaxy` MCP 条目,并保留不相关的现有 客户端配置。 如果你倾向于手动注册,代码库和 Linux 发布包 在 `examples/mcp/` 下包含了可随时复制的模板。除非 你确定 `sg` 位于客户端的 `PATH` 中,否则默认使用绝对路径 模板。 Codex: - Codex CLI 和 Codex IDE 扩展共享 `~/.codex/config.toml`。 - 使用以下之一: - `examples/mcp/codex/config.absolute.toml` - `examples/mcp/codex/config.path.toml` Claude Code: - 使用以下之一: - `examples/mcp/claude-code/mcp.absolute.json` - `examples/mcp/claude-code/mcp.path.json` - 将选定的 JSON 模板复制到项目根目录中的 `.mcp.json`。 注册命令支持相同的高级启动形式。例如, 这会写入一个在启动时加载策略的 Codex 条目: ``` sg -c ./examples/advanced-config.yaml mcp register codex ``` 如果你希望模型更可靠地优先选择此服务器,请将 `examples/mcp/project-instructions.md` 中的代码片段添加到你的项目指导文件中。 Codex 配置示例: ``` [mcp_servers.safe-galaxy] command = "/ABSOLUTE/PATH/TO/sg" args = ["mcp"] ``` Claude Code 配置示例: ``` { "mcpServers": { "safe-galaxy": { "command": "/ABSOLUTE/PATH/TO/sg", "args": ["mcp"] } } } ``` 要在服务器启动时加载策略文件,请将参数更改为: ``` --config /ABSOLUTE/PATH/TO/advanced-config.yaml mcp ``` ### 代理如何发现它 客户端启动 `sg mcp` 后,它会通过 MCP `tools/list` 请求服务器的工具目录。这就是代理了解到 `-galaxy` 暴露了 `assess_dependency` 和 `assess_path` 的方式。 MCP 是产品界面。技能包装器是可选的,Codex 或 Claude 调用 服务器并不需要它。 ### 提示示例 一旦配置了 MCP 服务器,像这样的提示应该可以工作: - `Investigate the npm package kleur version 4.1.5 and tell me whether I should allow, review, or block it.` - `Investigate the Python package requests version 2.32.3 and summarize the evidence behind the recommendation.` - `Analyze this local package path and tell me if it deserves review before install.` - `Use safe-galaxy to assess this dependency and explain the risk level, recommended action, and key findings.` ## 发布构建 已合并的发布 PR 会将 Linux tarball 和校验和发布到 `main` 分支工作流 [`.github/workflows/release-linux.yml`](.github/workflows/release-linux.yml) 中的 `v` GitHub Release。 该工作流从 `Cargo.toml` 中读取 `package.version`。要从 PR 中发布新版本, 请在合并前在 `Cargo.toml` 中升级版本。 要使用 Cargo 安装而不使用 crates.io: ``` cargo install --git https://github.com/berylliumsec/safe-galaxy --locked sg --help ``` 稍后要移除已安装的二进制文件: ``` sg shim uninstall sg uninstall ``` 你仍然可以在本地复现 Linux 发布打包: ``` bash scripts/release/package-linux.sh v0.1.0 ``` 这会创建包含以下内容的 `dist/` 输出: - 名为 `safe-galaxy--.tar.gz` 的 tarball - 解压后的 `safe-galaxy` 和 `sg` 二进制文件 - `examples/advanced-config.yaml`,用于路径繁重的配置 - `examples/mcp/`,包含 Codex 和 Claude 入门模板 - `checksums.txt`,包含二进制文件和 tarball 的 SHA-256 摘要 验证本地构建: ``` sha256sum -c dist/checksums.txt tar -xzf dist/safe-galaxy-v0.1.0-x86_64-unknown-linux-gnu.tar.gz -C /tmp /tmp/safe-galaxy-v0.1.0-x86_64-unknown-linux-gnu/sg --help ``` 将打包好的发布版安装到 `~/.local/bin`: ``` bash scripts/release/install-local.sh dist/safe-galaxy-v0.1.0-x86_64-unknown-linux-gnu.tar.gz ~/.local/bin/sg --help ``` 安装程序还会将入门资产复制到: ``` ${XDG_DATA_HOME:-$HOME/.local/share}/safe-galaxy/examples/mcp ``` 如果需要,将 `~/.local/bin` 添加到 `PATH`: ``` export PATH="$HOME/.local/bin:$PATH" ``` ## 配置 配置是可选的。正常流程是: - `sg install ...` - `sg --interactive install ...` - `sg --interactive install --audit ...` 仅在你需要高级行为(例如)时才使用配置文件: - 运行时批准路径 - 沙箱读/写/环境覆盖 - 高级策略调整或特定于项目的共享包覆盖 高级配置示例(`examples/advanced-config.yaml`): ``` best_effort: false mode: interactive analysis: max_file_size_bytes: 262144 ignored_directory_names: - .git - target - node_modules - dist - build sandbox: network_default: controlled read_allow: - ${PROJECT_ROOT} - ${CACHE_DIR} write_allow: - ${PROJECT_ROOT} - ${CACHE_DIR} allow_protected_paths: - ${HOST_HOME}/.aws deny_env: - SSH_AUTH_SOCK - AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY - GITHUB_TOKEN audit: mode: optional runtime_approval: mode: optional paths: - ${HOST_HOME}/.ssh - ${HOST_HOME}/.aws prompt_on: - open-read - open-exec - dir-open decision_scope: session policy: semantic_thresholds_by_attention: low_attention: allow review: ask high_attention: ask semantic_threshold_overrides: semantic.external-egress: block thresholds: install_hooks: ask native_artifacts: ask high_severity: ask medium_severity: warn low_severity: allow package_overrides: pip:trusted-package@1.2.3|semantic:semantic.network-capable-package: decision: allow note: approved interactively ``` 默认值: - `mode: fail-closed` - `best_effort: false` - `sandbox.network_default: controlled` - 受保护的宿主机机密路径默认拒绝,仅在 `--interactive` 模式下提供单次运行批准 - 除非明确请求,否则禁用审计和运行时批准 - 托管批准在存在时从 `${XDG_STATE_HOME:-$HOME/.local/state}/safe-galaxy/approvals.yaml` 加载 当 `best_effort` 为 `false` 时,缺少 `bwrap`、缺少包管理器 可执行文件、缺少审计/运行时批准依赖,或不支持 Landlock,都会在执行开始前中止安装。 ## 策略行为 - `allow`:继续,不执行额外操作。 - `warn`:继续,并打印从暂存分析中收集到的原因。 - `ask`:在 `interactive` 模式下需要交互式终端;持久的批准会写入托管用户状态。 - `block`:在沙箱重放运行之前停止安装。 策略评估发生在暂存构件提取之后以及最终的 离线安装阶段之前。语义发现现在驱动默认的审查路径, 而遗留的严重性阈值在没有语义发现 存在时仍作为后备。持久化的批准由管理器、规范化的包键、 包版本以及触发提示的稳定语义发现 ID 集作为键, 并且它们按用户和项目根目录存储在托管状态中。 交互式审查呈现明确的风险事实,而不是安全/恶意的判决, 并且每当存在审查或高关注度发现时,默认突出显示 `Block`。 ## 沙箱策略 `safe-galaxy` 现在通过显式绑定挂载来构建沙箱文件系统,而不是 将整个宿主机根目录以只读方式绑定。因此,`read_allow` 和 `write_allow` 控制着沙箱阶段真实的文件系统可见性。 - 相对路径从 `${PROJECT_ROOT}` 解析。 - 支持的路径 token 有 `${PROJECT_ROOT}`、`${CACHE_DIR}`、`${TMPDIR}`、`${SANDBOX_HOME}` 和 `${HOST_HOME}`。 - 如果可写路径尚不存在,则会按需创建。 - `allow_protected_paths` 是针对精确内置受保护根目录(如 `${HOST_HOME}/.ssh`)的显式逃生舱;父目录和非目录路径将被拒绝。 - `deny_env` 在沙箱运行时应用其所需覆盖(例如 `HOME` 和 `TMPDIR`)之前过滤宿主机环境。 - 安装流程仍然需要访问项目根目录和缓存目录;移除其中任何一个都会在执行开始前失败。 - `${HOST_HOME}` 下常见的携带凭证的路径默认被阻止。在每个受防护的阶段之前,`safe-galaxy` 会检查有效的挂载计划是否会暴露其中一个根目录。在 `interactive` 模式下,它会针对当前运行的每个路径提示一次;在交互模式之外,除非明确允许了确切的根目录,否则它会失败并关闭。 - 仍然被阻止的受保护根目录也会被空文件或目录覆盖层屏蔽,作为纵深防御,即使更广泛的绑定挂载(如工具前缀)会暴露它们。 - 内置的受保护集涵盖了 SSH、云 CLI、容器、Kubernetes、Git、Terraform、Cargo、Ruby、npm、pip、Poetry 和 `.env` 风格的用户机密。 - 在受支持的 Linux 内核上,最终的安装重放还会应用从相同读/写策略派生的 Landlock 路径规则,在发生变异的子进程内增加内核级别的文件系统防护。 - 每次安装运行现在都会在 `${CACHE_DIR}/runs/` 下获得自己的沙箱工作区,因此像沙箱主目录和 tmp 目录这样的临时状态不会跨运行重用。 - 会改变相同共享缓存或相同目标环境的并发安装,会在执行开始前使用宿主机端咨询锁进行串行化。 - `resolve` 和 `prefetch` 阶段现在在与最终重放相同的受防护隔离模型中运行,带有特定于阶段的可写挂载和显式网络策略验证。 - `uv` 阶段在沙箱内默认使用 `UV_LINK_MODE=copy`,以避免在隔离的缓存/工作区布局中出现跨文件系统的硬链接问题。 - `sandbox.audit.mode: disabled|optional|required` 控制沙箱阶段是否被 `strace` 包装,并在 `${CACHE_DIR}/audit//` 下写入 syscall 追踪。 - 审计追踪当前包含 `file`、`process` 和 `network` syscall。这是有意设为选择性加入(opt-in)的,因为它会增加可衡量的开销。 - 当审计审查运行时,`safe-galaxy` 首先将安装重放到一个临时目标中,然后呈现一个终端审查,其开头为: - `Attention level` - `Confirmed across sources` - `Observed during install` - `Present in the package` - `Observed runtime details` - 交互式审查和受保护机密批准屏幕现在使用 `ratatui` 替代屏幕界面,带有决策窗格、可滚动的详细信息窗格以及安全的 `Esc`/`q` 取消操作(回退到 `Block`)。UI 可以绑定到 `stdout`、`stderr` 或 `/dev/tty`,因此重定向 stdout 不会抑制审查屏幕。 - 默认的终端审查现在隐藏了低级别的追踪计数器和其他空白部分。它专注于能够改变开发者决策的浮现行为,并且当观察到敏感读取、外部网络操作、拒绝或提权执行时,它会包含确切的预览以及下方的详细表格。 - 语义发现行现在保持当前的节布局,但最多显示两行优先级证据。源路径证据被渲染为短尾部加上独立的完整文件系统路径,条目之间有分隔线,因此终端可以干净地链接路径,开发者可以看到具体观察到的动作、进程、端点或源位置,而无需在较低的表格中寻找。 - 回环和 unix 套接字监听器活动作为本地 IPC 上下文仍然可见,但它与非本地网络发现保持分离。 - 原始 syscall 计数、完整的追踪文件和审计 JSON 仍然存在于磁盘上的 `${CACHE_DIR}/audit//` 中,但它们不再打印在默认的交互式审查中。 - 每个审计阶段还会在 `*.summary.json` 处写入一个稳定的 JSON 摘要,使用 schema 版本 `safe-galaxy.audit-summary.v3`。 - 敏感路径发现仅针对观察到或被拒绝的访问发出,而不针对普通的缺失文件探测(例如针对包管理器配置文件的 `ENOENT` 检查)发出。 - 原始的包管理器 stdout/stderr 被捕获在 `${CACHE_DIR}/runs//phase-output/` 下。成功的阶段默认保持安静;失败时 `safe-galaxy` 会打印简短的摘录并指向完整的日志。 - 安装进度现在会打印共享缓存扫描、暂存构件分析、审计审查重放和每个受防护阶段的启动标记,因此长时间运行的 `resolve` 或 `prefetch` 工作在完成之前是可见的。 - 分阶段的安装分析现在会记录每个构件的推断 `artifact_form` 和 `behavior_class`,并且交互式审查会在语义发现之前打印这些配置文件。内置的配置文件当前可区分纯 JS、纯 Python wheels、源码构建、原生扩展、浏览器自动化、二进制供应商、模型/数据包和服务 SDK。 ## 运行时批准 `safe-galaxy` 可以选择在静态沙箱之上分层运行时路径批准: - `runtime_approval.mode: disabled|optional|required` 控制代理是关闭、尽力而为还是失败即关闭。 - `runtime_approval.paths` 列出了仅在运行时批准激活时才应可见的敏感根目录。 - `prompt_on` 支持 `open-read`、`open-exec` 和 `dir-open`。 - v1 决策范围是 `session`,因此批准仅为当前安装运行缓存。 - 运行时批准提示和 `runtime-approval.jsonl` 审计条目包含人类可读的原因,说明为什么请求的路径受到限制。 - 在你回答运行时批准提示后,`safe-galaxy` 会在沙箱阶段继续或展开时打印简短的状态行。 - 受防护的重放和审计子进程将 stdout/stderr 捕获到日志,并且不继承终端 stdin,因此交互式批准保留在 `safe-galaxy` 中,并且包管理器提示不能接管 Shell。 - `safe-galaxy` 还会在安装命令退出之前恢复调用者 tty 状态,因此受防护的子进程不能在提示或阶段失败后将你的 Shell 保留在原始模式。 - 该代理仅限 Linux 并使用 `fanotify`,因此它需要以 `root` 身份运行 `safe-galaxy`,或为隐藏的代理辅助程序使用无密码的 `sudo -n`。 - 如果启用了运行时批准,`safe-galaxy` 现在会在执行开始前预检权限和终端要求。 - 如果运行时批准为 `required` 或传递了 `--require-runtime-approval`,当代理、权限边界或终端不可用时,安装会在任何受防护阶段之前中止。 - 当同时启用沙箱审计时,运行时批准提示和决定也会写入 `${CACHE_DIR}/audit//runtime-approval.jsonl`。 ### 端到端流程 当你在启用受防护阶段和运行时批准的情况下运行 `sg install` 时, 完整流程是: 1. `safe-galaxy` 构建安装计划,验证先决条件,并为安装目标和共享缓存获取宿主机端锁。 2. 它暂存安装构件,运行静态分析,并在任何变异重放开始之前应用策略。 3. 对于每个受防护阶段,它会在 `${CACHE_DIR}/runs//` 下创建一个每次运行的工作区,构建显式的 bubblewrap 挂载计划,并将子进程的 stdout/stderr 捕获到 `phase-output/*.stdout.log` 和 `phase-output/*.stderr.log` 中。 4. 受保护的宿主机机密根目录和运行时批准监视的根目录被单独处理: `allow_protected_paths` 是内置受保护根目录的显式运行前逃生舱,而 `runtime_approval.paths` 启用对阶段期间确切监视根目录的每次访问批准。 5. 如果运行时批准处于活动状态,父 `safe-galaxy` 进程会启动一个短路径主管套接字,派生特权 Linux 代理,并为自己保留终端。受防护的子进程没有交互式 stdin,在它们自己的会话中运行,因此不能拥有或破坏调用者 TTY。 6. 当监视路径被触碰时,代理会发出权限请求,其中包含具体路径、访问类型、进程元数据,以及该路径受限的目录原因。父进程呈现 Ratatui 审查屏幕并默认为Block`。 7. `Allow once` 仅授予该会话范围的批准桶;`Block`、`Esc`、中断或超时会拒绝访问。拒绝时,受防护的子进程会看到访问失败,并且阶段以非零状态退出。 8. 决定之后,`safe-galaxy` 打印一条简短的交接行,完成阶段的展开或继续,在命令退出之前恢复调用者 tty 状态,并为下一个命令保留 Shell 交互。 ### 磁盘上的构件 - `${CACHE_DIR}/runs//phase-output/` 包含每个受防护阶段的原始包管理器 stdout/stderr。 - `${CACHE_DIR}/audit//runtime-approval.jsonl` 在启用沙箱审计时记录运行时批准提示和决定。 - `${CACHE_DIR}/audit//*.summary.json` 在启用审计时包含重放阶段的稳定审计摘要。 ### 在受保护路径和运行时批准之间做出选择 - 当你希望确切的内置宿主机机密根目录在整次运行中预先暴露时,请使用 `sandbox.allow_protected_paths`。 - 当你希望路径默认保持拒绝状态,并且仅在显式运行时决定后才变得可读或可遍历时,请使用 `runtime_approval.paths`。 - 你可以在同一配置中为不同的根目录同时使用两者,但它们 解决不同的问题:一个是挂载时异常,另一个是 每次访问的关卡。 有关本地端到端路径提示演示,请使用 `examples/runtime-approval/` 中的示例包,并遵循 [`examples/runtime-approval/README.md`](examples/runtime-approval/README.md)。 对于你可以立即分析并可选择在启用审计的情况下 通过受防护的安装进行重放的本地 Node 和 Python 能力演示,请使用 `examples/detection-demo/`,并遵循 [`examples/detection-demo/README.md`](examples/detection-demo/README.md)。 ## 分析缓存 暂存的构件分析缓存在 `${CACHE_DIR}/analysis-cache/` 下,使用: - 存档内容的 BLAKE3 哈希 - 从分析配置和分析器版本派生的分析配置文件哈希 如果两者都匹配,分阶段的安装流程将重用缓存的报告,而不是 再次运行元数据和 AST 提取。存档仍然会为当前 安装流程进行暂存,但未更改的构件会跳过昂贵的扫描工作。 ## 开发者指南 发布、基准测试、发布构建和终端演示位于 [developer.md](developer.md) 中。 ## JSON 报告 - `sg analyze --format json` 发射 `safe-galaxy.analyze-report.v4` 它现在包含用于过大或不可读源及跳过的原生二进制文件的 `report.skipped_inputs`。 - `sg install --format json` 发射 `safe-galaxy.install-report.v6` - `sg doctor --format json` 发射 `safe-galaxy.doctor.v1` - `sg gc --format json` 发射 `safe-galaxy.gc-report.v1` - 每阶段审计摘要发射 `safe-galaxy.audit-summary.v3` ## 安全模型 - 支持的平台:仅限 Linux。 - 默认姿态:失败即关闭。 - `--best-effort` 是在严格先决条件不可用时用于本地调试的显式逃生舱。 - `--best-effort` 不会绕过受保护的宿主机机密强制执行;如果直接回退会暴露受保护的根目录,除非明确允许了确切的根目录,否则运行仍会被阻止。 - 获取阶段只有在计划要求且沙箱网络策略允许时才可能使用网络。 - 重放/安装阶段在命令级别必须是离线的。 - 运行时批准是选择性加入的,并且由于依赖于 `fanotify`,仍然仅限 Linux。 ## 支持矩阵 - `pip`:受防护的 resolve、受防护的 fetch、暂存的构件分析、可选的审计审查、受防护的离线 replay - `uv`:受防护的 resolve、受防护的 fetch/缓存预热、暂存的构件分析、可选的审计审查、受防护的离线 replay - `pnpm`:受防护的基于 lockfile 的项目安装、受防护的 fetch、获取存档时的暂存构件分析(如存在)、可选的审计审查、受防护的离线 replay - 宿主机操作系统:仅限 Linux ## 下一步计划 - 将 AST 提取扩展为规范化的能力图
标签:API接口, Bubblewrap, DNS 解析, Landlock, Node.js包管理, pip安全, pnpm安全, Python包管理, Rust, TLS抓取, uv包管理器, 依赖安全, 包管理器安全, 可视化界面, 威胁情报, 安全防护, 安装时检测, 开发者工具, 沙箱, 系统调用追踪, 网络流量审计, 软件安全, 运行时监控, 通知系统, 错误基检测, 零信任安装, 静态代码分析, 风险拦截