Security Hardening: New API token system in Jenkins 2.129+
Jenkins API tokens are an authentication mechanism that allows a tool (script, application, etc.) to impersonate a user without providing the actual password for use with the Jenkins API or CLI. This is especially useful when your security realm is based on a central directory, like Active Directory or LDAP, and you don’t want to store your password in scripts. Recent versions of Jenkins also make it easier to use the remote API when using API tokens to authenticate, as no CSRF tokens need to be provided even with CSRF protection enabled. API tokens are not meant to — and cannot — replace the regular password for the Jenkins UI.
We addressed two major problems with the existing API token system in Jenkins 2.129:
First, reported in JENKINS-32442, user accounts in Jenkins have an automatically generated API token by default. As these tokens can be used to authenticate as a given user, they increase the attack surface of Jenkins.
The second problem was reported in JENKINS-32776: The tokens were previously stored on disk in an encrypted form. This meant that they could be decrypted by unauthorized users by leveraging another security vulnerability, or obtained, for example, from improperly secured backups, and used to impersonate other users.
The main objective of this new system is to provide API tokens that are stored in a unidirectional way on the disk, i.e. using a hashing algorithm (in this particular case SHA-256).
While this means that you will not be able to see the actual API tokens anymore after you’ve created them, several features were added to mitigate this potential problem:
You can have multiple active API tokens at the same time. If you don’t remember an API token’s value anymore, just revoke it.
You can name your tokens to know where they are used (and rename them after creation if desired). We recommend that tokens use a name that indicates where (for example the application, script, or host) where it will be used.
You can track the usage of your tokens. Every token keeps a record of the number of uses and the date of the last use. This will allow you to better know which tokens are really used and which are no longer actively required. Jenkins also encourages users to rotate old API tokens by highlighting their creation date in orange after six months, and in red after twelve months. The goal is to remind the user that tokens are more secure when you regenerate them often: The longer a token is around, perhaps passed around in script files and stored on shared drives, the greater the chance it’s going to be accessed by someone not authorized to use it.
You can revoke API tokens. When you know that you are not using a given token anymore, you can revoke it to reduce the risk of it getting used by unauthorized users. Since you can have multiple API tokens, this allows fine-grained control over which scripts, hosts, or applications are allowed to use Jenkins as a given user.
To help administrators migrate their instances progressively, the legacy behavior is still available, while new system is also usable.
On the user configuration page, the legacy token is highlighted with a warning sign, explaining that users should revoke it and generate a new one (if needed) to increase security.
In order to let administrators control the pace of migration to the new API token system, we added two global configuration options in the "Configure Global Security" page in the brand new "API Token" section:
An option to disable the creation of legacy API tokens on user creation.
An option to disable the recreation of legacy API tokens by users, forcing them to only use the new, unrecoverable API tokens.
Both options are disabled by default for new installations (the safe default), while they’re enabled when Jenkins is upgraded from before 2.129.
When upgrading to Jenkins 2.129, an administrative monitor informs admins about the new options described above, and recommend disabling them.
Another administrative warnings shows up if at least one user still has a legacy API token. It provides central control over legacy tokens still configured in the Jenkins instance, and allows revoking them all.