Configuring RBAC with CasC for controllers

ScalabilityAutomation

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.

Prerequisites

The following software and plugins must be installed to use RBAC with CasC:

  • If using CloudBees Jenkins Platform 2.249.3.1 - 2.303.3.3: CloudBees CasC API Plugin, version 1.2 - 1.41

  • If using CloudBees Jenkins Platform 2.319.1.5 or later: CloudBees CasC Client plugin, version 1.44 or later

  • Configuration as Code plugin

Required setup

You can define groups and roles at the controller-level using the Configuration as Code (CasC) for Controllers rbac.yaml file.

  • Controller authorization strategy: To apply RBAC settings (rbac.yaml) to a controller using CasC, the controller’s authorization strategy must not be inherited from operations center. For more information, see Configuring the controller authorization strategy.

  • User management: Users need to be created in your CloudBees Jenkins Platform system either by an identity provider (like LDAP) or manually. The examples below assume the users exist.

  • Item management: To apply RBAC groups and/or roles to items, the CasC configuration bundle must include an items.yaml file with the defined items. For more information, refer to Creating items with CasC for controllers.

Configuring the controller authorization strategy

To apply RBAC settings (rbac.yaml) to an individual controller using Configuration as Code (CasC) for Controllers, the controller’s authorization strategy must not be inherited from the operations center.

If groups and roles are defined in the operations center or if RBAC is only used with the items.yaml file, you do not need to opt out of inheriting the operations center’s authorization strategy.

To configure the controller authorization strategy:

  1. Ensure you are signed in to the operations center as a user with the Administer permission.

  2. From the operations center dashboard, in the left pane, select Manage Jenkins.

  3. Select Configure Global Security.

  4. Scroll down to Client controller security and select Allow client controllers to opt-out.

  5. Select Save.

    For more information on how to customize the authorization strategy for an individual controller, refer to Configuring SSO in operations center.
  6. From the operations center dashboard, select the down arrow to the right of your controller’s name, and then select Configure.

    Figure 1. Controller dropdown menu
  7. Scroll down to Security Setting Enforcement and select either Enforce Authentication only or Opt out of all security enforcement.

    For more information on how to customize the authorization strategy for an individual controller, refer to Configuring options for individual controllers.

Exporting RBAC configurations

You can export role-based access control (RBAC) configurations from an existing controller. 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 items

Example bundle.yaml file

id: "bundle-1"
version: "1"
apiVersion: "1"
description: "My CloudBees Configuration as Code (CasC) bundle"
availabilityPattern: "folder1/.*"
parent: "bundle-global"
jcasc:
  - "jenkins.yaml"
plugins:
  - "plugins.yaml"
catalog:
  - "plugin-catalog.yaml"
items:
  - "items.yaml"
rbac:
  - "rbac.yaml"

Example jenkins.yaml file

jenkins:
  systemMessage: "Jenkins configured using 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)
1Mandatory to use CloudBees RBAC configured with CasC.

Example plugins.yaml file

plugins:
  # In CloudBees Assurance Program (CAP)
  - { id: "bitbucket-branch-source" }
  - { id: "branch-api" }
  - { id: "cloudbees-casc-client" }
  - { id: "cloudbees-casc-items-api" }
  - { id: "cloudbees-casc-items-commons" }
  - { id: "cloudbees-casc-items-controller" }
  - { id: "configuration-as-code" }
  - { id: "git" }
  - { id: "github-branch-source" }
  - { id: "infradna-backup" }
  - { id: "workflow-multibranch"}
  # Not in CAP (see plugin-catalog.yaml)
  - { id: "chucknorris" }
  - { id: "manage-permission" }

Example plugin-catalog.yaml file

type: "plugin-catalog"
version: "1" (1)
name: "my-plugin-catalog"
displayName: "My Plugin Catalog"
configurations:
  - description: "Extensions to CAP"
    includePlugins:
      chucknorris:
        version: 1.4
      #my-custom-plugin:
        #url: http://www.example.org/jenkins-plugins/my-custom-plugin-1.2.3.hpi
      manage-permission: (2)
        version: 1.0.1 (3)
1version (required) - must currently have the value 1, which defines the current metadata format for the plugin catalog.
2Add the manage-permission plugin to enable the Overall/Manage permission.
3Replace 1.0.1 with the most recent version.

Example items.yaml file

If a CloudBees CI GitHub Organization is used to configure a repository from a GitHub Enterprise server and you add the server to the Configure System screen, API endpoint is a required field. You must verify that the apiUri property is configured in the items.yaml file. If the GitHub server is not an enterprise server, you can optionally remove the apiUri property from the items.yaml file.
Folders with limited fields
Folders with extended fields
Freestyle job
Pipeline job
Multibranch Pipeline job
GitHub Organization
Bitbucket Team/Project
Backup
Restore
removeStrategy:
  items: "none"
  rbac: "sync"

items:
  - kind: "folder"
    name: "project-alpha"
    displayName: "Project Alpha"
    description: "Project Alpha is going to change the world!"
    groups:
      - name: "Project Alpha Developers"
        members:
          external_groups:
            - "ldap-project-alpha"
        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"
1Items can be nested within other items, enabling users to create a folder structure.
2Roles can be filtered, for example to allow only administrators to view certain projects.
removeStrategy:
  items: "none"
  rbac: "sync"

