VS Code 扩展发布改用 Trusted Publishing:短期凭证如何替换长期 token
根据 Microsoft 公告摘要,VS Code 和 Visual Studio 扩展可从 GitHub Actions 或 Azure Pipelines 发布且无需存储长期 PAT;迁移的核心是用 CI 身份换取短期授权、先并行验证再撤销旧 token,具体配置、凭证寿命和支持矩阵待核实。
可以替换,但前提是把发布流水线的身份验证做对。根据 Microsoft 公告摘要,VS Code 和 Visual Studio 扩展可以从 GitHub Actions 或 Azure Pipelines 发布,且不需要存储长期 personal access token(PAT,个人访问令牌)。这句话确认的是支持范围和目标,不是完整配置步骤;截至本文写作时(2026 年 10 月 31 日),可核验的材料只有公告标题与摘要,具体交换协议、配置字段和凭证寿命均待核实。相关摘要见 Microsoft 的 Trusted Publishing 公告。
已经能确认的只有支持范围,不是完整教程#
公告摘要明确提到两个 CI 场景:GitHub Actions 和 Azure Pipelines;也明确目标是发布 VS Code 与 Visual Studio 扩展时,不再保存长期 PAT。这足以说明“长期 token 可以被替换”是官方支持方向,但不足以推导出可直接照抄的 YAML、命令行参数或发布者后台操作。
因此,下文把“来源事实”“通用推断”和“迁移建议”分开写。凡是涉及 Marketplace 具体字段、凭证类型、有效期、权限粒度和回滚方式的内容,都以“待核实”标注;在没有官方文档或可核验测试记录前,不应把它们当成已实现的行为。
替换的本质:不再保存可复制的长期秘密#
长期 PAT 是一种 bearer credential:谁拿到字符串,谁就能在有效期内使用它。把它放进 CI secret 只能减少明文暴露,不能消除复制、日志泄露、第三方 action 读取、fork 请求滥用和人员离职后忘记轮换等风险。这是通用风险模型,不是对某次具体事件的描述。
Trusted Publishing(可信发布)的通用思路,是把“预先存放的秘密”换成“运行时可验证的身份”。常见流程如下,但这是对 Trusted Publishing 一般模式的说明,不是对 VS Code Marketplace 实现细节的确认:
- CI 任务向平台证明自己的工作负载身份,例如来自哪个组织、仓库、分支、工作流或受保护环境。
- 发布服务按照预先配置的信任关系验证该身份断言。
- 验证通过后,发布服务签发短期凭证,或直接授权本次发布操作。
- 发布工具使用该短期授权调用 Marketplace;授权过期后不能继续使用。
常见实现会借助 OpenID Connect(OIDC)或云厂商的工作负载身份联合。Marketplace 是否采用 OIDC、凭证是一次性还是短时有效、是否直接返回 token,材料没有给出,需查官方文档确认。短期凭证也不是“无凭证”:发布请求仍要携带授权,只是授权不再以长期秘密的形式存放在仓库或 CI 设置里。
迁移顺序:先建立信任,再撤销旧 token#
不要先删除现有 PAT。更稳妥的顺序是让旧流程和新流程短暂并存,确认新流程可重复成功后,再撤销旧凭证。以下步骤是迁移建议,不是官方步骤清单:
- 盘点发布入口。列出所有会发布扩展的仓库、流水线、维护者和现有 PAT,确认哪些 token 仍在使用、权限是否过宽、是否有手工发布依赖。
- 确认官方支持矩阵。核对发布者类型、GitHub Actions 或 Azure Pipelines 的具体身份类型、自托管 runner、代理网络、工具版本,以及现有
vsce publish脚本是否仍兼容。未确认前不要切换生产发布。 - 设计信任边界。把信任关系绑定到受保护分支、受保护环境或明确的工作流,而不是整个组织或任意分支。具体可绑定哪些字段,待核实。
- 改流水线权限。只授予发布任务必要的仓库读取和身份令牌权限;固定第三方 action 的版本或提交哈希;禁止在日志中打印凭证;避免让不受信任的 fork 拉取请求获得发布身份。
- 并行试运行。在测试发布者、预发布通道或非生产扩展上验证身份交换、发布、失败重试和审计记录。若你的发布者不支持测试通道,至少先用一次手动触发的工作流验证。
- 撤销旧 PAT。确认新流程连续成功、回滚路径明确后,撤销或轮换旧 token。保留应急 token 时应有审批、到期时间和使用记录,不能无限期保留。
- 监控与复盘。同时查看 CI 运行记录和 Marketplace 发布者审计日志;为失败发布、异常触发和凭证交换错误设置告警。
概念示例:只展示结构,不可直接运行
下面的 YAML 仅用于说明“发布任务不应持有长期 PAT”这一结构。它不是官方 Marketplace 配置,字段名、action 名称和权限要求均待核实,且未实际执行。
# 未执行的概念示意,不是可复制的 Marketplace 配置
name: publish-extension
on:
workflow_dispatch:
permissions:
contents: read
id-token: write # 若采用 OIDC 时常见;VS Code Marketplace 是否要求待核实
jobs:
publish:
runs-on: ubuntu-latest
environment: marketplace-publish
steps:
- uses: actions/checkout@YOUR_CHECKOUT_VERSION
- name: Publish
uses: YOUR_MARKETPLACE_PUBLISH_ACTION
# 具体参数以官方文档为准;不要在此写入长期 PAT
这段示例没有经过运行验证,不能据此判断 Marketplace 会接受该配置。尤其要注意:id-token: write 只是通用 OIDC 场景下的权限写法,是否适用于 VS Code 扩展发布、是否还需要其他权限,均需以官方文档为准。
长期 PAT 与短期凭证的差异#
下表是通用安全比较,不是对 Visual Studio Marketplace 官方行为的逐项说明。具体实现可能不同。
| 维度 | 长期 PAT | Trusted Publishing(概念) |
|---|---|---|
| 凭证形态 | 预先创建、可重复使用 | 由 CI 身份换取短期授权;具体形态待核实 |
| 存储位置 | 常放在 CI secret 或本地环境 | 目标是不存放长期秘密 |
| 权限范围 | 取决于 token 权限,容易过宽 | 由信任策略和工作流身份约束,取决于实现 |
| 轮换 | 手工或定时轮换,容易遗漏 | 每次运行重新获取;是否如此待核实 |
| 审计线索 | 看 token 使用记录 | 可结合工作流运行与发布者日志;字段待核实 |
| 主要风险 | 泄露后在有效期内可被复制使用 | 信任条件过宽、工作流被篡改、身份被冒用 |
容易被忽略的边界条件#
- 信任策略本身就是高权限配置。谁能修改工作流、环境审批或发布者信任关系,谁就可能影响发布结果。应把发布工作流纳入代码所有者审批,并对生产发布环境设置人工审批。
- 短期凭证不解决所有供应链问题。如果第三方 action 被替换、构建脚本被注入,或者发布任务在不受信任的分支上运行,身份仍可能被滥用。固定依赖版本、限制令牌权限、检查构建产物,仍然必要。
- 失败模式会变化。身份交换依赖 CI 平台、网络、时钟和发布服务的可用性;重试可能带来重复发布。Marketplace 的幂等行为、重试建议和失败恢复方式待核实。
- 回滚要同时覆盖信任关系和发布物。撤销信任关系、恢复旧流程、下架或回滚扩展版本,是三件不同的事。迁移前应明确谁有权执行、需要多长时间。
- 审计不能只看一处。CI 日志能说明谁触发了工作流,发布者日志能说明谁调用了发布接口;两者时间线和身份标识是否能对上,需要实际验证。
上线前必须核实的清单
| 问题 | 为什么重要 | 当前状态 |
|---|---|---|
| 支持哪些 CI 身份类型和 runner? | 决定 GitHub Actions、Azure Pipelines、自托管 runner 能否使用 | 摘要只提到两个 CI 平台,细节待核实 |
| 信任关系可绑定到哪一层? | 绑定过宽会扩大滥用面,绑定过窄可能导致发布失败 | 待核实 |
| 短期凭证的有效期、受众和复用规则? | 影响泄露窗口、重试设计和审计判断 | 待核实 |
| 现有发布命令是否需要升级? | 决定迁移成本和回滚方式 | 待核实 |
| 个人发布者与组织发布者是否同流程? | 影响权限归属和多人协作 | 待核实 |
| 如何撤销信任关系、查看审计日志? | 决定事故响应速度 | 待核实 |
结论#
VS Code 扩展发布改用 Trusted Publishing 的核心,不是把 PAT 换成一个更短的字符串,而是让发布流水线用可验证身份换取短期授权,从源头上减少长期秘密的存放和复制。根据公开摘要,GitHub Actions 和 Azure Pipelines 已在支持范围内,且目标是不再存储长期 PAT;但具体配置、凭证寿命、工具兼容性和审计能力仍需以官方文档核实。
落地时建议先并行验证,再撤销旧 token;先限制信任边界,再追求自动化便利。若官方文档没有确认某个字段或行为,不要用推测的配置上线,也不要把本文中的概念示例当作可执行结果。
参考来源
以上为本文写作时的参考资料,引用观点以原文为准。