配了三年 GitHub Actions,今天才发现日志只保留 90 天——安全事件发生时根子不在代码,在「日志没了」
三个月前一次供应链攻击,回过头来想查是谁改的 workflow——日志没了。这类故事在安全圈不是个案,而是 GitHub Actions 默认行为的必然结果。
GitHub Actions 的日志保留规则是这样的:
工作流运行日志默认保留 90 天。公开仓库可以调成 1~90 天,私有仓库可以调成 1~400 天。听起来选择很多,但有三条硬限制你必须知道:
第一,只改新文件,不追溯。你今天把保留期改成 400 天,已删除的旧日志不会回来。
第二,日志内容本身有盲区。GitHub 官方文档写得很清楚:workflow run logs 只捕获标准输出。network calls、filesystem modifications、background processes 这些统统不进日志。想靠运行日志还原攻击链,先看清楚它记了什么。
第三,GitHub 托管的 runner 是临时环境,任务结束后整个环境销毁,不保留任何数据 beyond workflow run logs。
这三件事叠在一起,就是”日志还在但什么都查不出来”的根源。
企业级审计日志比这更短。
GitHub 官方文档在安全事件调查页面里悄悄埋了一句:GitHub-hosted audit log events 当前只保留 7 天。对于需要长期追溯的安全事件,7 天窗口基本等于没有。
今年 4 月 1 日,GitHub 审计日志服务因凭证轮换失败离线了 28 分钟,影响了 4297 个 API 调用和 127 个用户。没有日志丢失,但有 29 分钟的延迟——这还是 2026 年的事。
合规框架要多久?
对比一下现实:
- SOC 2 Type II:审计期 12 个月,要求日志保留至少 12 个月
- ISO 27001:一般要求 1 年以上
- HIPAA:6 年
- 金融行业:7 年
而 GitHub Actions 默认只给 90 天。GitHub 企业审计日志只给 7 天。这不是配置问题,是量级上的鸿沟。
怎么办。
第一,按仓库性质设保留期。私有仓库立刻改成 400 天,公开仓库设成 90 天。不要用默认值。
第二,把日志打出去。用 actions/upload-artifact 配合 retention-days: 365,或者直接往 S3/CloudWatch/你的 SIEM 推。if: always() 确保即使 workflow 失败了也打出去。
- name: Archive workflow logs
if: always()
run: |
aws s3 cp $GITHUB_STEP_SUMMARY s3://audit-logs/$GITHUB_REPOSITORY/$GITHUB_RUN_ID/log.txt
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
第三,把审计日志也导出。GitHub 企业审计日志只保留 7 天,但你可以通过 API 把它流式推到自己的存储。用 gh api /orgs/{org}/audit-log --paginate 配合定时任务,把 organization 级别的操作事件(谁改了 branch protection、谁加了 secret、谁触发了 workflow)同步到外部存储,保留周期和业务日志对齐。
第四,把这件事写进 team runbook。GitHub Actions 默认保留 90 天,审计日志默认 7 天,这不是常识,是需要显式传递的知识点。
日志是安全事件的最后一环。配了三年 GitHub Actions,今天才发现根子不在 workflow 逻辑,在于日志消失的那一刻,你已经失去了一切追查的机会。
评论区
登录后可评论。