Jenkins SAML SSO
CloudOps for Kubernetes supports SAML 2.0 Single Sign-On (SSO) for Jenkins. When enabled, users authenticate through your organization's Identity Provider (IdP) instead of built-in Jenkins local accounts. Common IdPs include Okta, Jumpcloud, Azure AD, and Keycloak.
note
SAML SSO support is available in CloudOps for Kubernetes release 3.7 and higher.
Quick paths
| If you want to… | Start here |
|---|---|
| Decide whether SAML SSO is right for your team | Should you enable SAML SSO? |
| See everything you need before you start | Information checklist |
| Prepare a request for your IdP administrator | For your IdP administrator |
| Enable SAML in CloudOps for Kubernetes | Enable SAML in CloudOps for Kubernetes |
| Confirm the integration works | Verify |
| Look up variables, examples, or recovery steps | Reference |
Should you enable SAML SSO?
SAML SSO is a good fit when your organization already uses a SAML 2.0 IdP and you want Jenkins access governed by that IdP (central login, group-based roles, and offboarding through the IdP) instead of the built-in Jenkins local accounts.
Before you proceed, understand these constraints:
- Local Jenkins accounts are disabled. Enabling SAML SSO disables the built-in
admin,poweruser,developer, andviewerusers. You must be able to authenticate through your IdP before applying the change. - IdP groups drive authorization. Each user must belong to at least one IdP group whose name matches a Jenkins role group (see Required IdP groups). Users who authenticate but are not in any configured group are denied access.
- You need IdP administrator involvement. Someone with IdP admin access must create the Jenkins SAML application, configure group membership in assertions, and map user attributes.
- Cluster reconfiguration is required. Enabling SAML updates
docker-compose.override.ymland applies changes through Updating Cluster Configuration. Jenkins restarts during the process. - Plan an exit strategy. Record the local
adminpassword before enabling SAML, and keep a copy of local-auth settings so you can revert to local accounts if the IdP is unreachable.
Logout behaviour (decision point). By default, logging out of Jenkins clears only the Jenkins session; the user may remain signed into the IdP and be silently re-authenticated on the next visit. You can optionally set TF_VAR_saml_logout_url so logout also redirects to the IdP's session-termination URL. See Logout behaviour for implications when other applications share the same IdP SSO session.
If these constraints are acceptable and you have a SAML 2.0 IdP, continue with the information checklist.
Information checklist
Use this checklist to gather what you need before and during setup. Items marked (from IdP) are provided by your IdP administrator after the Jenkins SAML application is created.
| Item | Where it comes from | Used for |
|---|---|---|
| Jenkins hostname (full URL your team uses) | Your cluster | IdP SP configuration; optional TF_VAR_saml_sp_entity_id override |
| IdP administrator access (or a contact) | Your organization | Creating the SAML application and mappings |
| IdP metadata URL (from IdP) | IdP admin after app creation | TF_VAR_saml_idp_metadata_url in docker-compose.override.yml |
| Group membership plan | Your team + IdP admin | Users assigned to required IdP groups |
| Attribute naming plan | Your team + IdP admin | Default names username, displayName, email, groups — or TF_VAR_saml_*_attribute overrides |
Local admin password | TF_VAR_jenkins_admin_password in docker-compose.override.yml | Recovery if you revert to local accounts |
| Optional IdP logout URL (from IdP) | IdP admin | TF_VAR_saml_logout_url for combined Jenkins + IdP logout |
| Custom authorization file (if needed) | Your fork of C4K | Copy of saml-role-based-authorization.yaml with custom group names |
docker-compose.override.yml access | Your C4K deployment | All TF_VAR_* SAML settings |
| Reconfigure procedure access | Your operations process | Updating Cluster Configuration |
Prerequisites
- CloudOps for Kubernetes
3.7or higher. - A SAML 2.0-compliant IdP (Okta, Jumpcloud, Azure AD, Keycloak, or equivalent).
- IdP groups and attribute mappings configured as described in For your IdP administrator.
Before you change Jenkins: record the local admin password from TF_VAR_jenkins_admin_password in your docker-compose.override.yml. When SAML is enabled, local accounts (including admin) are inaccessible until you revert.
For your IdP administrator
Provide this section (or the tables below) to your IdP administrator. It consolidates the Service Provider (SP) settings, group requirements, and attribute mappings Jenkins expects.
Service Provider (SP) settings
| Field | Value |
|---|---|
| Entity ID / Audience URI | https://<your_jenkins_hostname>/securityRealm/metadata |
| ACS URL / Single Sign-On URL | https://<your_jenkins_hostname>/securityRealm/finishLogin |
| ACS Binding | HTTP POST |
| Name ID Format | Username or Unspecified (do not use email) |
Replace <your_jenkins_hostname> with the Jenkins URL your team uses to access Jenkins.
After the IdP application is created, your IdP administrator should give you the IdP metadata URL for use in TF_VAR_saml_idp_metadata_url.
Required IdP groups
Jenkins uses a groups attribute in the SAML assertion to assign roles. Group names must exactly match the names Jenkins expects (case-sensitive). Defaults are defined in bootstrap/terraform/config/jenkins-authorization-config/saml-role-based-authorization.yaml:
| Group name in IdP | Jenkins role | Permissions |
|---|---|---|
jenkins-administrators | Administrators | Full access including Jenkins configuration |
jenkins-powerusers | PowerUsers | View, run, and configure all jobs; read all build output |
jenkins-developers | Developers | View and run all jobs; read all build output |
jenkins-viewers | Viewers | View all jobs; read all build output |
Each user must belong to at least one of these groups. Users who authenticate successfully but are not a member of any configured group are denied access to Jenkins.
note
If your IdP uses a different SAML attribute name for group membership (for example, memberOf), set TF_VAR_saml_groups_attribute in docker-compose.override.yml to match. See SAML variable reference.
note
You can customize group names and permissions by copying saml-role-based-authorization.yaml, editing the copy, and setting TF_VAR_jenkins_authorization_configuration_file to your file name in docker-compose.override.yml. If you customize group names, give your IdP administrator the updated group names from your file.
Required SAML assertion attributes
Map the following attributes into the SAML assertion:
| Attribute name | Description |
|---|---|
username | The Jenkins login name |
displayName | The display name shown in the Jenkins UI |
email | The user's email address |
groups | Group membership (drives role assignment) |
If your IdP cannot use these exact attribute names, ask your IdP administrator to rename them to match the defaults. If that is not possible, set the matching TF_VAR_saml_*_attribute variables in docker-compose.override.yml. See SAML variable reference.
Enable SAML in CloudOps for Kubernetes
Complete For your IdP administrator and obtain the IdP metadata URL before applying these changes.
Add or modify the SAML-related variables in your docker-compose.override.yml.
Minimal configuration:
TF_VAR_jenkins_security_realm: "saml"
TF_VAR_saml_idp_metadata_url: "<IdP metadata URL>"
TF_VAR_jenkins_authorization_configuration_file: "saml-role-based-authorization.yaml" # Or your custom file
TF_VAR_jenkins_overwrite_config: "true"
TF_VAR_jenkins_overwrite_plugins: "true" # Required on first enable for existing clusters (installs the saml plugin)
Optional — combined Jenkins and IdP logout:
TF_VAR_saml_logout_url: "<IdP logout URL>"
See Logout behaviour for what this does and does not do.
Apply the change by following Updating Cluster Configuration. Jenkins will restart.
After a successful restart, set TF_VAR_jenkins_overwrite_config and TF_VAR_jenkins_overwrite_plugins back to "false" (or remove them) to prevent unintentional Jenkins changes on subsequent bootstrap runs.
Verify
Open a private browser window and navigate to your Jenkins URL. You should be redirected to your IdP's login page. Log in with an IdP user who is a member of one of the required IdP groups and confirm the correct Jenkins role is assigned.
Reference
SAML variable reference
The following docker-compose.override.yml variables control SAML SSO:
| Variable | Default | Description |
|---|---|---|
TF_VAR_jenkins_security_realm | local | Set to saml to enable SAML SSO. Revert to local to use built-in Jenkins accounts. |
TF_VAR_saml_idp_metadata_url | (none) | Required when SAML is enabled. URL of the IdP SAML metadata document. |
TF_VAR_saml_logout_url | (none) | Optional. IdP session-termination URL. When set, clicking logout in Jenkins also terminates the IdP session. |
TF_VAR_saml_sp_entity_id | (auto) | Optional. Override for the SAML SP entity ID. When not set, defaults to https://<your_jenkins_hostname>/securityRealm/metadata. |
TF_VAR_saml_username_attribute | username | SAML assertion attribute for the Jenkins username. |
TF_VAR_saml_display_name_attribute | displayName | SAML assertion attribute for the user's display name. |
TF_VAR_saml_email_attribute | email | SAML assertion attribute for the user's email address. |
TF_VAR_saml_groups_attribute | groups | SAML assertion attribute for group memberships. |
TF_VAR_saml_maximum_authentication_lifetime | 86400 | Maximum seconds a SAML authentication is valid (default: 24 hours). |
TF_VAR_saml_idp_metadata_refresh_period | 1440 | How often Jenkins re-fetches IdP metadata, in minutes. Set to 0 to disable periodic refresh. |
Logout behaviour
If you set TF_VAR_saml_logout_url, a user logging out of Jenkins is also redirected to the IdP's logout URL, terminating the IdP SSO session.
Note that this is a browser redirect; Jenkins does not send a SAML logout request to the IdP. Practical implications:
- Clicking logout in Jenkins terminates both the Jenkins session and the IdP session (when
TF_VAR_saml_logout_urlis set). - Other applications that share the same IdP SSO session (if any) are not notified — their sessions continue independently.
- If
TF_VAR_saml_logout_urlis not set, Jenkins clears only its local session. The user remains logged into the IdP and will be silently re-authenticated on their next visit to Jenkins without seeing a login prompt.
For most CloudOps for Kubernetes deployments, Jenkins is the only application using the IdP SSO session, so the redirect approach provides effective logout behaviour.
Keycloak configuration example
High-level example of configuring Keycloak as a SAML IdP for Jenkins. The steps illustrate concepts that apply to any IdP.
note
This example is provided for reference only. CloudOps for Kubernetes does not ship or manage a Keycloak instance for production use.
In Keycloak, create a realm for your CloudOps for Kubernetes cluster (for example,
ep_non_prod).Create a SAML client within that realm:
- Client ID:
https://<your_jenkins_hostname>/securityRealm/metadata - Valid Redirect URIs:
https://<your_jenkins_hostname>/securityRealm/finishLogin - In the client settings, set the ACS URL to
https://<your_jenkins_hostname>/securityRealm/finishLogin(POST binding)
- Client ID:
Add protocol mappers to the client for each required attribute:
- Map the user's username to attribute
username - Map the user's first name (or full name) to attribute
displayName - Map the user's email to attribute
email - Map group membership to attribute
groupsusing a Group Membership mapper
- Map the user's username to attribute
Create groups in the realm with the exact names listed in Required IdP groups, and assign users to the appropriate groups.
Values for
docker-compose.override.yml:TF_VAR_saml_idp_metadata_url: "https://<keycloak-host>/realms/<realm>/protocol/saml/descriptor" TF_VAR_saml_logout_url: "https://<keycloak-host>/realms/<realm>/protocol/openid-connect/logout"
IdP certificate rotation
When your IdP rotates its SAML signing certificate, Jenkins must re-fetch the IdP metadata to obtain the new public key. Until it does, SAML logins will fail.
By default, Jenkins re-fetches the IdP metadata every 24 hours. To force an immediate update after a certificate rotation, restart the Jenkins pod:
kubectl rollout restart statefulset/jenkins -n default
To change the automatic refresh interval, set TF_VAR_saml_idp_metadata_refresh_period in your docker-compose.override.yml. See SAML variable reference.
Reverting to local accounts
To disable SAML SSO and restore built-in local Jenkins accounts, set the following in docker-compose.override.yml:
TF_VAR_jenkins_security_realm: "local"
TF_VAR_jenkins_authorization_configuration_file: "default-role-based-authorization.yaml" # Or your preferred file.
TF_VAR_jenkins_overwrite_config: "true"
TF_VAR_jenkins_overwrite_plugins: "true" # Recommended when switching back
Apply the change by following Updating Cluster Configuration. Jenkins will restart.
After a successful revert, set TF_VAR_jenkins_overwrite_plugins back to "false" (or remove it). Log in with the local admin account using the password you recorded before enabling SAML.
important
Keep a copy of your docker-compose.override.yml with the local-auth settings in a safe place so you can recover quickly if your IdP becomes unreachable.
Troubleshooting
Login fails immediately after entering IdP credentials
The most common cause is a mismatch in the groups attribute. Check that:
- The attribute name your IdP sends matches
TF_VAR_saml_groups_attribute(default:groups). - The group name values exactly match the required strings (they are case-sensitive).
Check the Jenkins pod logs for SAML assertion errors: kubectl logs -n default jenkins-0.
"A problem occurred while processing the request" after IdP certificate rotation
Jenkins is still using the old signing certificate from its cached metadata. Restart the Jenkins pod to force an immediate metadata refresh:
kubectl rollout restart statefulset/jenkins -n default
Users are logged in with the wrong role
Verify that IdP group names exactly match the strings in Required IdP groups. A common mistake is using a different case or adding spaces.
Jenkins is unreachable because the IdP is down
Revert to local accounts by following Reverting to local accounts.