* [JENKINS-69789] Add configurable password complexity policy to HudsonPrivateSecurityRealm Jenkins' built-in user database currently has no password complexity requirements beyond non-empty and encoder limits. This makes it difficult to meet enterprise security policies. Add configurable password policy options (minimum length, require uppercase/lowercase/digit/special character) via @DataBoundSetter fields on HudsonPrivateSecurityRealm. The policy is enforced on both user self-registration and admin password changes. All options default to off for backward compatibility. Closes #18323 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * [JENKINS-69789] Add password complexity rule extension point Refactor password complexity validation from hardcoded fields to an ExtensionPoint architecture. Add PasswordComplexityRule as a new extension point that allows plugins to contribute custom password validation strategies. Include DefaultPasswordComplexityRule as a built-in implementation with configurable minimum length and character type requirements (uppercase, lowercase, digit, special character). The rule is optional and configured via the Security settings UI using a dropdown selector. When no rule is selected, no extra password requirements are enforced, preserving backward compatibility. Closes #18323 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Spotless import ordering violation in Functions.java Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Add tests for password change flow with complexity rule Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Refactor PasswordComplexityRule per review feedback - Remove PasswordComplexityRuleDescriptor, use Descriptor<PasswordComplexityRule> - Remove getDescriptor() override from PasswordComplexityRule - Change validate() to void, throw PasswordComplexityException - Add NonePasswordComplexityRule to avoid null checks - Use dropdownDescriptorSelector in config.jelly - Remove getPasswordComplexityRuleDescriptors() from Functions.java - Change default minimum length from 0 to 8 - Add readResolve() for backward compatibility - Update tests for new validate() signature Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Remove @Restricted from DataBoundSetter to fix Stapler binding Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix Spotless import ordering in HudsonPrivateSecurityRealmTest Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix ATH test failures by setting a default for password complexity rule When using <f:dropdownDescriptorSelector> for passwordComplexityRule without a default attribute, the UI implicitly selects the first descriptor alphabetically (DefaultPasswordComplexityRule) for new instances. This caused JenkinsDatabaseSecurityRealmTest.login_and_logout in the Acceptance Test Harness to unexpectedly enforce password complexity rules and fail when testing with simple passwords. This commit explicitly sets the default passwordComplexityRule to NonePasswordComplexityRule via the default attribute in the Jelly UI, preserving the expected default behavior and fixing the ATH failures. * Refactor password complexity tests per review feedback - Move pure rule validation tests to core module as lightweight unit tests (no JenkinsRule needed) in DefaultPasswordComplexityRuleTest - Add assertions on exception messages to verify user-actionable content - Add tests for each individual character type requirement - Add test verifying multiple violations are reported together - Remove unused assertDoesNotThrow import from integration test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Update core/src/main/resources/hudson/security/DefaultPasswordComplexityRule/config.jelly Co-authored-by: James Nord <jtnord@users.noreply.github.com> * Rename DefaultPasswordComplexityRule to BasicPasswordComplexityRule Avoids confusion with "default" implying it is the default selection (the actual default is NonePasswordComplexityRule). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add real-time password validation on password change page - Add doCheckPassword() to Details.DescriptorImpl for AJAX validation - Change password inputs to f:password tags to enable auto-validation - Handles Protector-encrypted values gracefully Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Revert real-time password validation on change page The f:password tag renders as hidden input, breaking existing tests that expect HtmlPasswordInput. Real-time validation on the password change page requires a different approach and will be addressed in a follow-up PR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fixed test case failure * test: Address PR review by using allOf for multiple assertions * feat: Introduce PasswordComplexityRuleDescriptor base type * fix: Revert all() return type to avoid generic unchecked assignment * fix: Add @POST to doCheckPassword and fix Spotless formatting * fix: Replace deprecated getCheckUrl with toStemUrl to fix page nesting The deprecated getCheckUrl() returns a JavaScript expression that evaluates to a URL without a query string. When FormChecker.sendRequest processes a POST request with no '?' in the URL, url.indexOf('?') returns -1, causing url.substring(0, -1) to produce an empty string. This makes fetch('') request the current page, whose full HTML response gets inserted into the validation-error-area, triggering Behaviour.applySubtree on the new content and causing infinite page nesting on /user/{username}/security. Switch to the modern getCheckMethod().toStemUrl() which returns a plain URL, and add checkDependsOn="" so the frontend takes the modern code path that correctly appends the field value as a query parameter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: Add tests for doCheckPassword and null rule fallback - Test doCheckPassword returns error for weak password - Test doCheckPassword returns ok for strong password - Test doCheckPassword returns ok when no rule configured - Test doCheckPassword returns ok for empty password - Test setPasswordComplexityRule(null) falls back to NoneRule Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: Move null rule fallback test to integration test module The setNullPasswordComplexityRuleFallsBackToNone test creates a HudsonPrivateSecurityRealm instance which requires Jenkins runtime. Move it from core unit tests to integration tests where JenkinsRule provides the necessary environment. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: James Nord <jtnord@users.noreply.github.com>
Table of Contents
- About
- What to Use Jenkins for and When to Use It
- Downloads
- Getting Started (Development)
- Source
- Contributing to Jenkins
- News and Website
- Governance
- Adopters
- License
About
In a nutshell, Jenkins is the leading open-source automation server. Built with Java, it provides over 2,000 plugins to support automating virtually anything, so that humans can spend their time doing things machines cannot.
What to Use Jenkins for and When to Use It
Use Jenkins to automate your development workflow, so you can focus on work that matters most. Jenkins is commonly used for:
- Building projects
- Running tests to detect bugs and other issues as soon as they are introduced
- Static code analysis
- Deployment
Execute repetitive tasks, save time, and optimize your development process with Jenkins.
Downloads
The Jenkins project provides official distributions as WAR files, Docker images, native packages and installers for platforms including several Linux distributions and Windows. See the Downloads page for references.
For all distributions Jenkins offers two release lines:
- Weekly - Frequent releases which include all new features, improvements, and bug fixes.
- Long-Term Support (LTS) - Older release line which gets periodically updated via bug fix backports.
Latest releases:
Getting Started (Development)
For more information on setting up your development environment, contributing, and working with Jenkins internals, check the contributing guide and the Jenkins Developer Documentation.
Source
Our latest and greatest source of Jenkins can be found on GitHub. Fork us!
Contributing to Jenkins
New to open source or Jenkins? Here’s how to get started:
- Read the Contribution Guidelines
- Check our good first issues
- Join our Gitter chat for questions and help
For more information about participating in the community and contributing to the Jenkins project, see this page.
Documentation for Jenkins core maintainers is in the maintainers guidelines.
News and Website
All information about Jenkins can be found on our official website, including documentation, blog posts, plugin listings, community updates, and more.
Stay up-to-date with the latest Jenkins news, tutorials, and release notes:
Follow Jenkins on social media to stay connected with the community:
Governance
The Jenkins project is governed by an open source community. To learn more about the governance structure, project leadership, and how decisions are made, visit the Governance Page.
Adopters
Jenkins is trusted by millions of users and adopted by thousands of companies around the world — from startups to enterprises — to automate their software delivery pipelines.
Explore the Adopters Page and https://stories.jenkins.io to see:
- Companies and organizations using Jenkins
- Success stories and case studies
- How Jenkins is used in different industries
If your company uses Jenkins and you'd like to be featured, feel free to submit your story!
License
Jenkins is licensed under the MIT License.