GitHub 账号已经登录,为什么创建 Token、改 Webhook 或查看恢复码时还要重新认证?这不是登录态失效,而是把“当时登录过”与“此刻确实有人在操作”拆成两件事。GitHub 在 2026 年 9 月 24 日公布的 Proof of Presence(在场证明)公开预览,正是给 GitHub Enterprise Cloud 的高风险动作再加一道门。本文不把预览功能写成全量能力,而是从适用边界、认证链路、验收用例和失败排查四个角度,把它落成一份可执行的上线清单。

一、它解决的不是“密码太弱”,而是会话太长
传统登录成功后,浏览器会持有会话;攻击者如果拿到 Cookie,或者某个长期有效的认证材料被误用,单靠“这个会话仍然有效”很难证明操作者就在电脑前。Proof of Presence 的判断点更靠近敏感动作:成员发起动作后,GitHub 把人带回身份提供商(IdP),由 IdP 决定这一次需要重新登录、MFA,还是满足设备合规策略。只有带着满足策略的结果返回,动作才继续。
这和普通的登录保护不是一回事:登录解决“你是谁”,在场证明解决“现在是不是你本人正在做这件事”。两个概念混在一起,排查时就容易把所有失败都归咎于 Token。
二、先看清公开预览的适用边界
官方公告给出的公开预览范围很窄:只面向 github.com 上使用 Enterprise Managed Users(EMU)的企业,以及 GHEC-DR;企业的 SSO 身份提供商必须是 Microsoft Entra ID,并通过 SAML 或 OIDC 接入。普通个人账号、非 Entra 的 SSO 或自建 GitHub Enterprise Server,不能直接套用这条公告当作已支持证明。
示意图中的“创建 Token、编辑 Webhook、修改组织安全设置、查看恢复码”是官方列出的高影响动作示例,不代表所有动作都能由管理员自定义。Pull Request 合并前的 Proof of Presence 支持,公告明确说是后续能力,当前不要提前写进验收结论。
三、上线前先把 IdP 策略设计成可审计规则
Proof of Presence 的强度来自 IdP 策略,而不是按钮本身。建议先建立一张动作—策略矩阵,再到 GitHub 企业设置中启用公开预览能力:
动作 最低要求 验收证据
创建 Token 重新认证 + MFA Entra sign-in 日志、GitHub 操作记录
编辑 Webhook 重新认证 + 设备合规 设备条件命中、动作结果
查看恢复码 重新认证 + MFA 成功或拒绝的关联时间线
修改组织安全设置 重新认证 策略版本、操作者、结果
Pull Request 合并 先按公告确认是否支持 不把“即将支持”当当前能力这里的“最低要求”是企业内部的安全基线,不是 GitHub 对每个动作给出的固定配置模板。实际策略名称、条件访问和设备合规条件应以 Entra 管理后台当前界面为准;文章只保留可核验的动作和证据,不虚构某个不存在的 API 参数。
四、不要用“能不能点开”做验收
最小验收至少包含四组用例。第一组使用符合策略的测试账号,依次触发 Token、Webhook 和恢复码相关动作,确认会跳转 IdP,完成 MFA 后返回并成功结束动作。第二组在 IdP 中让测试账号不满足设备条件,确认返回 GitHub 后动作被阻断。第三组使用失效或取消的挑战,确认页面不会把取消误报成成功。第四组在两小时窗口内重复执行一个高风险动作,确认会话复用规则与官方 Sudo mode 口径一致。
# 只读检查示例:保存脱敏后的验收记录,不把 Token 或 Cookie 写入日志
printf 'actor=%s action=%s result=%s time=%s\n' \
'test-user' 'create-token' 'allowed-or-denied' '2026-09-25T20:00:00+08:00'
# 记录:GitHub 动作结果、IdP 策略命中、MFA 结果、关联时间戳
# 不记录:access token、session cookie、恢复码、完整认证响应如果只看到“页面能打开”,却没有 GitHub 动作记录与 IdP 策略命中记录,这个验收是不完整的。安全控制的重点是阻断证据和放行证据都要留。
五、两小时会话不是永久通行证
GitHub 的 Sudo mode 文档说明,完成敏感动作的再认证后,浏览器会临时进入 sudo mode,默认两小时内可以继续执行敏感动作;期间再次执行敏感动作会重置计时器。Proof of Presence 公告沿用同一会话模型。这里最容易出现一个误解:两小时是短期再认证会话,不是 Token 有效期,也不是“以后两小时内任何设备都信任”。
因此日志平台最好同时保存三类时间:原始登录时间、在场证明成功时间、具体动作执行时间。若只保存最后一次动作时间,后续很难判断动作究竟依赖了哪次挑战。
六、失败时按链路分层,不要先删 Token
| 现象 | 优先检查 | 常见结论 |
|---|---|---|
| 没有跳转 IdP | 企业范围、EMU、SSO 类型、功能是否已启用 | 可能不在公开预览范围 |
| 跳转后被拒绝 | Entra 条件访问、MFA、设备合规日志 | 策略未满足,不一定是 GitHub 故障 |
| 返回 GitHub 仍失败 | 回调时间、浏览器会话、GitHub 操作记录 | 挑战结果未被当前会话接受 |
| 短时间反复要求认证 | 浏览器 Cookie、跨域策略、系统时间、会话是否被清理 | 不要先扩大 Token 权限 |
排障顺序应是 GitHub 功能范围 → IdP 策略 → 回调与会话 → 具体动作权限。把 Token 权限调大,只会让问题更危险,通常还不能修复“在场证明”失败。
七、上线前的最终清单
- 确认企业属于官方公告的 EMU + github.com/GHEC-DR + Microsoft Entra SSO 范围。
- 把每类高风险动作绑定到明确的重新认证、MFA 或设备策略,并约定证据保存位置。
- 分别验证满足策略、拒绝策略、取消挑战和短期会话复用四种结果。
- 日志只保存操作者、动作、策略版本、结果和时间戳,不保存 Token、Cookie、恢复码或完整认证响应。
- 把“当前公开预览”和“后续支持”分开写,尤其不要把 Pull Request 合并提前标记为已支持。
Proof of Presence 的价值不在于让每次点击都弹 MFA,而在于把真正有影响的动作从普通会话里拎出来,要求新鲜、可解释、可追溯的身份确认。安全门可以多一道,但验收证据也要跟上,否则只是多了一个让人皱眉的登录框。
参考资料:GitHub Changelog:Require proof of presence for high-impact actions;GitHub Enterprise Cloud Docs:Sudo mode;GitHub Docs 源文件。
🔕 评论已关闭