配了三年 GitHub Actions,今天才发现日志只保留 90 天——安全事件发生时根子不在代码,在「日志没了」

三个月前一次供应链攻击,回过头来想查是谁改的 workflow——日志没了。这类故事在安全圈不是个案,而是 GitHub Actions 默认行为的必然结果。

GitHub Actions 的日志保留规则是这样的:

工作流运行日志默认保留 90 天。公开仓库可以调成 1~90 天,私有仓库可以调成 1~400 天。听起来选择很多,但有三条硬限制你必须知道:

第一,只改新文件,不追溯。你今天把保留期改成 400 天,已删除的旧日志不会回来。

第二,日志内容本身有盲区。GitHub 官方文档写得很清楚:workflow run logs 只捕获标准输出。network callsfilesystem modificationsbackground 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 逻辑,在于日志消失的那一刻,你已经失去了一切追查的机会。

评论区

0 条评论

登录后可评论。