PEP 740 – 数字证明的索引支持

猫勺猫勺 03-30 176 阅读 0 评论

抽象

PEP 提出了与上传和分发相关的一系列更改 用于在 Python 上验证它们的数字签名证明和元数据 包存储库,例如 PyPI。

这些更改有两个子组件:

  • 对当前未标准化的 PyPI 上传 API 的更改,允许客户端 上传数字证明;

  • 对 PEP 503 和 PEP 691“简单”API 的更改,允许客户端 检索数字证明和受信任的发布元数据 对于单个发布文件。

此 PEP 不推荐特定的数字证明格式,也不推荐 它围绕强制性数字证明提出政策建议 通过安装客户端(如 .pip

基本原理和动机

对 Python 包上的数字签名的渴望一再出现 由软件包维护者和下游用户共同表达:

  • 维护者希望证明其完整性和真实性 包上传;

  • 个别下游用户希望验证软件包的完整性和真实性 没有额外信任其指数的诚实性;

  • “批量”下游用户(如操作系统发行版)希望 执行类似的验证,并可能重新公开或会签 对于他们自己的下游包装生态系统。

该提案旨在适应上述每个用例。

此外,该提案还确定了以下动机:

  • Python 包分发的可验证来源:许多 Python 包当前包含未经身份验证的出处元数据,例如 作为源主机的 URL。加密证明格式可以启用 这些包与其源主机之间的强身份验证链接, 允许索引和下游用户以加密方式验证 包源自其声明的源存储库。

  • 提高攻击者要求:试图获取 在 Python 包上可以按照复杂程度(从简单到复杂)和目标维度进行描述 (机会主义到有针对性)。

    数字证明提出了额外的复杂要求: 攻击者必须足够复杂才能访问私人签名材料 (或签署身份)。此外,它们还规定了额外的定位要求: 发布一致性要求(如下所述)意味着攻击者 无法上传任何证明,但只能上传已看到的一种证明 特定版本。在未来,这可能会进一步“棘轮”下降 通过允许项目维护者在没有证明的情况下禁用发布 完全。

  • 发布一致性:在现状下,唯一由 index 是每个发布文件的可选 PGP 签名 (请参阅 PGP 签名)。这些签名不是 通过索引检查格式是否正确或有效,因为 该索引没有用于识别 签名。

    此外,该指数没有“全有或全无”的要求 对于 PGP 签名,这意味着没有一致性要求 在发行版内的发行版之间(维护者可以 添加其他签名时不小心忘记上传签名 发布发行版)。

虽然此 PEP 不推荐特定的数字证明格式, 它确实将 Trusted Publishing 的效用视为预先存在的, “零配置”是 Python 包的强来源。 因此,此 PEP 包括一个公开每个版本的拟议方案 文件的 Trusted Publisher 元数据,期望未来的数字 证明格式可能会使用它。

设计注意事项

此 PEP 在评估时确定了以下设计注意事项 它自己提议的更改和以前在相同或相邻的工作 Python 打包的领域:

  1. 索引可访问性:Python 包的数字证明 理想情况下,可以直接从索引本身检索,作为“分离” 资源

    这既简化了一些兼容性问题(通过避免 需要修改分发格式本身),并且还简化了 潜在安装客户端的行为(通过允许他们 在相应的包之前检索每个证明,而无需 进行流式解压缩)。

  2. 由索引本身进行验证:除了启用验证之外 通过安装客户端,每个数字证明都是可验证的 以某种形式由索引本身提供。

    这两者都提高了整体质量 上传到索引的证明(例如,防止用户 意外上传不正确或无效的证明)以及 启用索引本身的 UI 和 UX 优化(例如“来源” 查看每个上传的包)。

  3. 一般适用性:数字证明应适用于上传到索引的任何和每个包,无论其格式如何 (sdist 或 wheel)或内部内容。

  4. 元数据支持:此 PEP 指的是“数字证明”,而不是 只是“数字签名”,以强调额外的理想存在 加密信封中的元数据。

    例如,防止分配名称和 它的内容,数字证明可以执行,而不仅仅是.HASH(name || HASH(contents))HASH(contents)

  5. 一致的版本证明:如果属于某个版本的文件具有 一组数字证明,然后是属于该证明的所有其他文件 发布还应具有相同类型的证明。

    这简化了数字证明的下游使用情况,并且 防止可能易受攻击的“瑞士奶酪”释放模式(其中 验证程序检查有效的证明,但其安装客户端实际上解析了攻击者控制的 而不是特定于平台)。HolyGrail-1.0.tar.gz.whl

以前的工作

PGP 签名

PyPI 和其他索引历来支持上传时的 PGP 签名 分布。这些可以在上传期间提供,并且可以检索 通过 PEP 503 API 中的属性、PEP 691 API 上的密钥或通过相邻的后缀 URL 安装客户端。data-gpg-siggpg-sig.asc

自 2023 年 5 月以来,PyPI 上的 PGP 签名上传已被禁用,此前一项调查确定大多数签名(它们本身构成了 总上传的一小部分)无法与公钥关联,或者 否则有意义地验证。

在 PyPI 上以前支持的表单中,PGP 签名满足 上述考虑因素(1)和(3),但不包括(2)(由于需要外部 密钥服务器和密钥分发)或 (4)(由于 PGP 签名通常为 仅通过输入文件构造,没有任何关联的签名元数据)。 同样,PyPI 对 PGP 的历史实现也不满足考虑 (5)、由于不同发布文件之间缺乏一致性检查 (以及由于无法访问签名者的 公钥)。

车轮签名

PEP 427(及其活的 PyPA 对应物) 指定滚轮格式。

此格式包括对直接嵌入的数字签名的调整 以 JWS 或 S/MIME 格式进入轮子。指定了这些签名 在 PEP 376 RECORD 上,该记录已修改为包含加密摘要 对于轮子中的每个记录文件。

虽然车轮签名已完全指定,但它们似乎并不广泛 使用;官方车轮工具已弃用 0.32.0 中的签名生成和验证支持,这是 2018年发布。

此外,车轮签名不满足以下任何条件 上述考虑(由于签名的“附加”性质, 索引本身的不可验证性,仅支持轮子)。

规范

上传终结点更改

当前上传 API 未标准化。但是,我们提出以下建议 对它的更改:

  • 除了当前的顶级和字段外, 索引应接受作为附加的多部分形式 田。contentgpg_signatureattestations

  • 新字段应为 JSON 对象。attestations

  • JSON 对象应具有一个或多个键,每个键标识 索引已知的证明格式。如果任何键未标识 索引已知的证明格式,索引必须拒绝上传。

  • 与每个已知键关联的值应为 JSON 对象。

  • 每个证明值必须可由索引验证。如果索引失败 要验证 中的任何证明,它必须拒绝上传。attestations

除上述内容外,索引还应强制执行一致性 通过以下方式进行发布证明的策略

  • 如果新版本下的第一个文件提供了 , 则同一版本下所有后续上传的文件也必须 有。相反,如果新版本下的第一个文件 没有任何,则所有后续上传在 同一版本不得有 .attestationsattestationsattestationsattestations

  • 同一版本下的所有文件必须具有相同的已知数据集 证明格式键。

索引必须拒绝任何不满足这些条件的文件上传 一致性属性。

索引更改

来源对象

该索引将提供上传的证明以及可以提供帮助的元数据 以 JSON 序列化对象的形式验证它们。

这些“来源对象”将通过 PEP 503 简单索引提供 和 PEP 691 基于 JSON 的简单 API,如下所述,并将具有 结构如下:

{ 
   "publisher": {     
    "type": "important-ci-service",     
     "claims": {},      
     "vendor-property": "foo",      
     "another-property": 123   
    },    
    "attestations": {    
      "some-attestation": {/* ... */},     
      "another-attestation": {/* ... */}   
    }
}
  • publisher是一个可选的 JSON 对象,包含一个 文件当时的受信任发布者配置的表示形式 文件已上传到包索引。对象中的键特定于每个受信任的发布者,但至少包括:publisher

对象中的所有其他键都是特定于发布者的。一个完整的 附录 2:受信任发布者表示形式示例中提供了对象的说明性示例。publisherpublisher

一个键,该键必须是唯一标识 一种受信任的发布者。type

键,必须是包含任何特定于上下文的 JSON 对象 索引在受信任的发布者身份验证期间保留的声明。claims

  • attestations是必需的 JSON 对象,包含一个 更多由其键标识的证明对象。这个对象是 上传者通过字段提供的对象的超集,如上传终结点更改中所述。attestationsattestations

因为是文件原始上传证明的超集, 该指数可能选择嵌入自己的其他证明。attestations

简单索引

  • 当上传的文件具有一个或多个证明时,索引可以在其文件链接上包含一个属性,其值为 或 。data-provenancetruefalse

  • 当 是 时,索引必须在同一 URL 上提供来源对象,但附加到该对象。例如,如果存在并具有关联的证明,则将找到这些证明 在托管在 的 的 provenance 对象中。data-provenancetrue.provenanceHolyGrail-1.0.tar.gzHolyGrail-1.0.tar.gz.provenance

基于 JSON 的简单 API

  • 当上传的文件具有一个或多个证明时,索引可以在该文件的字典中包含对象。provenancefile

  • provenance,如果存在,则必须是来源对象。

这些更改需要对 JSON API 进行版本更改:

  • 必须指定版本 1.2 或更高版本。api-version

安全隐患

这种 PEP 本质上是“机械的”;它只为未来提供管道 对包装指数进行数字证明,但未指定其具体内容 加密详细信息。

因此,我们没有发现任何正面或负面的安全隐患 对于这个 PEP。

索引信任

此 PEP 不会增加(或减少)对指数本身的信任: 该指数仍然被有效地信任,可以诚实地提供未经修改的包 发行版,因为一个能够修改包的不诚实索引 内容还可能不诚实地修改或省略包证明。 因此,该 PEP 对指数信任的推定等同于 使用早期机制(如 PGP 和 Wheel 签名)的未说明推定。

本 PEP 不排除或排除未来的指数信任机制,例如 作为 PEP 458 和/或 PEP 480。

建议

此 PEP 不推荐特定的证明格式。确实如此, 但是,请提出以下建议来打包寻求索引 若要创建新的或实现预先存在的证明格式,请执行以下操作:

  1. 首先查阅现行 PyPA 规范,并确定当前定义的任何证明格式是否适合 你的目的。

  2. 如果在 PyPA 规范下没有定义合适的证明格式, 考虑将其提交到 PyPA 规范中,以实现寿命和重用 目的。

在设计新的证明格式时,我们提出了以下建议:

  1. 为证明格式选择一个简短但唯一的名称;这个名字会 在上传和索引 API 中用作证明的标识符。

    当适合证明格式时,我们建议使用 域分隔符。例如,提供发布的证明格式 使用 Sigstore 的出处可能具有 名字。:sigstore:publish

  2. 在格式中更喜欢简洁:避免可选字段和功能, 避免不必要的加密敏捷性和消息延展性,并确保 验证证明传达了一些有意义的东西,而不是 基本完整性检查(因为索引本身已经提供加密 为此目的的摘要)。

附录 1:上传的证明示例

本附录提供了该领域的一个虚构示例 在文件上传时提交,并带有两个虚构的证明(和):attestationspublishtimestamp

{  
  "publish": {      
    "mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.2",        
    "verificationMaterial": { /* omitted for brevity */ },        
    "messageSignature": {         
        "messageDigest": {             
           "algorithm": "some-hash-algo",               
           "digest": "digest-here"           
          },           
          "signature": "signature-here"     
       }  
   },    
   "timestamp": {    
       "cms": "some-long-blob-here"    
   }
}

这些虚构证明的有效载荷纯粹是说明性的。

附录 2:受信任的发布者表示形式示例

本附录提供了一个虚构的密钥示例 a PEP 691 列表:publisherproject.files[].provenance

"publisher": {   
 "type": "Github",    
 "claims": {    
     "ref": "refs/tags/v1.0.0",        
     "sha": "da39a3ee5e6b4b0d3255bfef95601890afd80709"    
  },    
  "repository_name": "HolyGrail",    
  "repository_owner": "octocat",    
  "repository_owner_id": "1",    
  "workflow_filename": "publish.yml",    
  "environment": null
}

版权

本文档位于公共领域或 CC0-1.0-通用许可证,以更宽松者为准。

The End 微信扫一扫

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

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

上一篇 下一篇

相关阅读

发表评论

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

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

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