Overview for Plugin Maintainers

The SECURITY project in the Jenkins Jira is a non-public issue tracker for security vulnerabilities. Public knowledge of these vulnerabilities could put our users at risk, so access to issues is restricted.

We grant access to specific SECURITY issues in JIRA to maintainers of affected plugins. They’re often in a much better position to fix issues in their plugins, and the security team needs to coordinate releases with them even if they don’t end up authoring the fix.

We identify maintainers using uploader permissions metadata, as that is the most reliable source for this kind of information in the Jenkins project. This is also where you would explicitly specify who should be the preferred contact for security issues. Learn more.

Make sure your notification email address configured in Jira is up to date and that you don’t ignore notifications sent from Jira. Obsolete email addresses and ignored emails will delay the initial contact.

Support for Maintainers

In general, the Jenkins security team helps maintainers understand reports, provides relevant documentation and examples, and reviews proposed security fixes.


The Jenkins security team can grant access to the private SECURITY issue in Jira to additional users upon request. This is the preferred information sharing platform between reporters, maintainers, and the Jenkins security team.


The Jenkins security team can create private GitHub repositories to support fix development and review. Any number of GitHub users can be added to these repositories (Read or Write permission) upon request. Jenkins security team members will be available to review and test security fixes.


To support staging of security updates (see below), the Jenkins security team will create a private Maven staging repository.

Due to the sensitive nature of security vulnerabilities, the following practices should be followed in resolving the issue and releasing the plugin:

Practices for Issue Handling

  • Be responsive. Not responding to reports of security vulnerabilities will not make them go away. Even if the reporter does not set a coordinated disclosure deadline, the Jenkins security team will publish security vulnerabilities in security advisories even if no fix exists. If you’re no longer maintaining the plugin, please let us know so we can proceed appropriately.

  • Respect embargoes. A few security issues are embargoed, which means information about them must not be shared with others, typically because a new class of issue was discovered and similar vulnerabilities exist in other components.

  • Keep any information gained from the SECURITY tracker private until a version of the plugin containing the fix is released, as it may put users at risk.

  • Keep the source code for your fix private until a fixed version of your plugin has been released, e.g. by pushing it to GitHub, even it’s just your fork that nobody watches. If you need assistance in fixing the vulnerability, ask for it in the SECURITY issue. The Jenkins security team also offers to review your security fix; please ask for a private repository in the jenkinsci-cert GitHub organization to be created, and submit your fix there.

  • Coordinate the date and time of the release of the fixed plugin with the Jenkins security team. This will allow for assigning a CVE ID prior to release, and publishing a security advisory informing users of the security vulnerability, and how to address it.

Practices for Fix Development

Security fixes should be developed on a branch that will be submitted as a pull request in a private repository in the jenkinsci-cert GitHub organization to facilitate fix review.

  • Keep the security fix minimal. This is not an opportunity to address some old TODO comments, refactor code, or modernize the plugin. All of that can be done in a separate update; either at least a week or two before the security update would be published, or after the security update is published. In some cases, this even means implementing a "hack" solution, and holding off on the superior fix until after the security update is published. This limits the potential risk of regressions in the security update due to unrelated changes. Please also refrain from reformatting code you’re not otherwise changing to make it easier to review the security fix.

  • Keep the security update minimal. If the target branch of the security fix has unrelated changes, branch off from the previous release (specifically the prepare for next development iteration commit) and target that branch instead, or make sure to release the plugin’s unrelated changes a week or two before the security release. This also limits the potential risk of regressions in the security update due to unrelated changes.

  • Keep source code private until the security updates are published. The staging instructions below prevent pushing the release commits, which would result in premature disclosure due to delays in the infrastructure, or the staging process. Once you’ve staged a plugin release to a staging repository, push the branch/commits and release tag to the private repository in the jenkinsci-cert GitHub organization only. From there, the commits and tag will be pushed to the public repository after the security update is made public, typically within an hour.

  • No late changes. Don’t add changes to the security release unless they’re essential for the security fix to work after the fix has been reviewed and approved. Otherwise this will invalidate the testing and review that has happened before.

See also How We Fix Security Issues for general guidelines.

Process Overview