items: (1)
  - kind: "folder"
    name: "project-alpha"
    displayName: "Project Alpha"
    description: "Project Alpha is going to change the world!"
    groups:
      - name: "Project Alpha Developers"
        members:
          external_groups:
            - "ldap-project-alpha"
        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
      - 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"
1Items can be nested within other items, enabling users to create a folder structure.
2Roles 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: "pipeline"
    name: "project-beta-pipeline-job"
    displayName: "Project Beta Pipeline job"
    description: "This is Project Beta's Pipeline job!"
    definition:
      cpsScmFlowDefinition:
        scriptPath: "Jenkinsfile"
        scm:
          gitSCM:
            gitTool: "git"
            userRemoteConfigs:
              - userRemoteConfig:
                  name: "developer-b"
                  credentialsId: "credentials-id"
                  url: "git@github.com:company/project-beta.git"
            extensions:
              - checkoutOption:
                  timeout: 2
              - cloneOption:
                  reference: "/workspace/git"
                  noTags: false
                  honorRefspec: false
                  shallow: true
                  timeout: 5
            branches:
              - branchSpec:
                  name: "*/main"
removeStrategy:
  items: "none"
  rbac: "sync"

items:
  - kind: "multibranch"
      name: "project-beta-multibranch-pipeline"
      displayName: "Project Beta Multibranch Pipeline"
      description: "This is Project Beta's Multibranch Pipeline job!"
      orphanedItemStrategy:
        defaultOrphanedItemStrategy:
          pruneDeadBranches: true
          daysToKeep: 3
          numToKeep: 4
      projectFactory:
        workflowBranchProjectFactory:
          scriptPath: "Jenkinsfile"
    sourcesList:
      - branchSource:
          source:
            github:
              traits:
                - gitHubBranchDiscovery:
                    strategyId: 1
                - gitHubPullRequestDiscovery:
                    strategyId: 1
                - gitHubForkDiscovery:
                    trust:
                      gitHubTrustEveryone: {}
                    strategyId: 1
                - headWildcardFilter:
                    excludes: "feature/*"
                    includes: "*"
                - gitHubSshCheckout:
                    credentialsId: "github-ssh"
              repoOwner: "company"
              id: "scm-source-id"
              repository: "project-alpha"
              configuredByUrl: true
              repositoryUrl: "https://github.com/company/project-beta"
          strategy:
            allBranchesSame: {}
removeStrategy:
  items: "none"
  rbac: "sync"

items:
  - kind: "organizationFolder"
    name: "project-alpha-github-org"
    displayName: "Project Alpha GitHub Organization job"
    description: "This is Project Alpha's Github Organization job!"
    navigators:
      - github:
          traits:
            - checkoutOptionTrait:
                extension:
                  checkoutOption:
                    timeout: 5
            - cloneOptionTrait:
                extension:
                  cloneOption:
                    reference: main
                    noTags: false
                    honorRefspec: false
                    shallow: true
                    timeout: 6
          repoOwner: "company"
    projectFactories:
      - customMultiBranchProjectFactory:
          factory:
            customBranchProjectFactory:
              marker: ".my-marker-file"
              definition:
                cpsScmFlowDefinition:
                  scriptPath: "pipelines/default/Jenkinsfile"
                  scm:
                    gitSCM:
                      extensions:
                        - checkoutOption:
                            timeout: 4
                      gitTool: "git"
                      userRemoteConfigs:
                        - userRemoteConfig:
                            name: "admin-a"
                            credentialsId: "credentials-id"
                            url: "git@github.com:company/project-alpha.git"
                      browser:
                        githubWeb:
                          repoUrl: "git@github.com:company/project-alpha"
                      branches:
                        - branchSpec:
                            name: "*/main"
                  lightweight: false
removeStrategy:
  items: "none"
  rbac: "sync"

items:
  - kind: "organizationFolder"
    name: "project-beta-bitbucket-org"
    displayName: "Project Beta Bitbucket Organization job"
    description: "This is Project Beta's Bitbucket Organization job!"
    navigators:
      - bitbucket:
          traits:
            - bitbucketBranchDiscovery:
                strategyId: 1
            - bitbucketPullRequestDiscovery:
                strategyId: 1
            - bitbucketForkDiscovery:
                trust:
                  bitbucketTrustTeam: {}
                strategyId: 1
          repoOwner: "company"
    projectFactories:
      - workflowMultiBranchProjectFactory:
          scriptPath: "Jenkinsfile"
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
removeStrategy:
  items: "none"
  rbac: "sync"

items:
  - kind: backupAndRestore
    name: project-alpha-restore
    displayName: "Project Alpha restore"
    description: "This is Project Alpha's restore job!"
    buildersList:
      - restoreBuilder:
          ignoreConfirmationFile: false
          preserveJenkinsHome: true
          ignoreDigestCheck: true
          store:
            s3Store:
              bucketName: bucket
              sse: true
              bucketFolder: bucketFolder
              credentialsId: testCredential
              region: us-east-1
          restoreDirectory: /tmp
    label: agent-for-restore
    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:
        - "ldap-cb-admins"
  - 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
1For security reasons, SYNC is here to remove groups/roles from CloudBees Continuous Integration when they are removed from this file.
2If filterable is not included, the default value is “false”.
3Other options that could be used here include: "child" or "grandchild".
4If propagates is not included, the default value is "true".
5If grantedAt is not included, the default value is "current".