使用可信发布从GitHub Actions轻松发布NuGet包
在本文中,我将介绍如何使用nuget.org的新功能"可信发布"从GitHub Actions工作流发布NuGet包,无需生成和存储API密钥,同时享受更高的安全性。
当前推送NuGet包的方式
如果你创建NuGet包并将其推送到nuget.org,可能会采用以下几种方式之一:
- 在本地构建包并手动上传到nuget.org
- 在CI中构建包,下载后手动上传到nuget.org
- 在CI中构建包,直接从CI推送到nuget.org
这些方法逐步"优化",通常能提高构建的一致性并减少手动步骤。但从CI推送.nupkg文件到NuGet比通过nuget.org网站在本地上传要"困难"一些。现在你需要:
- 生成API密钥
- 在GitHub Actions中安全存储(例如作为Secret)
- 在GitHub Actions工作流中传递密钥
- 密钥更改时进行轮换
- 确保组织中的其他人也能执行相同操作(如果为组织发布包)
这些都不是无法克服的困难,但管理长期密钥的生命周期 notoriously 困难。这就是可信发布的用武之地。
什么是可信发布?
可信发布是一项已在多个生态系统中实施一段时间的倡议。例如Python有PyPI的可信发布,Ruby有RubyGems.org的可信发布,JavaScript有npm的可信发布。上周起,.NET为nuget.org推出了可信发布🎉
可信发布使用现有的身份验证标准(OpenID Connect)将CI基础设施提供商(如GitHub Actions或GitLab Pipelines)与公共包存储库(如PyPI和nuget.org)连接起来。你无需存储和管理API密钥让两个系统相互通信,而是使用OpenID Connect检索短期身份验证令牌,然后使用该令牌将包推送到包存储库。
具体实现因提供商和包存储库而异,但整体流程相同。对于GitHub actions和nuget.org,流程如下:
- 用户在nuget.org上配置"信任策略"
- 在CI工作流中,从GitHub检索作业的OpenID Connect令牌(GitHub是身份提供商)
- 令牌是签名的JSON Web Token(JWT),包含有关仓库和运行工作流的详细信息
- 将令牌发送到nuget.org,用令牌交换API密钥
- NuGet.org根据配置的信任策略验证JWT内容
- 如果一切匹配,nuget.org发出可用于发布包的短期API令牌
- CI工作流使用API令牌将.nupkg包推送到nuget.org
由于信任策略是预先配置的,并且你已经通过GitHub身份验证(因其在其基础设施中运行),因此很容易启动和运行。
在NuGet.org上配置可信发布
看到博客文章后,我决定为新的sleep-pc工具尝试一下,因为我还没有为它设置CI。我将首先展示没有NuGet发布的工作流作为基线,然后展示我通过可信发布添加发布的步骤。
工作流起点
没有发布的初始工作流如下所示,存储在文件.github/workflows/BuildAndPack.yml
中:
|
|
这只是做了3件事:
- 检出仓库
- 安装.NET 10
- 运行dotnet pack
值得注意的是,我添加了permissions条目以限制从仓库读取的权限,这是安全最佳实践。这不是必需的,但我添加它主要是为了展示使用可信发布时需要更改的内容。
更新工作流以添加可信发布支持
要添加可信发布,我们需要做三件事:
- 添加
id-token: write
权限 - 使用
NuGet/login@v1
将OIDC令牌交换为NuGet API密钥 - 使用生成的API密钥将包推送到NuGet
以下显示更新的工作流,注释突出显示了差异:
|
|
在此工作流中,你需要配置的唯一密钥是NUGET_USER
密钥,应将其设置为你的nuget.org用户名(不是电子邮件地址)。考虑到这无论如何都是公共信息,将其存储在密钥中似乎有点过度,但为什么不呢😄
如果你现在运行此工作流,NuGet登录步骤将失败,出现类似以下错误:
|
|
从消息中可以看到,阶段失败是因为我们尚未在nuget.org上配置信任策略,所以这是我们的下一个任务。
在NuGet.org上配置信任策略
配置信任策略非常容易。我们首先在nuget.org登录并导航到可信发布页面:
点击创建以创建新策略,并填写所有必填字段:
- 策略名称(我认为使用包/GitHub仓库的名称是有意义的)
- 包所有者(无论是个人账户还是组织)
- GitHub仓库详细信息(所有者和仓库)
- 将推送到Nuget的工作流文件
创建信任策略后,它处于"部分"活动状态,直到你使用该策略。
现在如果你再次运行工作流,登录步骤将成功:
|
|
策略已变为完全活动:
假设其他一切按计划进行,在下一步中,你的包将发布到NuGet,无需长期API密钥🎉
总结
据我所知,截至目前,在nuget.org上使用可信发布除了发布简便和缺乏长期凭据外,没有额外的好处。我当然可以预见未来的额外好处,通过可信发布推送的包将具有额外的验证标记。例如,将来可能与来源证明有一些关联?我猜我们会拭目以待!
概要
在本文中,我讨论了可信发布以及它如何通过避免在GitHub仓库中存储长期凭据来提供帮助。然后我展示了如何使用可信发布将我的sleep-pc包从GitHub仓库配置发布到nuget.org。