Skip to content

秘密报告 API

未公开

请注意,此 API 仅根据具体情况提供。如果您想集成此 API,请联系admin@pypi.org 。

第三方合作伙伴与 PyPI 集成,以查找、识别和撤销意外公开的 API 令牌。以下合作伙伴目前会向 PyPI 报告公开的 API 令牌:

所有使用 API 令牌的 PyPI 用户默认都已选择加入此功能,无需任何操作即可从中受益。

此 API 适用于可能找到 PyPI API 令牌并希望将其报告给 PyPI 的第三方。

检测 PyPI 密钥格式

PyPI API 令牌是一个字符串,由前缀 ( pypi)、分隔符 ( ) 和表示使用 PyMacaroon-序列化的Macaroon 的字符串组成:base64

pypi-[A-Za-z0-9-_]{85,}

字符串base64长度不会少于 85 个字符。令牌的长度可以任意,因为我们可以向序列化的 Macaroon 添加任意的限制条件。

整合

PyPI 采用了GitHub 的密钥扫描报告模式。

公钥标识符和签名

PyPI 要求对该 API 的每个请求都包含两个标头:

  • 包含公钥标识符的标头
  • 包含使用此密钥对原始消息体进行签名的标头

这些请求头的名称可以任意指定,需要在集成时提供给 PyPI。系统会对每个请求进行验证。

PyPI 假定签名是 ECDSA 签名,摘要是 SHA-256。

公钥验证

PyPI 需要能够在集成时提供的 URL 上验证用于签署请求的公钥。此 URL 结构是任意的,但必须位于受信任的域中。

集成各方应准备提供 P-256/384/521 密钥,并且仅使用 SHA-256(尽管 SHA-384 和 SHA-512 分别与 P-384 和 P-521 常见,但不能使用 SHA-384 或 SHA-512)。

向此 URL 发送 GET 请求后,应返回一个 JSON 文档,其结构示例如下:

{
  "public_keys": [
    {
      "key_identifier": "90a421169f0a406205f1563a953312f0be898d3c7b6c06b681aa86a874555f4a",
      "key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9MJJHnMfn2+H4xL4YaPDA4RpJqUq\nkCmRCBnYERxZanmcpzQSXs1X/AljlKkbJ8qpVIW4clayyef9gWhFbNHWAA==\n-----END PUBLIC KEY-----\n",
      "is_current": false
    },
    {
      "key_identifier": "bcb53661c06b4728e59d897fb6165d5c9cda0fd9cdf9d09ead458168deb7518c",
      "key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYAGMWO8XgCamYKMJS6jc/qgvSlAd\nAjPuDPRcXU22YxgBrz+zoN19MzuRyW87qEt9/AmtoNP5GrobzUvQSyJFVw==\n-----END PUBLIC KEY-----\n",
      "is_current": true
    }
  ]
}

请注意,无需提供多个密钥。PyPI 不会接受在提交时未标记为有效密钥的响应。

路线

报告秘密

路线:POST /_/secrets/disclose-token

接受一个或多个任意 API 令牌的报告,并包含令牌所在位置的详细信息。消息体是一个 JSON 数组,其中包含一个或多个对象,每个对象代表一个密钥匹配。

每场秘密比赛的密钥如下:

  • token:秘密匹配的值(必填)
  • type找到的令牌类型(必填)
  • url:找到匹配项的公开网址(必填)

目前唯一有效的type值为"pypi_api_token"

可以填写其他字段,但这些字段将被忽略。

请求示例:

POST /_/secrets/disclose-token HTTP/1.1
Host: pypi.org
Some-Public-Key-Identifier: ...
Some-Public-Key-Signature: ...

[
  {
    "token": "pypi-NMIfyYncKcRALEXAMPLE...",
    "type": "pypi_api_token",
    "url": "https://github.com/octocat/Hello-World/blob/12345600b9cbe38a219f39a9941c9319b600c002/foo/bar.txt",
  }
]

状态码:

  • 204 No Content- 我们已收到请求,但不对结果发表评论。
  • 400 Bad Request- 该请求格式有误,我们无法处理该报告。响应正文将包含更详细的错误信息。令牌未公开,请重新提交。