The following is a rough approximation of the typical recommended lifecycle of a plugin security issue in the SECURITY tracker:

  1. Someone reports an issue in a plugin.

  2. The security team evaluates the report.

    1. If we’re confident it is not a security vulnerability, the issue is moved to the JENKINS project.

  3. We determine the maintainer and/or security contact. For the purposes of this document, only plugins maintained by people not also on the security team are considered here. Maintainers and security contacts are decided based on release permissions.

  4. We assign the issue to the plugin maintainers (resulting in access to the issue), and notify them in a comment. If necessary, plugin maintainers are contacted repeatedly, in Jira and/or directly via email, to notify them of this issue.

  5. The plugin maintainer reviews the reported issue.

  6. If they identify it as an actual security vulnerability, they (and, if requested, the security team) work to resolve the issue.

    1. The security team provides a private repository for that work in the jenkinsci-cert GitHub organization.

    2. Work usually happens on a branch, and a corresponding pull request will be used for review.

  7. A date and time of the release is coordinated between the security team and maintainers. The security team handles CVE ID assignment, advance notification of users, and creation of the security advisory.

  8. The security fix is merged. For details, see Merge the Fix below.

  9. A version of the plugin containing the fix is uploaded to a staging repository (see Stage with Maven below).

  10. The staged release is published by the security team, and the corresponding security advisory is published and announced. The source code is pushed to the public GitHub repository. The issue in the issue tracker is closed.

Staging Procedure

Staging includes all the steps described below and is typically done a few days before the scheduled advisory. This strikes a balance between allowing the longest possible time for reviews and testing, while minimizing the risk of releases failing on the intended release date and acknowledging time constraints and different time zones of everyone involved.

The Jenkins security team needs to prepare a Maven staging repository before security updates can be staged, so follow the instructions below only once you know the Maven repository to stage to. Make sure to follow instructions provided by the Jenkins security team if they deviate from the instructions below.

Merge the Fix

First, prepare the release branch: If there are unrelated, unreleased changes on the default branch, create a new branch based on the previous release. For plugins with manual release process this is the prepare for next development iteration commit. For plugins delivered with JEP-229 CD automated releases), it is the commit that got tagged as a release.

Next, use the Git command line to squash-merge pull request branches in the private jenkinsci-cert repository (git merge --squash <BRANCH>).

Do not merge using the GitHub UI: It would by default add a reference to the private PR (like #1), which is confusing (or at best useless) when seen in the public repository.

As commit message, use just the ID of the security issue (for example [SECURITY-12345]), without further details. At this point, it may not be clear exactly how the fix will be announced and documented, and discrepancies between the commit message and security advisory would be confusing. If you didn’t develop the fix, make sure to credit the original author by adding --author='Actual Author <author@example.org>' to the git commit command. To find out what name and email address to put there, see git log <BRANCH>.

Stage with Maven

Plugins with manual releases

For Maven-based plugins that are usually released manually using mvn release:prepare release:perform, use the following command to stage the plugin release. REPONAME is a placeholder for the name of the Maven staging repository that is provided by the Jenkins security team.

mvn -DstagingRepository=maven.jenkins-ci.org::default::https://repo.jenkins-ci.org/REPONAME -DpushChanges=false -DlocalCheckout=true org.apache.maven.plugins:maven-release-plugin:2.5.3:prepare org.apache.maven.plugins:maven-release-plugin:2.5.3:stage

The staging repository name (REPONAME) is never a GitHub URL or GitHub repository name.

Always use release:stage instead of release:perform. While the latter also supports specifying a different repository, it’s not a necessary parameter, so typos in the system property can result in accidental uploads to the public repository, disclosing any vulnerabilities early.

Plugins with otherwise automated releases (JEP-229 CD)

For Maven-based plugins that use JEP-229, use the following commands to stage the plugin release. REPONAME is a placeholder for the name of the Maven staging repository that is provided by the Jenkins security team.

Build and deploy the release

mvn -Dset.changelist -DaltDeploymentRepository=maven.jenkins-ci.org::default::https://repo.jenkins-ci.org/REPONAME deploy

The staging repository name (REPONAME) is never a GitHub URL or GitHub repository name.
If your account is allowed to upload plugin releases, be very careful to enter the -DaltDeploymentRepository argument correctly, as any typo in the name would end up deploying to the regular Maven repository, creating a public release.
Create the tag

git tag "$( mvn -q help:evaluate -Dexpression=project.version -DforceStdout -Dset.changelist )"

The specific syntax depends on your shell. This command works for bash and zsh. You can also just run mvn … first, then copy the output and provide it as argument to git tag manually.

Since this release is staged from a private GitHub repository, be careful not to merge changes into the public GitHub repository that would trigger further releases until after the private commits have been made public after advisory publication. Otherwise, administrators may not be offered the staged release containing the security fix, but another release created from the public repository.

Push Commits and Tags

After uploading, push the release commits/branch(es) and tag(s) to the private GitHub repository in the jenkinsci-cert GitHub organization, but NOT to the public (jenkinsci) repository. The Jenkins security team will typically push these tags and branches to the public repository after the security advisory has been published, or will comment on the private SECURITY issue asking the maintainer to do it otherwise.

Keep Documentation Private

Documentation (outside the plugin source code, e.g. in the Jenkins wiki or in GitHub releases metadata) should only be published once the security advisory has been published.