You can configure global role-based access control (RBAC) by adding the rbac.yaml
file to the configuration bundle. Additionally, the authorizationStrategy
attribute must be added to the jenkins.yaml
file.
If the operations center items.yaml file is used to create controller items, the controller RBAC configuration is defined in the operations center items.yaml file.
|
Prerequisites
The following software and plugins must be installed to use RBAC with CasC:
-
If using CloudBees CI 2.289.3.2 - 2.303.3.3: CloudBees CasC API Plugin (Deprecated) version, 1.14 - 1.41
-
If using CloudBees CI 2.319.1.5 or later: CloudBees CasC Client Plugin, version 1.44 or later
-
Configuration as Code plugin
Required setup
-
User management: You must create users in your CloudBees CI system, either using an identity provider (like LDAP) or manually creating them. The examples below assume the users exist.
-
Item management: You must include an
items.yaml
file in the controller CasC bundle to apply RBAC groups and/or roles to items.
For more information, refer to Creating items with CasC for the operations center.
Exporting RBAC configurations
You can export role-based access control (RBAC) configurations from an existing operations center instance. For more information, refer to Exporting a CasC configuration.
The exported file should be used as a starting point, as it may require modifications and adjustments to make it production-ready. |
Example CasC configuration bundle with RBAC
Example bundle.yaml file
id: "bundle-1"
version: "1"
apiVersion: "1"
description: "My CloudBees Configuration as Code (CasC) bundle"
jcasc:
- "jenkins.yaml"
jcascMergeStrategy: "errorOnConflict"
plugins:
- "plugins.yaml"
items:
- "items.yaml"
rbac:
- "rbac.yaml"
variables:
- "variables.yaml"
Example jenkins.yaml file
jenkins:
systemMessage: "Operations center configured using CloudBees CasC"
numExecutors: 0
securityRealm:
ldap:
configurations:
- displayNameAttributeName: "cn"
groupMembershipStrategy:
fromGroupSearch:
filter: "member={0}"
groupSearchBase: "ou=Groups"
inhibitInferRootDN: false
managerDN: "cn=admin,dc=example,dc=org"
managerPasswordSecret: ${LDAP_MANAGER_PASSWORD}
rootDN: "dc=example,dc=org"
server: "ldap://ldap-openldap:389"
userSearchBase: "ou=People"
disableMailAddressResolver: false
groupIdStrategy: "caseInsensitive"
userIdStrategy: "caseInsensitive"
authorizationStrategy: "cloudBeesRoleBasedAccessControl" (1)
security:
securitySettingsEnforcement:
global:
realmAndAuthorization:
canCustomMapping: false
canOverride: true
defaultMappingFactory: "restrictedEquivalentRAMF"
controllerExecutorCount:
enforce:
canOverride: false
count: 0
cloudBeesCasCServer:
visibility: true (2)
unclassified:
cascAutoControllerProvisioning:
provisionControllerOnCreation: true (3)
fireAndForget: true (4)
initialDelay: 15 (5)
timeout: 600 (6)
duration: 60 (7)
location:
url: https://operations-center:8888/ (8)
bundleStorageService: (9)
activated: true
activeBundle:
name: "local-folder"
retriever:
SCM:
scmSource:
git:
id: "acf88621-05a0-4d50-9166-d7767868dc43"
remote: "https://github.com/my-company/repo.git"
traits:
- "gitBranchDiscovery"
pollingPeriod: 0
purgeOnDeactivation: false
1 | Required to use CloudBees RBAC configured using CasC. |
2 | Optional if using the items.yaml file to create a controller item. When visibility is set to true , all CasC bundles that do not have an availability pattern defined can be used by any controller. This option provides more flexibility, but is less secure. |
3 | When provisionControllerOnCreation is set to true , all managed controller items are provisioned automatically after they are created using CasC. |
4 | When fireAndForget is set to true , the automatic provisioning process starts immediately, and does not wait for the controller to be connected. |
5 | The amount of time, in seconds, to wait before starting the automatic provisioning process. |
6 | The amount of time, in seconds, to complete the automatic provisioning process. If fireAndForget is set to false , this timeout may prevent queued provisioning requests from being blocked. |
7 | The provisioning duration, in seconds. After the initial delay, controllers are provisioned at random in batches of 20 controllers, for this time period. Increase this value to increase the amount of time between controller provisioning requests. If provisioning more than 20 controllers, the provisioning process will exceed the specified duration. |
8 | Required to create client controller items. The url is the operations center URL. |
9 | Required if using a local folder on the operations center server or an SCM tool as the Configuration as Code bundle location. |
Example plugins.yaml file
plugins:
# In CAP
- id: "cloudbees-casc-client"
- id: "cloudbees-casc-items-api"
- id: "cloudbees-casc-items-commons"
- id: "cloudbees-casc-items-server"
- id: "configuration-as-code"
- id: "operations-center-rbac"
Example items.yaml file
|
removeStrategy:
items: "none"
rbac: "sync"
items:
- kind: "folder"
name: project-${team_group}
displayName: "Project Alpha"
description: "Project Alpha is going to change the world!"
properties:
- folderCredentialsProperty:
folderCredentials:
- credentials:
- usernamePassword:
password: ${secret_location}
scope: GLOBAL
description: description
id: test-id
usernameSecret: false
username: test-user
domain: {}
groups:
- name: "Project Alpha Developers"
members:
external_groups:
- ldap-project-${team_group}
roles:
- name: "developer"
items: (1)
- kind: "folder"
name: "project-alpha-tests"
displayName: "Project Alpha Tests"
items:
- kind: "folder"
name: "test-1"
- kind: "folder"
name: "test-2"
- kind: "folder"
name: "project-beta"
displayName: "Project Beta"
description: "Secret project! Only Admins can see this!"
filteredRoles: (2)
- "developer"
- "browser"
1 | Items can be nested within other items, enabling users to create a folder structure. |
2 | Roles can be filtered, for example to allow only administrators to view certain projects. |
removeStrategy:
items: "none"
rbac: "sync"
items: (1)
- kind: "folder"
name: project-${team_group}
displayName: "Project Alpha"
description: "Project Alpha is going to change the world!"
groups:
- name: "Project Alpha Developers"
members:
external_groups:
- ldap-project-${team_group}
roles:
- name: "developer"
items:
- kind: "folder"
name: "project-alpha-tests"
displayName: "Project Alpha Tests"
items:
- kind: "folder"
name: "test-1"
- kind: "folder"
name: "test-2"
properties:
- envVars:
vars:
FOO: "BAR"
BAR: "BAZ"
- folderLibraries:
libraries:
- libraryConfiguration:
implicit: false
allowVersionOverride: true
retriever:
modernSCM:
scm:
github:
traits:
- gitHubBranchDiscovery:
strategyId: 1
- gitHubPullRequestDiscovery:
strategyId: 1
- gitHubForkDiscovery:
trust:
gitHubTrustEveryone: {}
strategyId: 1
repoOwner: "company"
id: "library-id"
repository: "project-alpha"
configuredByUrl: true
repositoryUrl: "https://github.com/company/project-alpha"
name: "my-library"
includeInChangesets: true
- folderCredentialsProperty:
folderCredentials:
- credentials:
- usernamePassword:
password: ${secret_location}
scope: GLOBAL
description: description
id: test-id
usernameSecret: false
username: test-user
domain: {}
- itemRestrictions:
allowedTypes:
- "org.jenkinsci.plugins.workflow.job.WorkflowJob"
- "hudson.matrix.MatrixProject"
- "hudson.model.FreeStyleProject"
- "com.cloudbees.hudson.plugins.modeling.impl.jobTemplate.JobTemplate"
- "com.cloudbees.hudson.plugins.folder.Folder"
- "com.cloudbees.hudson.plugins.modeling.impl.builder.BuilderTemplate"
- "com.cloudbees.hudson.plugins.modeling.impl.auxiliary.AuxModel"
- "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject"
- "com.cloudbees.hudson.plugins.modeling.impl.publisher.PublisherTemplate"
- "com.cloudbees.hudson.plugins.modeling.impl.folder.FolderTemplate"
- "com.infradna.hudson.plugins.backup.BackupProject"
filter: true
items:
- kind: "freeStyle"
name: "project-alpha-freestyle"
displayName: "Freestyle job in the Project Alpha folder"
- kind: "folder"
name: "project-beta"
displayName: "Project Beta"
description: "Secret project! Only Admins can see this!"
filteredRoles: (2)
- "developer"
- "browser"
1 | Items can be nested within other items, enabling users to create a folder structure. |
2 | Roles can be filtered, for example to allow only administrators to view certain projects. |
removeStrategy:
items: "none"
rbac: "sync"
items:
- kind: "freeStyle"
name: "project-alpha-freestyle"
displayName: "Project Alpha Freestyle"
description: "This is Project Alpha's Freestyle job!"
disabled: false
scm:
gitSCM:
extensions:
- checkoutOption:
timeout: 4
gitTool: git
userRemoteConfigs:
- userRemoteConfig:
name: "developer-a"
credentialsId: "credentials-id"
url: "git@github.com:company/project-alpha.git"
browser:
githubWeb:
repoUrl: "https://github.com/company/project-alpha"
doGenerateSubmoduleConfigurations: false
branches:
- branchSpec:
name: "*/main"
buildDiscarder:
logRotator:
artifactDaysToKeep: 3
daysToKeep: 1
numToKeep: 2
artifactNumToKeep: 4
scmCheckoutStrategy:
standard: { }
builders:
- shell:
command: "pwd"
removeStrategy:
items: "none"
rbac: "sync"
items:
- kind: clusterOpProject
name: "project-alpha-cluster-operations"
displayName: "Project Alpha - Cluster operations"
description: "These are Project Alpha's cluster operations!"
disabled: false
concurrentBuild: true
operations:
- masterClusterOperation:
failureMode: IMMEDIATELY
clusterOpSteps:
- backupClusterOpStep:
subjects:
- buildRecordSubject: {}
- jobConfigurationSubject: {}
format:
zipFormat: {}
retentionPolicy:
exponentialDecayRetentionPolicy: {}
safeDelaySeconds: 10
store:
s3Store:
bucketName: ' mybucket'
sse: true
bucketFolder: somefolder
credentialsId: 'my-aws-credentials-id'
region: us-east-1
timeoutSeconds: 0
itemSource:
jenkinsRootItemSource: {}
filters:
- isMasterOnlineFilter: {}
inParallel: 0
noRetries: 0
removeStrategy:
items: "none"
rbac: "sync"
items:
- kind: managedController
displayName: "managed-controller-alpha"
name: "managed-controller-alpha"
description: "This is Project Alpha's managed controller!"
groups:
- name: "Project Alpha Developers"
members:
users:
- developer-1
roles:
- name: developer
properties:
- configurationAsCode:
bundle: bundle-1
- healthReporting:
enabled: false
- owner:
delay: 5
owners: ''
- envelopeExtension:
allowExceptions: false
- sharedConfigurationOptOut:
optOut: false
- licensing:
strategy:
perUserLicensingStrategy: {}
configuration:
kubernetes:
allowExternalAgents: false
terminationGracePeriodSeconds: 1200
#image: cloudbees/mc-foo-image # uncomment to use a non-default image
memory: 3072 (1)
fsGroup: '1000'
cpus: 1.0
readinessTimeoutSeconds: 5
livenessInitialDelaySeconds: 300
readinessInitialDelaySeconds: 30
clusterEndpointId: default
disk: 50
readinessFailureThreshold: 100
livenessTimeoutSeconds: 10
domain: managed-controller-alpha
livenessPeriodSeconds: 10
javaOptions: -DfooSystemProperty="foo" -Dbar="bar"
yaml: |-
---
kind: StatefulSet
metadata:
labels:
my-label: my-value
1 | Some settings, such as controller memory, require the controller to be re-provisioned for the setting to take effect. |
removeStrategy:
items: "none"
rbac: "sync"
items:
- kind: clientController
displayName: "client-controller-beta"
name: "client-controller-beta"
description: "This is Project Beta's client controller!"
groups:
- name: "Project Beta Developers"
members:
users:
- developer-1
roles:
- name: developer
properties:
- configurationAsCode:
bundle: bundle-2
- healthReporting:
enabled: false
- owner:
delay: 5
owners: ''
- envelopeExtension:
allowExceptions: false
- sharedConfigurationOptOut:
optOut: false
- licensing:
strategy:
perUserLicensingStrategy: {}
- webSocket:
enabled: true
removeStrategy:
items: "none"
rbac: "sync"
items:
- kind: "sharedAgent"
displayName: "Shared Agent for this cluster"
name: "shared-agent-1"
description: "Shared Agent for this cluster"
remoteFS: "/tmp/remote"
properties:
- sharedAgent:
customizers:
- envVars:
value:
SKIP_RELEASE: "TRUE"
JENKINS_VERSION: "2.303"
- toolLocation:
value:
- name: "git"
type: "git"
home: "/usr/local/git"
- name: "maven3"
type: "mvn"
home: "/usr/local/mvn"
labels: "ubuntu"
launcher:
inboundAgent:
webSocket: true
workDirSettings:
remotingWorkDirSettings:
internalDir: "/path/to/directory"
disabled: false
failIfWorkDirIsMissing: true
workDirPath: "/path/to/directory"
agentStartupOptions: "-noCertificateCheck"
vmargs: "-Xms2G -Xmx2G"
tunnel: "192.1.1.45:22"
mode: EXCLUSIVE
numExecutors: 10
retentionStrategy:
sharedNodeRetentionStrategy: {}
removeStrategy:
items: "none"
rbac: "sync"
items:
- kind: "sharedCloud"
displayName: "Shared Cloud for this cluster"
name: "shared-cloud-1"
description: "Shared Cloud for this cluster"
properties:
- sharedCloud:
customizers:
- envVars:
value:
SKIP_RELEASE: "TRUE"
JENKINS_VERSION: "2.303"
- toolLocation:
value:
- name: "git"
type: "git"
home: "/usr/local/git"
- name: "maven3"
type: "mvn"
home: "/usr/local/mvn"
cloud:
inboundAgents:
mode: EXCLUSIVE
numExecutors: 10
remoteFS: "/path/to/directory"
labels: "ubuntu"
launcher:
inboundAgent:
webSocket: true
workDirSettings:
remotingWorkDirSettings:
internalDir: "/path/to/directory"
disabled: false
failIfWorkDirIsMissing: true
workDirPath: "/path/to/directory"
agentStartupOptions: "-noCertificateCheck"
vmargs: "-Xms2G -Xmx2G"
tunnel: "192.1.1.45:22"
removeStrategy:
items: "none"
rbac: "sync"
items:
- kind: backupAndRestore
name: project-alpha-backup
displayName: "Project Alpha backup"
description: "This is Project Alpha's backup job!"
buildersList:
- backupBuilder:
subjects:
- buildRecordSubject:
excludes: foo
- jobConfigurationSubject:
excludes: bar
- systemConfigurationSubject:
excludes: baz
omitMasterKey: true
format:
zipFormat: {}
exclusive: false
store:
s3Store:
bucketName: bucket
sse: true
bucketFolder: bucketFolder
credentialsId: testCredential
region: us-east-1
retentionPolicy:
exponentialDecayRetentionPolicy: {}
safeDelaySeconds: 42
label: agent-for-backup
triggers:
- cron:
spec: 0 0 * * *
buildDiscarder:
logRotator:
numToKeep: 5
Example rbac.yaml file
removeStrategy:
rbac: "SYNC" (1)
roles:
- name: administer
permissions:
- hudson.model.Hudson.Administer
- name: developer
permissions:
- hudson.model.Hudson.Read
- hudson.model.Item.Read
- hudson.model.Item.Create
- hudson.model.Item.Configure
filterable: "true" (2)
- name: browser
permissions:
- hudson.model.Hudson.Read
- hudson.model.Item.Read
filterable: "true"
- name: authenticated
filterable: "true"
permissions:
- hudson.model.Hudson.Read
groups:
- name: Administrators
roles:
- name: administer
grantedAt: current (3)
members:
users:
- admin
external_groups:
- ${external_admin_group}
- name: Developers
roles: (4) (5)
- name: developer
members:
users:
- developer
internal_groups:
- "some-other-group"
external_groups:
- "ldap-cb-developers"
- name: Browsers
roles:
- name: browser
members:
users:
- read
1 | For security reasons, SYNC is here to remove groups/roles from CloudBees Continuous Integration when they are removed from this file. |
2 | If filterable is not included, the default value is “false”. |
3 | Other options that could be used here include: "child" or "grandchild". |
4 | If propagates is not included, the default value is "true". |
5 | If grantedAt is not included, the default value is "current". |