PEP 710 – 记录已安装软件包的来源

猫勺猫勺 03-16 198 阅读 0 评论

抽象

PEP 描述了一种记录已安装的 Python 发行版的来源的方法。 该记录由安装程序创建,可供以下用户使用 目录中 JSON 文件的形式。 提到的 JSON 文件捕获其他元数据,以允许将 URL 与已安装的分发哈希一起记录到分发包。这 提案建立在 PEP 610 之上,遵循其相应的规范 PyPA 规范和 与 for when 包互补 由名称和版本(可选)标识。provenance_url.json.dist-infodirect_url.jsonprovenance_url.json

赋予动机

安装 Python 项目涉及从包索引下载分发包并将其内容提取到适当的位置。安装后 过程完成,有关使用的发布工件及其来源的信息 一般是丢失的。但是,有一些用例可以保留以下记录 用于安装软件包及其来源的发行版。

Python 轮子可以使用不同的编译器标志或支持来构建 不同的车轮标签。在这两种情况下,用户都可能遇到以下情况: 安装人员可能会考虑使用多个轮子(可能来自不同的 包索引),并立即找出实际使用的 wheel 文件 在安装过程中可能会有所帮助。这样,开发人员可以使用 有关轮子的信息,以调试问题,确保所需的轮子是 实际安装。另一个用例可能是工具报告软件 已安装,例如报告 SBOM(软件物料清单)的工具,可能会 提供更准确的报告。另一个用例可能是重建 Python 环境,将每个已安装的包固定到特定发行版 从 Python 包索引中使用的项目。

理由

本 PEP 中描述的动机是 PEP 610 中的动机的扩展。 除了记录使用直接 URL 安装的软件包的出处信息外, 安装程序也应该对按名称安装的软件包执行此操作 (以及可选的版本)来自 Python 包索引。

