Safeguard
Developer Tools•

Keeping scan results as build artifacts: five CI systems compared

How GitHub Actions, GitLab CI, Jenkins, CircleCI and Azure DevOps keep scan output, the keyword each uses, retention defaults and the failed run trap.

Safeguard Security Team
3 min read

Every major CI system can keep a scan result file with the run, but the keyword, retention and failure behaviour differ. The common trap is that the save step is skipped when an earlier step fails. Make the upload run always, and set retention on purpose.

Why keep them at all

Safeguard's CI/CD guidance lists keeping scan results as build artifacts as a best practice. A result file ties a finding to a specific commit and build, which helps when someone asks months later what was known at release time. It also lets you compare runs.

The five approaches

GitLab CI uses the artifacts keyword with paths. The expire_in keyword sets how long they stay, and it overrides the instance default. GitLab's documentation says that report type artifacts upload whether the job succeeded or failed, but for plain paths you should set when to always.

Jenkins uses the archiveArtifacts step. Put it in a post block with the always condition, which Jenkins documents as running regardless of result. The fingerprint option records file fingerprints.

CircleCI uses store_artifacts with a path. Its when setting accepts on_success, on_fail and always. Files are kept 30 days by default and a file can be up to 3 GB, per CircleCI.

Azure DevOps uses the publish keyword, a shortcut for the Publish Pipeline Artifact task, with a path and artifact name. Deleting the run deletes its artifacts, and artifacts are not available to the same job that published them but to dependent jobs.

GitHub Actions can upload SARIF to code scanning, which stores alerts in the repository's Security tab rather than as a file. For a plain file, use an artifact upload step of your choice and check its retention setting, which this post did not verify.

The failed run trap

If the scan job fails, or a later test job fails, the default behaviour in several systems is to skip remaining steps. That drops the one file you wanted. Use the always style condition in each system. In Azure, that is a condition on the publish step.

Retention advice

Short retention costs nothing and lowers exposure, because an SBOM lists everything you ship. Long retention helps audits. A reasonable split is to keep run artifacts for a few weeks and copy release build results to a longer lived store, such as the platform, at tag time.

What to name the files

Include the commit in the name when the system allows it, or rely on the run metadata. A file called results.json tells nobody which build it came from once it is downloaded.

Matching the artifact to a decision

Ask who will use the file. An auditor wants the release build kept for a long time. A developer wants the latest pull request run for a day. A security engineer wants trends, which no artifact store gives you. Choose the system for each reader instead of one setting for all.

Quick check

Do artifacts replace a vulnerability management system?

No. Artifacts are evidence per build. A platform tracks state over time, such as accepted risks and fixes.

Can an artifact leak secrets?

Yes, if the tool writes them. Keep detect redaction on and limit who can download artifacts.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.