{{< details >}}
- Tier: 旗舰版
- Offering: JihuLab.com, 私有化部署
{{< /details >}}
极狐GitLab 密钥检测会在发现某些类型的泄露密钥时自动响应。自动响应可以:
- 自动撤销密钥。
- 通知发出密钥的合作伙伴。合作伙伴可以随后撤销密钥,通知其所有者,或采取其他措施防止滥用。
支持的密钥类型和操作
极狐GitLab 支持以下类型密钥的自动响应:
密钥类型 | 采取的操作 | 支持极狐GitLab.com | 支持极狐GitLab 私有化部署 |
---|---|---|---|
极狐GitLab 个人访问令牌 | 立即撤销令牌,发送邮件给所有者 | ✅ | ✅ 15.9 及以后 |
Amazon Web Services (AWS) IAM 访问密钥 | 通知 AWS | ✅ | ⚙ |
Google Cloud 服务账户密钥, API 密钥, 和 OAuth 客户端密钥 | 通知 Google Cloud | ✅ | ⚙ |
Postman API 密钥 | 通知 Postman;Postman 通知密钥所有者 | ✅ | ⚙ |
组件图例
- ✅ - 默认可用
- ⚙ - 需要使用 令牌撤销 API 手动集成
功能可用性
{{< history >}}
- 在极狐GitLab 15.11 中,为非默认分支启用。
{{< /history >}}
凭证只有在密钥检测发现时才会进行后处理:
- 在公共项目中,因为公开暴露的凭证构成了更大的威胁。
- 在极狐GitLab 旗舰版项目中,出于技术原因。
高级架构
这个图描述了如何在极狐GitLab 应用中通过后处理钩子撤销密钥:
- 一个包含密钥检测任务的流水线完成,产生扫描报告(1)。
- 报告由服务类处理(2),如果可能进行令牌撤销,则安排异步 worker。
- 异步 worker(3)与外部部署的 HTTP 服务通信(4 和 5),以确定哪些类型的密钥可以自动撤销。
- worker 发送(6 和 7)极狐GitLab 令牌撤销 API 能够撤销的检测到的密钥列表。
- 极狐GitLab 令牌撤销 API 将每个可撤销的令牌发送(8 和 9)到它们各自供应商的 合作伙伴 API。请参阅 极狐GitLab 令牌撤销 API 文档以获取更多信息。
泄露凭证通知的合作伙伴计划
极狐GitLab 在极狐GitLab.com 上的公共存储库中泄露的凭证时通知合作伙伴。
实现一个合作伙伴 API
合作伙伴 API 与极狐GitLab 令牌撤销 API 集成以接收和响应泄露令牌撤销请求。该服务应该是一个公开可访问的 HTTP API,支持幂等和速率限制。
对您的服务的请求可以包含一个或多个泄露的令牌,以及带有请求正文签名的头。我们强烈建议您使用此签名验证传入请求,以证明这是来自极狐GitLab 的真实请求。下面的图表详细描述了接收、验证和撤销泄露令牌的必要步骤:
- 极狐GitLab 令牌撤销 API 发送(1)一个撤销请求到合作伙伴 API。请求包含头信息,其中包含公共密钥标识符和请求正文签名。
- 合作伙伴 API 请求(2)来自极狐GitLab 的公共密钥列表。响应(3)可能包含多个公共密钥,以防密钥轮换,并应根据请求头中的标识符进行过滤。
- 合作伙伴 API 验证签名与实际请求正文相对照,使用公共密钥(4)。
- 合作伙伴 API 处理泄露的令牌,可能涉及自动撤销(5)。
- 合作伙伴 API 以适当的 HTTP 状态码响应极狐GitLab 令牌撤销 API(6):
- 成功响应代码(HTTP 200 至 299)确认合作伙伴已接收并处理请求。
- 错误代码(HTTP 400 或更高)导致极狐GitLab 令牌撤销 API 重试请求。
撤销请求
此 JSON 模式文档描述了撤销请求的主体:
{
"type": "array",
"items": {
"description": "A leaked token",
"type": "object",
"properties": {
"type": {
"description": "The type of token. This is vendor-specific and can be customised to suit your revocation service",
"type": "string",
"examples": [
"my_api_token"
]
},
"token": {
"description": "The substring that was matched by the Secret Detection analyser. In most cases, this is the entire token itself",
"type": "string",
"examples": [
"XXXXXXXXXXXXXXXX"
]
},
"url": {
"description": "The URL to the raw source file hosted on GitLab where the leaked token was detected",
"type": "string",
"examples": [
"https://gitlab.example.com/some-repo/-/raw/abcdefghijklmnop/compromisedfile1.java"
]
}
}
}
}
示例:
[{"type": "my_api_token", "token": "XXXXXXXXXXXXXXXX", "url": "https://example.com/some-repo/-/raw/abcdefghijklmnop/compromisedfile1.java"}]
在此示例中,密钥检测已确定 my_api_token
的一个实例已泄露。令牌的值提供给您,以及包含泄露令牌的文件的原始内容的公开可访问 URL。
请求包括两个特殊头:
头 | 类型 | 描述 |
---|---|---|
Gitlab-Public-Key-Identifier |
string | 用于签署此请求的密钥对的唯一标识符。主要用于帮助密钥轮换。 |
Gitlab-Public-Key-Signature |
string | 请求正文的 base64 编码签名。 |
您可以使用这些头以及极狐GitLab 公共密钥端点来验证撤销请求是否真实。
公共密钥端点
极狐GitLab 维护一个公开可访问的端点,用于检索用于验证撤销请求的公共密钥。可以根据请求提供端点。
此 JSON 模式文档描述了公共密钥端点的响应主体:
{
"type": "object",
"properties": {
"public_keys": {
"description": "An array of public keys managed by GitLab used to sign token revocation requests.",
"type": "array",
"items": {
"type": "object",
"properties": {
"key_identifier": {
"description": "A unique identifier for the keypair. Match this against the value of the Gitlab-Public-Key-Identifier header",
"type": "string"
},
"key": {
"description": "The value of the public key",
"type": "string"
},
"is_current": {
"description": "Whether the key is currently active and signing new requests",
"type": "boolean"
}
}
}
}
}
}
示例:
{
"public_keys": [
{
"key_identifier": "6917d7584f0fa65c8c33df5ab20f54dfb9a6e6ae",
"key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEN05/VjsBwWTUGYMpijqC5pDtoLEf\nuWz2CVZAZd5zfa/NAlSFgWRDdNRpazTARndB2+dHDtcHIVfzyVPNr2aznw==\n-----END PUBLIC KEY-----\n",
"is_current": true
}
]
}
验证请求
您可以通过验证 Gitlab-Public-Key-Signature
头与请求正文的对照来检查撤销请求是否真实,使用从上面的 API 响应中获取的对应公共密钥。我们使用 ECDSA 与 SHA256 哈希来产生签名,然后将其 base64 编码到头值中。
下面的 Python 脚本演示了如何验证签名。它使用流行的 pyca/cryptography 模块进行加密操作:
import hashlib
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import load_pem_public_key
from cryptography.hazmat.primitives.asymmetric import ec
public_key = str.encode("") # obtained from the public keys endpoint
signature_header = "" # obtained from the `Gitlab-Public-Key-Signature` header
request_body = str.encode(r'') # obtained from the revocation request body
pk = load_pem_public_key(public_key)
decoded_signature = base64.b64decode(signature_header)
pk.verify(decoded_signature, request_body, ec.ECDSA(hashes.SHA256())) # throws if unsuccessful
print("Signature verified!")
主要步骤是:
- 将公共密钥加载到适合您使用的加密库的格式中。
- 对
Gitlab-Public-Key-Signature
头值进行 base64 解码。 - 验证正文与解码签名的对照,指定 ECDSA 与 SHA256 哈希。