Workflow artifacts expire after 90 days by default, and the retention-days input accepts 1 to 90. To keep an SBOM or scan report for an audit period, copy it to storage you control at the end of the workflow, record its digest, and keep the release identifier in the file name.
What the documentation says
The actions upload-artifact README says artifacts are retained for 90 days by default, that you can choose a shorter period with retention-days, and that the value must be between 1 and 90 inclusive. GitHub's page on removing artifacts adds that you can check an artifact's scheduled deletion through the expires_at value in the REST API, and that deleting a workflow run deletes its artifacts too.
Organization settings can also limit retention, and from 1 October 2026 the same policy governs checks, workflow runs and commit statuses as well. See the retention change.
Artifact or storage
| Question | Keep it as an artifact | Copy to your own storage |
|---|---|---|
| Needed for a week of debugging | Yes | Not needed |
| Needed for an audit period of six to twelve months | Risky | Yes |
| Must prove the file was not edited | Weak | Strong with a digest and write-once settings |
Steps
- In the build workflow, generate the SBOM and run the scan.
- Upload both with upload-artifact so they are visible to the team in the run.
- In a follow-up step, copy them to a bucket or evidence store with a path that includes the repository, release tag and date.
- Compute a SHA-256 of each file and store it beside the file.
- Turn on object versioning or write-once retention on the bucket so the copy cannot be quietly replaced.
- Add a line to an index file: release, commit, file name, digest, upload time.
Keep the index in a simple format such as CSV so a person can open it during an audit without special tools. Our guide on archiving SBOMs and provenance for every release goes further on the release side.
What to name the files
Use names that survive being moved: repository, tag, tool, date. A file called report.json tells nobody anything in a year. A file with the tag and scan date answers the first question an auditor asks.
Common traps
Setting retention-days to 90 and assuming that is long enough. Storing only the latest scan, so the history disappears. Giving the CI job broad write permission to the evidence bucket. Scope it to a path prefix and make deletion impossible from CI.
Try it yourself
Click through it at your own pace, or open it full screen. Look at what a dependency inventory contains, which is the content worth archiving per release.
Where Safeguard fits
Safeguard provides SBOM and dependency scanning and compliance and evidence automation, with results stored beyond a single CI retention window. Try the free scan.
Quick check
What is the longest retention-days value?
The README says the value must be between 1 and 90 inclusive.
How can I see when an artifact will be deleted?
The REST API returns an expires_at value for each artifact.
Sources
- actions/upload-artifact README
- GitHub Docs: removing workflow artifacts
- GitHub Docs: retention period configuration
Last reviewed: 19 October 2026.