Content last updated 2026-03-19

パッチリリースにおける Product Security Incident Response Team の一般的なプロセス

  • release-management

GitLab Security Patch Release Process

This document outlines the process and responsibilities for managing security patch releases at GitLab for a PSIRT Engineer.

You can find the current month’s release managers (from PSIRT) by utilizing our dynamically updated Release-Manager-Scheduling wiki.

Introduction and Process Overview

The security patch release process ensures that security vulnerabilities in GitLab products are properly addressed, documented, and communicated to users based on vulnerability SLAs. This systematic approach helps protect GitLab users by quickly resolving security issues while maintaining appropriate transparency about the fixes.

For information about which versions receive security fixes, see the GitLab Maintenance Policy.

Security patch releases come in two main types:

  • Planned patch releases: Scheduled twice a month on Wednesdays of the weeks before and after the monthly release.
  • Unplanned patch releases: Immediate patches required outside the planned cadence to mitigate high-severity (critical) vulnerabilities. These ad-hoc patches typically result from security incidents and may only include the fix for the critical vulnerability.

This handbook page describes the responsibilities and processes for PSIRT engineers involved in these releases.

Expected Outputs

  1. Patched GitLab Release with all security fixes included
  2. Published Blog Post detailing vulnerabilities and fixes
  3. Communication email sent to customers with blog post link
  4. Published CVEs with accurate version and description information
  5. HackerOne reports marked as resolved and rewarded

High-Level Overview

This diagram shows a high-level overview of the process for a PSIRT engineer working on a security release:

flowchart TD
    A[PSIRT Task Issue created by release automation (release tools bot)] --> B[Run validate_release and update_cves;\nensure CVEs and security issues are complete]
    B -.->|Delivery team: draft blog post MR| C[Engineer reviews blog post and comms]
    C -.->|Delivery team: publishes blog post| D[Blog post is published]
    D --> E[Engineer runs close_release;\ncloses issues, publishes CVEs, notifies HackerOne]
    D --> F[Engineer coordinates comms:\nemail to Security Alerts subscribers]

PSIRT Release Management Procedures

PSIRT Task Issue

The PSIRT Task Issue (patch release checklist) is generated by the release team tooling, typically a few days before the scheduled patch release (often the Sunday or Monday before a regularly scheduled patch). A notification is shared in the #sec-appsec Slack channel when it is created.

You can also find these issues in gitlab-org/gitlab by searching for open work items whose title contains PSIRT Task Issue, or by using the ~"AppSecWorkType::SecurityReleaseRotation" label.

Planned Patch Releases Process

The release process spans several days. Tasks are captured in the PSIRT Task Issue, which is created by delivery automation. Refer to the checklist template as a source of truth for patch release PSIRT tasks (the generated issue title references PSIRT).

Upcoming patch releases can be found in the GitLab issue list filtered by the upcoming security release label.

Security release tools and script order

Before working through the PSIRT Task Issue for a particular patch release, clone and set up security release tools.

  1. After the PSIRT Task Issue exists, run bin/validate_release.rb to validate CVSS, council approvals, and related fields; it can post comments on issues when information is missing.
  2. Once patch release version numbers are set, run bin/update_cves.rb to refresh CVE YAML (including affected/fixed version placeholders and descriptions where applicable).
  3. When ready, use bin/generate_blog_post.rb to produce the “Security fixes” section for the draft blog post MR (or use the pipeline job in the tools project, per the checklist).
  4. After the blog post is published, run bin/close_release.rb to close canonical issues, request CVE publication, and notify HackerOne (use --live and the appropriate flags; see --help).
  5. Optionally run bin/make_thankyou.rb for a #thanks Slack message.

Follow the PSIRT Task Issue checklist for exact steps, MR links, and stakeholder pings.

