Search code examples
jenkinsjenkins-pipelinejenkins-pluginsdevops

Jenkins role strategy plugin and restrict user to build if not in proper group -- Jenkins file


We have two environments, qa and dev, and that is configured as parameters in Jenkinsfile. Plugin Role-based Authorization Strategy is enabled, and there are two groups of users, qa and dev (same as environment). The problem here is that qa users can start to build jobs with dev environment. Is there any way that we restrict this behavior? Here is a simple example:

pipeline {
    agent any 
     
    choice(name: 'environment', choices: ['dev', 'qa']

    stages {    
        stage('test') { 
            script {
              if (params.environment == 'dev' && env.BUILD_USER_ID not in env.BUILD_USER_GROUPS) {echo "User ${env.BUILD_USER_ID} can not start build on DEV enviroment"}
              else if (params.environment == 'qa' && env.BUILD_USER_ID not in env.BUILD_USER_GROUPS) {echo "User ${env.BUILD_USER_ID} can not start build on QA enviroment"}
              else {echo "You can run job, You are in proper group for this enviroment"}
        } 
      }                     
    }
  }

An example is not real, and maybe not working, but I hope that can be understood what I want to accomplish.

P.S. Documentation for this is not so good, and also can't find much more examples on web.


Solution

  • Instead of blocking (or failing) the execution after it started, you can use a different approach and prevent an unauthorized user to even start the build with irrelevant parameters (dev environment in this case).
    To do so you can use the Extended Choice Parameter plugin, it enables you to create a select list value (multi or single select) based on the return value of a groovy script.
    Then you can use the following script:

    def buildUserGroup = ["group1","group 2","group3"]
    def environments = ['qa']  // This default value will be available to everyone
    
    // All the groups that the current logged in user is a member of
    def currentUserGroups = hudson.model.User.current().getAuthorities() 
    if (currentUserGroups.any{ buildUserGroup.contains(it) }) {
        environments.add("dev")  // Add relevant environments according to groups
    }
    return environments
    

    This way you can define the logic that will add environments according to group membership and adjusted it according to your needs. The user that builds the job wont even see the environments that he is not allowed to build and you will get the restriction you need.
    In a Pipeline Job using your requirements the configuration can be simplified and will look like:

     pipeline {
        agent any
        parameters {
            extendedChoice(name: 'environment', type: 'PT_SINGLE_SELECT', description: 'Environment type', visibleItemCount: 10,
                    groovyScript:"return hudson.model.User.current().getAuthorities().contains('dev') ? ['dev','qa'] : ['qa']")
        }
        stages {
            stage('test') {
                ....
            }
        }
    }
    

    Update: If you are using the Role-based Authorization Strategy and want to use the above solution with roles instead of groups you can use the following code (based on this script in your parameter:

    def environments = ['qa']  // This default value will be available to everyone
    
    def userID = hudson.model.User.current().id  // The current user it
    def authStrategy = jenkins.model.Jenkins.instance.getAuthorizationStrategy()
    def permissions = authStrategy.roleMaps.inject([:]){map, it -> map + it.value.grantedRoles}
    
    // Validate current user is in the 'dev' role
    if (permissions.any{it.key.name == 'dev' && it.value.contains(userID)}) {
        environments.add("dev")  // Add relevant environments according to groups
    }
    return environments