此 PEP 中描述的想法起源于一个名为 micropipenv 的工具,该工具用于在容器化中安装分发包 环境(请参阅报告的问题 thoth-station/micropipenv#206)。 目前,组装好的容器化应用程序不隐式携带 有关已安装分发包的来源的信息 (除非这些是从完整的 URL 安装并通过 记录的)。 这需要容器镜像供应商链接 容器映像及其相应的构建过程、其配置和 用于在以下情况下检查需求文件的应用程序源代码 容器化环境中存在的软件需要进行审核。direct_url.json

随后在话语线程中的讨论也被提出 pip 的新选项,可以生成详细的 JSON 报告 安装过程。此选项可以帮助解决出处问题 这种 PEP 方法。但是,需要显式传递此选项 到 pip 以获取出处信息,并包含其他元数据 检查出处可能不是必需的(例如 Python 版本 每个分发包的要求)。此外,此选项是 在撰写此 PEP 时特定于 pip。--report

请注意,用于记录已安装软件包的当前规范定义了一个文件 记录已安装的文件,但不记录这些文件的分发工件 获取了文件。可以审核已安装的项目 基于匹配文件中列出的条目。然而,这 该技术需要一个预先计算的文件数据库,其中包含每个工件提供的文件或 与实际工件内容的比较。这两种方法都是相对的 昂贵且耗时的操作,可以通过 建议的文件。RECORDRECORDprovenance_url.json

记录已安装分发包的出处信息, 从直接 URL 和索引中按名称/版本获取的那些, 可以简化对 Python 环境的一般审计,而不仅仅是 前面提到的容器化应用程序的特定用例。 社区项目 pip-audit 提高了他们对 pypa/pip-audit#170 的可能兴趣。

规范

关键词“必须”、“不得”、“必需”、“应该”、“应该”、“必须 “不应”、“推荐”、“可以”和“可选” 本文档中的说明将按照 RFC 2119 中的说明进行解释。

安装由名称(可选)指定的分发包时,安装程序应在目录中创建该文件(也可以由版本说明符指定)。provenance_url.json.dist-info

从要求安装分发包时,不得创建此文件 指定直接 URL 引用(包括 VCS URL)。

只有一个文件和(来自 PEP 610), 可能存在于给定目录中;安装人员不得同时添加两者。provenance_url.jsondirect_url.json.dist-info

JSON 文件必须是字典,符合 RFC 8259 和 UTF-8 编码。provenance_url.json

如果存在,它必须恰好包含两个键。第一个是 ,带有 类型。第二个键必须具有定义的值 下面。urlstringarchive_info

密钥的值必须是从中下载分发包的 URL。如果轮子是 从源代码分发构建,值必须是 URL 源分发已下载。如果直接下载并安装轮子, 该字段必须是下载轮子的 URL。 与直接 URL 源规范中一样,值 出于安全原因,必须去除任何敏感的身份验证信息。urlurlurlurl

但是,URL 的 user:password 部分可以由 environment 组成 变量,匹配以下正则表达式:

\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?

此外,URL 的 user:password 部分可能是一个众所周知的, 非安全敏感字符串。一个典型的例子是 URL,例如 .gitssh://git@gitlab.com

MUST 的值必须是具有单个键的字典。的值是将哈希函数名称映射到 值引用的文件的十六进制编码摘要。多个哈希值 可以包含,由消费者决定如何处理 多个哈希值(它可以验证所有哈希值或其中的子集,或者不验证任何哈希值 全部)。archive_infohasheshashesurl

每个哈希值必须是 提供的单个参数哈希值之一,不包括 和 不得使用。 从 Python 3.11 开始,包含和排除 对于多参数,允许的哈希集为:sha1md5shake_128shake_256

>>> import hashlib>>> sorted(hashlib.algorithms_guaranteed - {"shake_128", "shake_256", "sha1", "md5"})['blake2b', 'blake2s', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512']

每个哈希值必须由哈希值的规范名称引用,始终小写。

出于安全性考虑,哈希值和 MUST NOT 存在 这些哈希算法的局限性。相反,哈希应该 被包括在内。sha1md5sha256

从索引缓存分发包的安装程序应保留 与缓存的分发工件相关的信息,以便 即使在安装分发包时也可以创建该文件 从安装程序的缓存中。provenance_url.json

向后兼容

按照录制已安装项目规范, 安装程序可以在目录中保留其他特定于安装程序的文件。确保此 PEP 不会导致任何向后兼容性 问题,对安装程序和库的全面调查发现,当前没有使用类似名称文件的工具, 或其他重大可行性问题。.dist-info

Wheel 规范列出了可以 存在于目录中。这些文件名均不与 来自此 PEP 的建议文件。.dist-infoprovenance_url.json

安装程序和库中存在provenance_url.json

对现有安装程序、库和依赖项的全面调查 Python 生态系统中的管理人员分析了为每个工具添加支持的影响。 总之,没有重大的向后兼容性问题、冲突或可行性障碍 在撰写本文时发现 PEP。有关调查的更多详细信息 可以在附录:安装人员和库的调查部分找到。provenance_url.json

与direct_url.json的兼容性

此提案不会对文件进行任何更改 在 PEP 610 及其相应的规范 PyPA 规范中进行了描述。direct_url.json

文件内容的设计方式最终 允许安装程序重用一些逻辑支持当 直接 URL 是指源存档或轮子。provenance_url.jsondirect_url.json

和 文件之间的主要区别在于文件中的必需键及其值。 这有助于确保文件的使用者可以依赖 如果文件存在于目录中,则在其内容上。provenance_url.jsondirect_url.jsonprovenance_url.jsonprovenance_url.json.dist-info

安全隐患

该文件的主要安全功能之一是 能够在 Python 环境中审核已安装的工件。工具可以检查 哪些 Python 包索引用于安装 Python 发行版 包及其发布的哈希摘要 工件。provenance_url.json

举个例子,我们可以把最近被破坏的依赖链放在 PyTorch 事件。 PyTorch 索引提供了一个名为 的包。攻击者 在运行恶意二进制文件的 PyPI 上发布。通过检查 文件中说明的已安装的 Python 发行版的 URL,工具可以自动检查 已安装的 Python 发行版。如果发生 PyTorch 事件,则 的 URL 应指向 PyTorch 索引,而不是 PyPI。工具可以提供帮助 通过检查 已安装 Python 分发 URL。更精确的检查还可以包括哈希值 文件中所述的已安装的 Python 发行版。对哈希的此类检查对于镜像的 Python 包索引很有帮助 其中 Python 发行版无法通过其源 URL 来区分,使 确保只安装所需的 Python 包发行版。torchtritontorchtritonprovenance_url.jsontorchtritonprovenance_url.json

恶意行为者可以故意调整内容,以可能隐藏 已安装的 Python 发行版。安全检查将发现此类情况 恶意活动超出了此 PEP 的范围,因为它需要监控 对文件系统执行操作,并最终查看用户或文件权限。provenance_url.json

如何教这个

元数据文件用于工具,而不是 对最终用户直接可见。provenance_url.json

例子

有效provenance_url.json示例

有效的列表多个哈希值:provenance_url.json

{  "archive_info": {    "hashes": {      "blake2s": "fffeaf3d0bd71dc960ca2113af890a2f2198f2466f8cd58ce4b77c1fc54601ff",      "sha256": "236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f",      "sha3_256": "c856930e0f707266d30e5b48c667a843d45e79bb30473c464e92dfa158285eab",      "sha512": "6bad5536c30a0b2d5905318a1592948929fbac9baf3bcf2e7faeaf90f445f82bc2b656d0a89070d8a6a9395761f4793c83187bd640c64b2656a112b5be41f73d"    }  },  "url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"}

列出单个哈希条目的有效列表:provenance_url.json

{  "archive_info": {    "hashes": {      "sha256": "236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f"    }  },  "url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"}

一个有效的源代码分发列表,用于 构建和安装轮子:provenance_url.json

{  "archive_info": {    "hashes": {      "sha256": "8bfe29f17c10e2f2e619de8033a07a224058d96b3bfe2ed61777596f7ffd7fa9"    }  },  "url": "https://files.pythonhosted.org/packages/1d/43/ad8ae671de795ec2eafd86515ef9842ab68455009d864c058d0c3dcf680d/micropipenv-0.0.1.tar.gz"}

无效provenance_url.json的示例

以下示例在字典中包含一个键 最初在 PEP 610 中设计,以及记录已安装发行版的直接 URL 来源中记录的数据结构。 密钥不得存在,以防止任何可能的混淆 以及保持哈希值所需的其他检查 值同步。hasharchive_infohashhashes

{  "archive_info": {    "hash": "sha256=236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f",    "hashes": {      "sha256": "236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f"    }  },  "url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"}

另一个示例演示了无效的哈希名称。引用的哈希名称不会 对应于此 PEP 中描述的规范哈希名称,并且 在 Python 文档下的 .

{  "archive_info": {    "hashes": {      "SHA-256": "236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f"    }  },  "url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"}

示例 pip 命令及其对 provenance_url.json 和 direct_url.json 的影响

  • 这些命令生成文件,但不生成文件。这些示例遵循 PEP 610 中的示例:direct_url.jsonprovenance_url.json

  • pip install https://example.com/app-1.0.tgz

  • pip install https://example.com/app-1.0.whl

  • pip install "git+https://example.com/repo/app.git#egg=app&subdirectory=setup"

  • pip install ./app

  • pip install file:///home/user/app

  • pip install --editable "git+https://example.com/repo/app.git#egg=app&subdirectory=setup"(在这种情况下,将是 git 存储库已克隆到的本地目录,并且将存在并且不会设置任何内容)urldir_info"editable": truevcs_info

  • pip install -e ./app

生成文件但不生成的命令 一个文件:provenance_url.jsondirect_url.json

  • pip install app

  • pip install app~=2.2.0

  • pip install app --no-index --find-links "https://example.com/"

可以使用 PR pypa/pip#11865 中实现的对 pip 的更改来测试此行为。

参考实现

用于在以下情况下创建元数据文件的概念验证 在 PR 中可以安装 Python 分发包到 pip pypa/pip#11865。它重用直接 URL 数据结构的现有实现,以提供 当不是 创建。provenance_url.jsonprovenance_url.jsondirect_url.json

开发了一个名为 pip-preserve 的原型 演示创建考虑文件和元数据文件。此工具模拟该功能,但已安装软件包的列表还包括 Python 分发工件的哈希值。requirements.txtdirect_url.jsonprovenance_url.jsonpip freeze

为了进一步支持这个提议,pip-sbom 演示了创建 SPDX 格式的 SBOM。该工具使用存储在文件中的信息。provenance_url.json

被拒绝的想法

将文件命名为 direct_url.json 而不是 provenance_url.json

为了保持与直接 URL 源规范的向后兼容性, 根据该规范的文本,该文件无法命名:direct_url.json

从其他发行版安装发行版时,不得创建此文件 需求类型(即名称加版本说明符)。

对于仅在分发 使用直接 URL 引用进行安装。direct_url.json

弃用 direct_url.json 并仅使用 provenance_url.json

文件已经建立,PEP 610 被接受,并且是 安装程序已使用。例如,使用 报告直接 URL 引用。弃用需要对 pip 中的实现进行额外的更改(参见 PR fridex/pip#2),并且可能会引入向后兼容性 现有消费者的问题。direct_url.jsonpipdirect_url.jsonpip freezedirect_url.jsonpip freezedirect_url.json

将哈希键保留在archive_info字典中

PEP 610 及其相应的规范 PyPA 规范讨论了在字典中将密钥与密钥一起包含的可能性。此 PEP 显式不包括 文件,并只允许存在密钥。 通过这样做,我们消除了文件中可能的冗余、可能的混淆、 以及为确保哈希值在 同步。hashhashesarchive_infohashprovenance_url.jsonhashes

将哈希键设为可选键

PEP 610 及其相应的规范 PyPA 规范建议在文件中包含 的密钥,但这不是必需的(根据 RFC 2119 语言):hashesarchive_infodirect_url.json

哈希键应作为将哈希名称映射到十六进制的字典存在 文件的编码摘要。

如果创建了该文件,则此 PEP 要求将密钥包含在文件中;根据此 PEP:hashesarchive_infoprovenance_url.json

MUST 的值必须是具有单个键的字典。archive_infohashes

通过这样做,消费者可以检查 当安装程序创建文件时,项目会摘要。provenance_url.jsonprovenance_url.json

未解决的问题

Conda 中 provenance_url.json 文件的可用性

我们希望从Conda获得有关该文件的反馈 维护。目前尚不清楚Conda是否愿意采用该文件。Conda 已经存储了与出处相关的 信息(类似于本 PEP 中建议的出处信息)在 操作后位于目录中的 JSON 文件 在安装过程中。provenance_url.jsonprovenance_url.jsonconda-meta

在下游安装程序中使用provenance_url.json

拟议的文件主要由以下机构通过 Python 安装程序。其他安装程序(如 APT 或 DNF)可能会记录 已安装的下游 Python 发行版的来源 特定于下游包管理的方式。建议的文件是 不希望由这些下游包安装程序创建,因此它们 被故意排除在这个 PEP 之外。但是,开发人员的任何输入或 这些安装程序的维护者很有价值,可以用某种方式有帮助的信息来丰富文件。provenance_url.jsonprovenance_url.json

附录:安装人员和库的调查

果仁

来自 pip 内部 API 的函数,负责安装轮子,名为 _install_wheel, 不存储目录中的任何文件。此外,在 pypa/pip#11865 中将上述文件引入 pip 的原型演示了在 pip 的源代码中合并处理文件的逻辑。provenance_url.json.dist-infoprovenance_url.json

由于下面提到的一些工具使用 pip 来安装 Python 包 分布,pip 的发现适用于这些工具,而 pip 则不适用于 允许参数化在其目录中的文件创建 内部 API。下面提到的大多数使用 pip 的工具都调用 pip 作为 子进程,对目录中文件的最终存在没有影响。.dist-infoprovenance_url.json.dist-info

distlib的

distlib 实现了操作目录的低级功能。已安装发行版的数据库不使用 任何名为 的文件,基于 distlib 的源代码。dist-infoprovenance_url.json

皮彭夫

Pipenv 使用 pip 来安装 Python 包发行版。 没有任何其他已识别的逻辑会导致倒退 在目录中引入文件时出现兼容性问题。provenance_url.json.dist-info

安装

安装程序不会显式创建文件。 尽管如此,根据 Recording Installed Projects 规范,安装程序允许将参数传递给 在目录中创建文件 - 请参阅源代码。 为避免任何向后兼容性问题,任何库或工具使用 安装程序不得请求使用 提到的论点。provenance_url.jsonadditional_metadata.dist-infoprovenance_url.jsonadditional_metadata

诗歌

Poetry 中的安装逻辑取决于配置选项(参见文档)。installer.modern-installer

对于设置了配置选项的情况 到,Poetry 使用 pip 来安装 Python 包发行版。installer.modern-installerfalse

另一方面,当配置选项为 设置为,Poetry 使用安装程序来安装 Python 包发行版。 从链接的来源可以看出,没有传递任何额外的 命名的元数据文件会导致兼容性 此 PEP 的问题。installer.modern-installertrueprovenance_url.json

康达

安装 Python 包分发时,Conda 不会创建任何文件。provenance_url.json


孵化

Hatch 使用 pip 来安装项目依赖项。

微移液器

由于 micropipenv 是 pip 顶部的包装器,它使用 pip 来安装 Python 发行版,用于锁定文件和需求文件。

塔摩斯

Thamos 使用 micropipenv 安装 Python 包 分布, 因此,任何关于micropipenv的发现都适用于Thamos。

PDM的

PDM 使用安装程序来安装二进制发行版。 它最终在目录中创建的唯一附加元数据文件是 REFER_TO 文件。.dist-info

确认

感谢 Dustin Ingram、Brett Cannon 和 Paul Moore 的初步讨论 这个想法的起源。

感谢 Donald Stufft、Ofek Lev 和 Trishank Kuppusamy 的早期反馈 并支持开展此 PEP 的工作。

感谢 Gregory P. Smith、Stéphane Bidoul 和 C.A.M. Gerlach 审查此 PEP 并提供有价值的建议。

感谢 Seth Michael Larson 提供宝贵的建议和 提出的PIP-SBOM原型。

感谢 Stéphane Bidoul 和 Chris Jerdonek 的 PEP 610。

最后但并非最不重要的一点是,感谢 Donald Stufft 赞助了这次 PEP。

版权

本文档位于公有领域或属于 CC0-1.0-Universal 许可证,以更宽松的为准。

The End 微信扫一扫

文章声明:以上内容(如有图片或视频在内)除非注明,否则均为腾龙猫勺儿原创文章,转载或复制请以超链接形式并注明出处。

本文作者:猫勺本文链接:https://www.jo6.cn/post/66.html

上一篇 下一篇

相关阅读

发表评论

访客 访客
快捷回复: 表情:
评论列表 (暂无评论,198人围观)

还没有评论,来说两句吧...

取消
微信二维码
微信二维码
支付宝二维码