How to Build a Who/What/When Audit Trail of Deploys
Creating a GitHub Deployment for each release captures the actor, commit SHA, environment, and timestamp in one queryable record.
Auditors ask who deployed what and when. The GitHub Deployments API records exactly that, and a structured log line gives you a second, exportable copy. Emit both from the deploy job. This is educational guidance for building traceability.
Steps
- Create a deployment record with actions/github-script (captures actor, SHA, environment).
- Emit a structured JSON log line with the same fields for log-based search.
- Update the deployment status to success or failure at the end.
Record the deployment
.github/workflows/deploy.yml
permissions:
deployments: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
script: |
const d = await github.rest.repos.createDeployment({
owner: context.repo.owner, repo: context.repo.repo,
ref: context.sha, environment: 'production',
required_contexts: [], auto_merge: false
})
core.setOutput('id', d.data.id)Structured log line
Terminal
echo "{\"event\":\"deploy\",\"actor\":\"${{ github.actor }}\",\"sha\":\"${{ github.sha }}\",\"env\":\"production\",\"run\":\"${{ github.run_id }}\",\"ts\":\"$(date -u +%FT%TZ)\"}"Notes
- Deployment records survive even after the workflow log retention window passes.
- Ship the JSON line to your SIEM so the trail lives outside the CI system too.
Related guides
How to Keep CI Audit Logs ImmutableShip GitHub Actions audit logs to write-once storage such as S3 Object Lock so the record cannot be altered o…
How to Collect CI Evidence for an AuditExport GitHub Actions workflow runs, approvals, and reviews with the gh CLI and REST API to produce audit evi…
How to Log Incidents and Rollbacks in CIRecord rollbacks and incident-linked deploys in GitHub Actions with deployment status updates and structured…