Pre-Release (starts ~2 days before release):

  • CVE verification and updates:

    The engineer on rotation is responsible for ensuring all CVEs in the release have their required fields properly filled in. The engineer who originally imported a HackerOne report is automatically assigned to its CVE issue and can help supply missing details. Security release tools automatically populate many CVE fields once issues are linked to the upcoming release; any remaining or missing fields below may require human review.

    On each linked security issue, ensure required details are present in the issue (for example GitLab EE Only and First Version Affected in the Details table).

    Given the following example CVE YAML (template source):

    vulnerability:
    # If the affected product is GitLab, please mention if it's GitLab CE/EE or GitLab EE
    description: TODO   # "[VULNTYPE] in [COMPONENT] in [VENDOR][PRODUCT] affecting all versions from 1X.X prior to 16.X.X, 16.Y prior to 16.Y.Y, and 16.Z prior to 16.Z.Z allows [ATTACKER] to [IMPACT] via [VECTOR]"
    cwe: CWE-400 # TODO, for example "CWE-22" # Path Traversal
    product:
      gitlab_path: gitlab-org/gitlab   # "namespace/project" # the path of the project within gitlab
      vendor: GitLab   # "iTerm2"
      name: GitLab   # "iTerm2"
      # GitLab advisories MUST reference at least one CPE. Uncomment the best fitting CPE below and feel free to modify
      # the wildcard values to be more specific if applicable.
      # See https://en.wikipedia.org/wiki/Common_Platform_Enumeration#Scheme_format for more information on the format.
      cpes:
        - cpe:2.3:a:gitlab:gitlab:*:*:*:*:*:*:*:*
        # - "cpe:2.3:a:gitlab:gitaly:*:*:*:*:*:*:*:*"
        # - "cpe:2.3:a:gitlab:runner:*:*:*:*:*:*:*:*"
        # - "cpe:2.3:a:gitlab:gitlab-shell:*:*:*:*:*:*:*:*"
        # - "cpe:2.3:a:gitlab:dast_api_scanner:*:*:*:*:*:*:*:*"
        # - "cpe:2.3:a:gitlab:dynamic_application_security_testing_analyzer:*:*:*:*:*:*:*:*"
        # - "cpe:2.3:a:gitlab:gitlab-vscode-extension:*:*:*:*:*:*:*:*"
      affected_versions:
        - '>=1X.X, <16.X.X' # "1.2.3"
        - '>=16.Y, <16.Y.Y' # "1.2.3"
        - '>=16.Z, <16.Z.Z' # "1.2.3"
      fixed_versions: [] # If empty, fixed versions will be automatically filled based on affected version constraints
      # fixed_versions:
      #  - "16.X.X"
      #  - "16.Y.Y"
      #  - "16.Z.Z"
    impact: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H   # CVSS:3.1 string, without the prefix
    solution: '' # If empty, solution will be automatically filled based on affected version constraints
    # solution: "Upgrade to version 16.X.X, 16.Y.Y or 16.Z.Z"
    credit: Thanks [example](https://hackerone.com/) for reporting this vulnerability
      through our HackerOne bug bounty program
    # credit: "This vulnerability has been discovered internally by GitLab team member <TEAM MEMBER NAME>"
    references:
       - https://gitlab.com/
    

    The engineer should ensure that the following fields are properly filled out:

    • CVE request issue title: Use the format ${CWE_TITLE} issue in ${COMPONENT} impacts GitLab ${GITLAB_EDITION}. This title is consumed by automation (for example blog post generation). Do not pack the title with exploitation hints: avoid naming specific endpoints, parameters, internal code paths, or reproduction steps that would make it easy for someone to rediscover or weaponize the issue before customers can patch. Revise auto-generated or tool-suggested titles that are too specific.
    • description (in the CVE YAML): Must reflect the vulnerability and affected versions, stay aligned with our process for disclosing security issues, and must not leak information that would materially help an attacker discover and develop an exploit ahead of broad patch adoption. For tone and wording (for example avoiding sensational terms), use Security Communications guidance and the internal PSIRT patch release runbook.
    • cwe:: The cwe field should contain a value that fits the vulnerability. It needs to be a non-discouraged one by MITRE. Duo is typically pretty helpful at suggesting good values for this.
    • cpes:: The cpes field should properly reflect the affected product
    • affected_versions: The first line should contain the first affected version. This is determined by engineering and put in the Details table of a security release as Version affected (example)
    • fixed_versions:: This should match release version numbers
    • impact:: This needs to be the CVSS determined in the associated bug bounty council discussion
    • credit:: It should contain the person who found the CVE, typically a HackerOne reporter or a GitLab team member
    • references:: It should have the canonical issue as a reference, as well as the HackerOne report in such cases
    Human review and description::validated label of CVE request issues

    Review the CVE request issue title and YAML description. When both are accurate and suitably vague for coordinated disclosure (not detailed enough to make exploitation easy before customers patch) add description::validated to the CVE request issue.

    That label means a human reviewed and approved the title and description as they appear, and they do not overshare.

  • Draft blog post review:

    The engineer on rotation is responsible for the content of the blog post. While much of it is generated from the CVE contents when all of the automation works, it’s important to double verify that all the information within it is accurate.

    The Security blog post is automatically generated one day before the patch release due date.

    Things to look for when reviewing the blog post:

    • It contains all of the issues resolved in a release
    • It does not include any issues that are not in the release. Watch for reverted MRs and unlinked issues; routine releases can change at the last minute. Confirm fix lists before the post moves to canonical www-gitlab-com.
    • The CVE titles and descriptions do not contain more information than necessary for initial disclosure. They should be intentionally vague, but descriptive enough to differentiate between similar vulnerabilities of the same weakness style in the same release. Full technical details are made available via our process for disclosing security issues.
    • All versions mentioned in the blog post match the release version
    • No ‘TODO’ is left behind in the blog post.
    • The ‘Table of security fixes’ and the CVEs are properly ordered by severity
    • Links in the ‘Table of security fixes’ work and link to each associated entry within the blog post
    • Ensure that we follow the Documentation Style Guide as much as possible. For example, if an acronym is used, we spell it out on first use on a page.
    • The author: and author_gitlab: should be set to the engineer on rotation

Release Day:

  • Final verification of included fixes:

    Ensure nothing has been added or removed at the last minute. If changes occurred, confirm the blog post reflects the final set of included fixes (no removed entries, and any newly included fixes are present).

  • Blog post finalization:

    Final review of the blog post before it is being sent out. Ensure you have had at least one other team member review the blog post. The delivery release manager will ask whether PSIRT is ready on release day before releasing the blog post.

  • Communication to stakeholders:

    Let the Marketing team know that the blog post is about to be released by using the linked Security communications issue (a link should be available in the PSIRT Task Issue). In case of critical security patches, ensure that communications is aware of it by posting a message in #comms-team-security and has reviewed and approved of customer communications.

Comms coordination (email and subscribers)

After the blog post is published, follow the Release finalization section of the PSIRT Task Issue so that email communications go out to customers subscribed to GitLab’s Security Alerts mailing list. Coordinate with the comms contact on the Security communications issue (and Marketing Ops when the checklist calls for it) to test and send email as documented there.

Post-Release (After publication):

Post-release steps are usually performed with bin/close_release.rb (dry-run by default; use --live to apply). Typical flags include --close-issues, --publish-cves, and --notify-hackerone, scoped with --release-issue IID. See bin/close_release.rb --help and the PSIRT Task Issue checklist.

  • Issue closure:

    Close all issues on the canonical repository, with a reminder to pay a bounty in cases where it fits.

  • CVE publishing:

    • Review each CVE to ensure the advisory::invalid label is absent first. If it is present, look for comments from the cnaworkflow bot that describes why the submission is considered invalid.
    • Confirm each CVE request issue still has the description::validated label before you request publication (security-release-tools performs checks for this).
    • Set all CVEs to Publish Immediately by ticking the appropriate box in the issue description for the relevant ones.
  • HackerOne notifications:

    Notify the engineer associated with the HackerOne reports associated with the release that the fix is out, and on which version.

  • Public acknowledgments (optional):

    Use the bin/make_thankyou.rb script to create a thank you message and post it in the #thanks slack channel in appreciation of the efforts team members put in creating the release.

Summary

For each security patch release:

  1. Use the PSIRT Task Issue - Work from the generated checklist and linked Security communications issue
  2. Run validation - Execute bin/validate_release.rb and resolve gaps (CVSS, council votes, required fields)
  3. Update CVEs - Run bin/update_cves.rb when versions are set; verify YAML and security-issue fields (for example GitLab EE only, first version affected)
  4. Verify CVE information - Ensure titles and descriptions do not overshare; add description::validated when title and description are human-reviewed and approved; confirm CWE values, affected/fixed versions, and CVSS scores are accurate
  5. Generate and review blog content - Use bin/generate_blog_post.rb or the pipeline as appropriate; review draft MR per checklist (language, anchors, versions)
  6. Verify included fixes - Confirm nothing was added or removed last minute (reverted MRs, unlinked issues) before canonical publish
  7. Finalize blog post - Complete final review with at least one other PSIRT member; notify release managers when ready
  8. Communicate with stakeholders - Marketing, Legal, Corporate Communications, and critical-path pings per checklist
  9. Coordinate comms - After publication, complete email steps for Security Alerts subscribers per the PSIRT Task Issue
  10. Close associated issues - Use bin/close_release.rb --close-issues (with --live) where applicable
  11. Publish CVEs - Review for validity; use bin/close_release.rb --publish-cves and set “Publish Immediately” as needed
  12. Send HackerOne notifications - Use bin/close_release.rb --notify-hackerone or equivalent manual steps
  13. Acknowledge contributors - Optionally run bin/make_thankyou.rb and share output in #thanks

Security Fix Development and Verification

Security fixes follow a thorough development and verification process that starts well before the release date. This process can be found here: https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/security/engineer.md

PSIRT Team Organization and Responsibilities

Cross-regional PSIRT Release Managers

To ensure coverage, the PSIRT team assigns two members to each release:

Primary PSIRT Release Manager:

  • Main DRI for the patch release
  • Responsible for executing the core release steps in the checklist

Secondary PSIRT Release Manager (in a different region):

  • Provides regional coverage when the Primary is offline
  • Answers any questions from delivery that arises in their timezone
  • Assists with the completion of release tasks
  • Reviews blog post in the security project

The Primary and Secondary should post handover messages in the #sec-psirt-team Slack channel at the end of their workday to maintain continuous coverage.

The following template is an example for a handover message that can be used:

Patch release handover to @username
Status: (brief status statement)
Next: (brief description of what should happen next)
Links
- Patch release issue:
- PSIRT patch release checklist:
- Release draft blog post MR:
- Release blog post MR:
- Release communications issue:

Additional Stakeholders

Instructions to contact these groups are in the PSIRT task issue under “Collaborative Tasks”.

  • Release Managers: Initiates planned patch releases
  • Legal Team: Reviews security disclosures
  • Corporate Communications: Handles external communication (@gitlab-com/marketing/corporate_marketing/security-communications)
  • Field Security Team: Notified for Critical/High severity issues (@gitlab-com/gl-security/security-assurance/governance-and-field-security/field-security-team/field-security-field-ciso-collaboration)
  • GitLab Dedicated Team: Notified for Critical severity issues
  • Support Team: Coordinated for Critical/High severity issues

Overall Patch Release Process

For a detailed diagram and explanation of the overall patch release process, see the Patch Releases documentation.

Special Considerations for Unplanned Critical Releases

For a detailed process about remediating GitLab environments in case of a critical vulnerability, see the GitLab Critical Vulnerability Remediation Runbook.

As a PSIRT engineer handling a critical (S1) vulnerability, your key responsibilities include:

Initial Assessment and Coordination

  • Work with SIRT, Release Managers, GitLab Dedicated engineers, and the Stage team to assess impact
  • Request CVE immediately upon vulnerability verification
  • Create security tracking issue with ~security and ~“upcoming security release” labels

Vulnerability Analysis

  • Help evaluate impact across GitLab environments (multi-tenant SaaS, single-tenant SaaS, self-managed)
  • Contribute to developing a comprehensive remediation plan

Security Fix Validation

  • Review, validate, and approve the security merge request that remediates the vulnerability
  • Ensure the security fix adequately addresses the vulnerability
    • This is not a pro-forma verification. PSIRT must thoroughly validate that the vulnerability is properly addressed
    • For complex vulnerabilities with multiple dependencies or attack vectors, take sufficient time for a comprehensive review
    • While critical patches are time-sensitive, a proper and robust fix takes priority over speed. It’s acceptable to delay a fix to ensure complete verification
    • For extensive reviews, consider dividing the work among multiple team members

Post-Deployment Validation

  • After production deployment, perform security validation on the production environment
  • Confirm that GitLab.com has been remediated (EOC assistance might be required)

Communication

  • Coordinate with release managers and SIRT on timing and disclosure
  • Help prepare appropriate communications for different stakeholder groups

Definitions

  • CVE: Common Vulnerabilities and Exposures - standardized identifiers for security vulnerabilities
  • Security Repository: Private repository where security issues are initially tracked (e.g., gitlab-org/security/gitlab)
  • Canonical Repository: Public repository where issues are moved after disclosure (e.g., gitlab-org/gitlab)
  • Master MR: The merge request containing the security fix targeting the default branch (master or main)
  • Backport MR: A merge request that applies a security fix to a previous stable version
  • S1: Security severity level 1 (Critical) - highest severity level requiring immediate attention
  • DRI: Directly Responsible Individual - the person accountable for the task
  • Security Communications Issue: Tracking issue for release communications
  • Security Implementation Issue: Issue in the security repository that tracks the implementation of a fix
  • Security Tracking Issue: Issue that tracks all fixes included in a specific security release
  • PSIRT Task Issue: The generated patch-release checklist issue for PSIRT (linked security communications issue, blog MRs, and automation steps)
  • description::validated: Label on a CVE request issue indicating a human has reviewed both the issue title and the CVE description and confirmed they are correct and appropriately limited for disclosure (not overly detailed)

Frequently Asked Questions

What if I realize there is a mistake in the blog post after its been published?

You can create an MR to modify its content by going to https://gitlab.com/gitlab-com/www-gitlab-com/-/tree/master/sites/uncategorized/source/releases/posts?ref_type=heads and finding the file with the blog post to adjust.

What if one of the scripts throws an error?

Complete the steps manually by referring to the present guide and open an issue in the release tools tracker with the error to help identify the issue.

Resources