How to Manage Jenkins Users: A Complete Guide to the User API
Jenkins represents each user with the hudson.model.User class, providing lifecycle management, persistence to XML, security integration, and REST API access through the core/src/main/java/hudson/model/User.java source file.
Managing Jenkins users programmatically requires understanding the core User model that powers both the web interface and automation scripts. The hudson.model.User class in the jenkinsci/jenkins repository handles everything from on-demand creation to deletion, storing each user's configuration in individual XML files under $JENKINS_HOME. Whether you are administering users through the script console, Groovy scripts, or HTTP requests, the underlying architecture remains consistent and extensible through the UserProperty system.
Understanding the Jenkins User Architecture
The Jenkins user management system is built around several key components that work together to provide a pluggable, secure identity framework.
Core Components
-
User object – Defined in
core/src/main/java/hudson/model/User.java, this class holds the user ID, full name, description, and a collection ofUserPropertyinstances. The class header defines the model between lines 26-34. -
On-demand creation – User objects are instantiated lazily through factory methods. The
getOrCreateByIdfactory and private constructor ensure thatUser.get(id, true)only creates records when explicitly requested. -
Persistence layer – Each user is stored in its own folder under
$JENKINS_HOME/users/<hashed-folder>/config.xml. ThegetConfigFile()method builds this path, whilesave()writes the XML representation. -
User registry –
User.AllUsersacts as a singleton registry holding a map of all loaded users, keyed by the canonical ID strategy. The registry populates at startup viaAllUsers.scanAll()(lines 990-1014). -
Security integration – The
Userclass implementsAccessControlled, withgetACL()(lines 606-614) granting users full control over themselves while deferring to the global security strategy for other permissions. -
Extensible properties – The
propertieslist storesUserPropertyobjects such as API tokens and profile pictures. Adding a property viaaddProperty()automatically persists the change.
Creating and Retrieving Users
Jenkins uses lazy initialization for user objects. The primary factory method User.get(String idOrFullName, boolean create) retrieves existing users or creates new ones on demand.
Script Console Method
Run this Groovy code in Manage Jenkins > Script Console to create or retrieve a user:
// Retrieve an existing user or create a new one on-demand
def jenkins = jenkins.model.Jenkins.instance
def alice = hudson.model.User.get("alice", true) // true => create if missing
alice.fullName = "Alice Example"
alice.description = "Team lead for UI"
alice.save() // persists to $JENKINS_HOME/users/…
println "Created user: ${alice.id} (${alice.fullName})"
The save() method validates the user ID against restricted names (such as anonymous, system, or unknown) using isIdOrFullnameAllowed() before writing to disk.
Managing User Properties
User properties extend the base User object with additional functionality like API tokens and avatar images. The UserProperty base class lives in core/src/main/java/hudson/model/UserProperty.java.
Adding an API Token
import jenkins.security.ApiTokenProperty
def bob = hudson.model.User.get("bob", true)
def tokenProp = new ApiTokenProperty()
bob.addProperty(tokenProp) // automatically persists the property
println "API token for ${bob.id}: ${tokenProp.getApiToken()}"
Calling addProperty() immediately updates the user's config.xml file. The UserPropertyDescriptor class (core/src/main/java/hudson/model/UserPropertyDescriptor.java) provides the descriptor pattern for creating default property instances.
Listing All Users
To enumerate every user in the system, access the singleton registry through User.getAll():
hudson.model.User.getAll().each { u ->
println "${u.id} – ${u.fullName}"
}
This method returns a collection of all loaded User objects from the AllUsers internal cache.
Deleting Users
Jenkins provides multiple deletion pathways, all requiring the ADMINISTER permission and preventing self-deletion.
REST API Deletion
# Delete user "dave" via HTTP POST (requires ADMINISTER permission)
curl -X POST -u admin:adminToken \
http://jenkins.example.com/user/dave/doDelete
The doDoDelete() method (lines 122-131) performs permission checks, validates that the current user is not deleting themselves, removes the user's folder from $JENKINS_HOME/users/, and clears the cache entry from User.AllUsers.
Accessing Users via the REST API
Every user exposes a REST endpoint for programmatic access to their data.
JSON Endpoint
curl -u admin:adminToken http://jenkins.example.com/user/alice/api/json
The getApi() method (lines 915-917) returns a new Api object that handles the serialization of User properties to JSON or XML.
Updating Descriptions via POST
curl -X POST -u admin:adminToken \
-F "description=New description for Carol" \
http://jenkins.example.com/user/carol/submitDescription
The doSubmitDescription() method processes this request and persists changes through the standard save() mechanism.
Security Implementation Details
The User class implements AccessControlled to integrate with Jenkins' role-based security model. The getACL() implementation combines a per-user access control list (granting full control to the user over their own record) with the global security realm's ACL. For authentication caching, Jenkins uses UserDetailsCache (core/src/main/java/jenkins/security/UserDetailsCache.java) and ImpersonatingUserDetailsService2 to handle user impersonation and session management.
Summary
- User model – The
hudson.model.Userclass incore/src/main/java/hudson/model/User.javaprovides the core identity management functionality. - Lazy creation – Use
User.get(id, true)to create users on demand through the Groovy script console. - Persistence – Users are stored as XML files in
$JENKINS_HOME/users/<hashed-folder>/config.xml. - Extensibility – Attach
UserPropertyobjects (API tokens, profiles) viaaddProperty()for automatic persistence. - Deletion safety – The
doDoDelete()method requires ADMINISTER permission and prevents self-deletion. - Programmatic access – Access user data via
/user/<id>/api/jsonendpoints exposed bygetApi().
Frequently Asked Questions
How are Jenkins users stored on disk?
Each user is stored in a separate directory under $JENKINS_HOME/users/ using a hashed folder name. Inside each folder, a config.xml file contains the serialized User object and its properties. The getConfigFile() method constructs this path, and save() handles the XML serialization.
Can I create Jenkins users without using the web UI?
Yes. Use the Groovy script console with hudson.model.User.get("username", true) to create users programmatically. Set the fullName and description properties, then call save() to persist. You can also use the REST API to modify existing user properties via POST requests to endpoints like /user/<id>/submitDescription.
What prevents invalid user IDs in Jenkins?
The isIdOrFullnameAllowed() method validates user IDs during the save() operation. It rejects reserved system names including anonymous, system, and unknown to prevent conflicts with Jenkins' internal security contexts and special user accounts.
How does Jenkins handle user deletion permissions?
The doDoDelete() method enforces strict security controls. It requires the ADMINISTER global permission, prevents users from deleting their own accounts (self-deletion protection), and removes both the on-disk folder and the in-memory cache entry from User.AllUsers to ensure complete removal from the system.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →