docker / docker/github-builder

Proposal: support for signing policy

未关闭
#203 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

kind/enhancement status/triage
主要语言
没有语言数据
星标
83
派生
23
平均合并
2 天 22 小时
30 天内合并 PR
8

描述

Description

Docker Github builder creates a strong signature proving the link between the commit from a source repository and the resulting build artifact. The artifact had to be built from the specific commit, exactly as it is fully defined in the signed provenance attestation. Even if you obtain a leaked token or have write or admin access to the source repository, you can't fake this signature.

This is great security for the build process, but it doesn't provide extra protection if the source commit was already malicious. If a malicious commit is legitimately pushed to the source repository, DGB will happily build that commit and sign the resulting artifact. In that case, your only protection is that you can always trace your way back to this malicious commit and possibly use it to revoke certain artifacts based on that afterward.

This proposal explores opportunities to detect such cases before the builder runs and stops before any artifact from a malicious commit is actually created.

In order for the builder to detect if the commit is valid and they should continue, it needs to look at some properties of the build that are hard to fake.

These would be:

  • The release commit points to an annotated signed tag that is signed by a specific HSM. Assumption is that leaking repository credentials would not give access to this HSM or at least any unexpected HSM usage would be logged or trigger notifications.
  • A quorum of the source repository maintainers would need to approve the commit. An attacker would need to compromise multiple maintainers for a successful attack, which is significantly harder.
  • Optionally, we could consider that some specific code scanners need to run and pass on the source commit for the builder to pass.

This sort of rule we can refer to as "signing policy", meaning a policy that needs to pass on source commit for us to consider it valid for signing. Now we need to figure out how to securely define and store such policy.

Signing policy update flow

As an example lets consider Rego-style policy similar to Build Source policy:

allow = false

allow if = {
  input.tag.signer = "HSM_KEY"
}

allow if = {
  input.tag.approveQuota = 3
}

allow if = {
  input.tag.approveName = ["crazy-max", "abc"]
}

codescanned = if {
  input.
}

As the source repo owner, you first push the rego to your repo.

Then you run workflows/github-builder-signing-policy-update.yml on main branch.

The workflow has an optional environment clause if approveQuota is set. https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments

After the environment gets confirmed, the local workflow calls a reusable workflow github-builder/github-builder-signing-policy-update (probably better to use a different repo than the main builder).

The reusable workflow calls back to the source repository to check who approved the environment. This should work fine for public repositories using the GITHUB_TOKEN in the environment, but private repositories may need something special.

If the policy matches approvals, then the file is:

  • signed with the current reusable workflow sigstore scope (similar unforgeable proof as our image attestation signatures)
  • then saved into a transparent storage location by the repository name(maybe internal repository ID):
    • We need to find a KV store that is publicly readable, but only our OIDC scope can write to
    • Maybe existing transparency logs could be used, but really we would need a KV storage
    • We could just use a static Github repository for storage and access policies through https://raw.githubusercontent.com/ without the need to clone full repo.

When .docker/github-builder.rego is updated, the workflow is invoked again. Reusable workflow first pulls down the last signed policy. The environment needs to match the previous policy and the new one. If everything is correct then policy in storage gets updated.

Build flow

Before every GitHub Builder build or bake flow, the signing policy is pulled down from the static storage based on the source repo name. If one does not exists then it is ignored. If it does exist then the policy is evaluated: 1) is the policy correctly signed with Sigstore 2) is the git tag signed? 2) does the current run URL have the environment approvals. If environment approvals are used, then the user needs to add an environment block into their build workflow before the call to the reusable workflow. If they don’t do this, then all builds fail.

Notes
  • The Github Environments have nice UI for doing in-person approvals, but it seems that they have no support for the concept of quorum. This could be potentially worked around with two environments, so that first gathers quorum and second triggers the build to continue. But maybe there is a better alternative?
  • When using quorum, the signers need to be named. If it is just a number, then if the admin credentials leak, the attacker can just make N number of new users and give them write permissions to pass the policy.
  • When using some code scanner pass rule, the question would be if these run in the source repo scope or the reusable workflow scope. Source repo scope could potentially be insecure, as the source repo can likely be modified to add "ignore" exceptions to the scanner configuration. When using workflow scope, we could probably only support a couple of specific scanners with specific configuration options.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先检查提议的 .docker/github-builder.rego policy、workflows/github-builder-signing-policy-update.yml 以及所引用的 reusable workflow flow。完成的要求是形成一份经过一致同意的 signing-policy 设计,涵盖更新、存储、审批和 build 评估,但该 issue 未指明实现文件或测试。

由索引模型根据 Issue 内容生成。

评估

技术栈
docker, git, github-actions
领域
build-system, ci-cd, security
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
冷清
描述清晰度
需要澄清
新手友好度
25/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。