# GitLab Release Evidence

![Release Evidence Chain](/files/oOYGBq0k0I3yALKkUwhJ)

> **Intro:** Release evidence is where the pipeline stops being a transient execution log and becomes a durable record. For security teams, this matters because a good release story is not only “the pipeline was green”. It is also “here is exactly what was built, tested, scanned, approved, and released.”
>
> **What this page includes**
>
> * what GitLab release evidence captures and why it matters
> * how to preserve artifacts so evidence remains useful
> * practical GitLab snippets for tagging releases and collecting evidence snapshots
>
> **Working assumptions**
>
> * auditability should be a by-product of engineering flow, not a separate ritual at the end of the quarter

## What release evidence is for

Release evidence is a **JSON snapshot** associated with a GitLab release. It can include release metadata, linked milestones, and report artifacts from the relevant pipeline.

This is useful for:

* external and internal audits;
* release retrospectives;
* proving that specific controls were executed;
* reducing ambiguity when people ask “what exactly went live?”

## What makes evidence valuable

Evidence only helps if the pipeline has preserved meaningful artifacts.

| Artifact type                    | Why it matters                                         |
| -------------------------------- | ------------------------------------------------------ |
| test reports                     | proves basic verification happened                     |
| SAST / DAST / SCA reports        | shows security controls were executed                  |
| SBOM or dependency report        | supports supply-chain review                           |
| signed package or image metadata | ties the release to a verified build artifact          |
| changelog or release notes       | explains intent and scope                              |
| approval data                    | shows that risky releases were deliberately authorized |

## Design rule: keep the proof alive long enough

If your security jobs write artifacts but those artifacts expire before evidence is collected, the release record will be weaker than it should be.

Use artifact retention intentionally:

```yaml
artifacts:
  paths:
    - rspec.xml
    - semgrep.json
    - zap/zap.html
  reports:
    junit: rspec.xml
  # Pick a retention period that fits your audit and incident-review needs.
  expire_in: 30 days
```

## Minimal tag-and-release pattern

```yaml
create_release:
  stage: release
  image: registry.gitlab.com/gitlab-org/cli:latest
  script:
    - >-
      glab release create "$CI_COMMIT_TAG"
      --ref "$CI_COMMIT_SHA"
      --notes-file CHANGELOG.md
  rules:
    - if: $CI_COMMIT_TAG
```

This works well when:

* tags are your release boundary;
* release notes are generated or maintained as code;
* package and security checks have already passed.

## Collect an extra evidence snapshot

GitLab collects release evidence automatically when the release is created, but it can also collect an additional snapshot later through the API.

```yaml
collect_release_evidence:
  stage: release
  image: registry.gitlab.com/gitlab-org/cli:latest
  needs: [create_release]
  script:
    - >-
      glab api -X POST
      "/projects/$CI_PROJECT_ID/releases/$CI_COMMIT_TAG/evidence"
  rules:
    - if: $CI_COMMIT_TAG
```

Use an additional snapshot when:

* some artifacts become available only after initial release creation;
* you want evidence after a downstream verification step;
* you need a new point-in-time record for compliance or change control.

## A more complete release job with attached assets

```yaml
create_release:
  stage: release
  image: registry.gitlab.com/gitlab-org/cli:latest
  needs:
    - package_image
    - security_gate
    - zap_baseline
  script:
    - |
      glab release create "$CI_COMMIT_TAG"         --ref "$CI_COMMIT_SHA"         --notes-file CHANGELOG.md         --assets-links='[
          {"name":"Container image digest","url":"https://registry.example.com/product-api@'$IMAGE_DIGEST'"},
          {"name":"SBOM","url":"https://gitlab.example.com/$CI_PROJECT_PATH/-/jobs/$CI_JOB_ID/artifacts/file/sbom.json"},
          {"name":"ZAP HTML report","url":"https://gitlab.example.com/$CI_PROJECT_PATH/-/jobs/$CI_JOB_ID/artifacts/file/zap/zap.html"}
        ]'
  rules:
    - if: $CI_COMMIT_TAG
```

## What a security team should verify before trusting the evidence

1. **The release was created from the correct ref or tag.**
2. **Artifacts belong to the expected pipeline and commit.**
3. **Security jobs were not skipped silently.**
4. **Artifact retention is long enough for audit and incident-review needs.**
5. **Evidence snapshots are collected after the right control points.**

## Good pairings

Release evidence becomes much stronger when combined with:

* [Security Quality Gates and Release Blocking](/devsecops-cicd-and-supply-chain/index-1/security-quality-gates-and-release-blocking.md)
* signed images and commits from the snippets branch;
* protected environments and manual production approval;
* SBOM retention and provenance metadata;
* a changelog that maps release scope to issues or milestones.

## Common mistakes

| Mistake                                           | Why it hurts                                                   |
| ------------------------------------------------- | -------------------------------------------------------------- |
| creating releases without preserved artifacts     | evidence has very little to point to                           |
| treating evidence as an audit-only feature        | teams miss its operational value during incidents or rollbacks |
| collecting evidence before security outputs exist | snapshot is incomplete                                         |
| relying on mutable external links only            | future investigators cannot reconstruct the release cleanly    |

## Related pages

* [GitLab CI YAML Deep Dive](/devsecops-cicd-and-supply-chain/index-1/gitlab-ci-yaml-deep-dive.md)
* [Security Quality Gates and Release Blocking](/devsecops-cicd-and-supply-chain/index-1/security-quality-gates-and-release-blocking.md)
* [Git Commit Signing and Image Signing](/learning-labs-interview-and-templates/index/git-commit-signing-and-image-signing.md)

***

*Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.*

## Use this page with

* [Compliance-to-Engineering Evidence Pass](/metrics-audit-risk-evidence-and-compliance/index-1/compliance-to-engineering-evidence-pass.md)
* [CSA Cloud Controls Matrix (CCM) — Practical Guide](/metrics-audit-risk-evidence-and-compliance/index-1/csa-cloud-controls-matrix-ccm-practical-guide.md)
* [Signing, Attestation, and Verification — Legacy vs Current](/devsecops-cicd-and-supply-chain/index-1/signing-attestation-and-verification-legacy-vs-current.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.product-security.expert/devsecops-cicd-and-supply-chain/index-1/gitlab-release-evidence.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
