Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-43726

Allow importing local classes when the build is running as an administrator

      I have Authorize Plugin installed and I'm running the build as an admin user (without that it would just fail with ERROR: script not yet approved for use).

      I'm trying to run a job-dsl step with files checked out from SCM.

      It fails when trying to import another class defined in the same directory:

      /var/lib/jenkins/jobs/CFS Pipeline Seed/workspace/avalonPipeline.groovy: 3: unable to resolve class JobBuilder
       @ line 3, column 1.
         import JobBuilder
         ^

      There is a JobBuilder.groovy file in the workspace.

      I was able to run the job only by disabling "Enable script security for Job DSL scripts" option in the global security settings.

          [JENKINS-43726] Allow importing local classes when the build is running as an administrator

          Mike Kobit added a comment - - edited

          We are affected by both of those issues:

          1. The whitelist problem
          2. The import problem

          The whitelist problem is fairly annoying because we run Job DSL from the Bitbucket Branch Source Plugin and this means every changes we make is going to require a whitelist change. Any thoughts on how to deal with this?

          Mike Kobit added a comment - - edited We are affected by both of those issues: The whitelist problem The import problem The whitelist problem is fairly annoying because we run Job DSL from the Bitbucket Branch Source Plugin and this means every changes we make is going to require a whitelist change. Any thoughts on how to deal with this?

          mkobit I think you are just missing the Authorize Project plugin settings, as described in https://github.com/jenkinsci/job-dsl-plugin/wiki/Script-Security

          My problem is that importing classes doesn't work even if I run the job as an admin user (ERROR: script not yet approved for use is not happening then)

          Jakub Bochenski added a comment - mkobit I think you are just missing the Authorize Project plugin settings, as described in https://github.com/jenkinsci/job-dsl-plugin/wiki/Script-Security My problem is that importing classes doesn't work even if I run the job as an admin user ( ERROR: script not yet approved for use is not happening then)

          Mike Kobit added a comment - - edited

          Thanks jbochenski, I'll have to dive into this today to see if there is a workaround for us.

          I don't believe that it will solve our issues now, but maybe it will help.

          Our "seed job" is automated and ran in a Jenkinsfile, and that will update the jobs on many other folders.

          node {
            checkout scm
            timestamps {
              stage('Validate Jobs') {
                sh './gradlew build'
              }
              if (env.BRANCH_NAME == 'master') {
                stage('Process Job DSLs') {
                  jobDsl(
                    additionalClasspath: 'build/classes/main',
                    failOnMissingPlugin: true,
                    removedJobAction: 'DISABLE',
                    removedViewAction: 'DELETE',
                    targets: 'jobs/**/*.groovy'
                  )
                }
              }
            }
          }
          

          Where one of our job files might look like

          final rootFolder = folder('bitbucket_projects') {
            description('A 1:1 mapping of projects in Bitbucket to Jenkins')
            displayName('Bitbucket Projects')
          }
          
          organizationFolder("${rootFolder.name}/proj") {
            description('Bitbucket Branch Source for the PROJ project on Bitbucket Server')
            organizations {
              bitbucketSCMNavigator {
                autoRegisterHooks(true)
                bitbucketServerUrl('https://bitbucket.internal-corp.com')
                checkoutCredentialsId('checkout-creds-id')
                credentialsId('scan-creds-id')
                pattern('.*')
                repoOwner('PROJ')
                sshPort(7999)
              }
            }
            // Other configuration for organization folder
          }
          
          // Other folders
          
          

          Users of this Jenkins instance will add and self-service their jobs into this job DSL definition for which our team would approve, and then the changes would automatically be applied.

          Now, we can't do this in an entirely automated fashion because of these new additions of script security.

          It seems like we have a couple possible options:

          • Use the Authorize Project Plugin and hope we can configure it for organization folders
          • Create an "seed job" and remove our automated pipeline job that needs to be manually triggered to run the job DSL
          • Create a job that automatically runs using the Authorize Project Plugin

          These seem entirely undesirable compared to our previous nearly full autonomous solution. We generally avoid installing additional plugins because they very frequently break and cause problems. Another reason is automating the configuration of these jobs' Authorization is not supported with the Job DSL (see JENKINS-29630) which makes it even more difficult to automate all of this stuff.

          Mike Kobit added a comment - - edited Thanks jbochenski , I'll have to dive into this today to see if there is a workaround for us. I don't believe that it will solve our issues now, but maybe it will help. Our "seed job" is automated and ran in a Jenkinsfile , and that will update the jobs on many other folders. node { checkout scm timestamps { stage('Validate Jobs') { sh './gradlew build' } if (env.BRANCH_NAME == 'master') { stage('Process Job DSLs') { jobDsl( additionalClasspath: 'build/classes/main', failOnMissingPlugin: true, removedJobAction: 'DISABLE', removedViewAction: 'DELETE', targets: 'jobs/**/*.groovy' ) } } } } Where one of our job files might look like final rootFolder = folder('bitbucket_projects') { description('A 1:1 mapping of projects in Bitbucket to Jenkins') displayName('Bitbucket Projects') } organizationFolder("${rootFolder.name}/proj") { description('Bitbucket Branch Source for the PROJ project on Bitbucket Server') organizations { bitbucketSCMNavigator { autoRegisterHooks(true) bitbucketServerUrl('https://bitbucket.internal-corp.com') checkoutCredentialsId('checkout-creds-id') credentialsId('scan-creds-id') pattern('.*') repoOwner('PROJ') sshPort(7999) } } // Other configuration for organization folder } // Other folders Users of this Jenkins instance will add and self-service their jobs into this job DSL definition for which our team would approve, and then the changes would automatically be applied. Now, we can't do this in an entirely automated fashion because of these new additions of script security. It seems like we have a couple possible options: Use the Authorize Project Plugin and hope we can configure it for organization folders Create an "seed job" and remove our automated pipeline job that needs to be manually triggered to run the job DSL Create a job that automatically runs using the Authorize Project Plugin These seem entirely undesirable compared to our previous nearly full autonomous solution. We generally avoid installing additional plugins because they very frequently break and cause problems. Another reason is automating the configuration of these jobs' Authorization is not supported with the Job DSL (see JENKINS-29630 ) which makes it even more difficult to automate all of this stuff.

          Mike Kobit added a comment -

          It doesn't seem like the jobDsl step now in Jenkins Pipeline jobs with or without sandbox, presumably because the pipeline is already running in a sandbox.

          Mike Kobit added a comment - It doesn't seem like the jobDsl step now in Jenkins Pipeline jobs with or without sandbox, presumably because the pipeline is already running in a sandbox.

          This is not a bug, this is a consequence of fixing the security vulnerabilities as mentioned in https://jenkins.io/security/advisory/2017-04-10/.

          Imported code is neither executed in the script security sandbox nor checked for approval by an administrator. Anyone with permission to modify the code will effectively gain administrative privileges in Jenkins. To fix that problem, the classpath is not extended by the "Additional classpath" or the script directory. And thus importing code is not possible when script security for Job DSL is enabled.

          As mentioned in the Migration docs, there is a switch to restore the old behavior. But be careful with that.

          Please move the discussion to the mailing list because this is interesting for a wider audience. I'm sure we can come up with a way to allow imports, but in a secure way.

          Daniel Spilker added a comment - This is not a bug, this is a consequence of fixing the security vulnerabilities as mentioned in https://jenkins.io/security/advisory/2017-04-10/ . Imported code is neither executed in the script security sandbox nor checked for approval by an administrator. Anyone with permission to modify the code will effectively gain administrative privileges in Jenkins. To fix that problem, the classpath is not extended by the "Additional classpath" or the script directory. And thus importing code is not possible when script security for Job DSL is enabled. As mentioned in the Migration docs, there is a switch to restore the old behavior. But be careful with that. Please move the discussion to the mailing list because this is interesting for a wider audience. I'm sure we can come up with a way to allow imports, but in a secure way.

          This would boil down to disabling script security when running with RUN_SCRIPTS permission. jglick and danielbeck, do you think this is a good idea?

          Daniel Spilker added a comment - This would boil down to disabling script security when running with RUN_SCRIPTS permission. jglick and danielbeck , do you think this is a good idea?

          daspilker I'm not sure what are you referring to.
          I tried to start a discussion on the mailng list as you suggested but got no responses.

          What I don't get at this point is why it's possible to import classes from Jenkinsfiles (https://jenkins.io/doc/book/pipeline/shared-libraries/) even with security ON, but not from Job-DSL scripts.

          Jakub Bochenski added a comment - daspilker I'm not sure what are you referring to. I tried to start a discussion on the mailng list as you suggested but got no responses. What I don't get at this point is why it's possible to import classes from Jenkinsfiles ( https://jenkins.io/doc/book/pipeline/shared-libraries/ ) even with security ON, but not from Job-DSL scripts.

          Mike Kobit added a comment -

          It seems to me like the same type of classpath "extending" when using Shared Libraries would be applicable here, as those are still sandboxed and security checked.

          Mike Kobit added a comment - It seems to me like the same type of classpath "extending" when using Shared Libraries would be applicable here, as those are still sandboxed and security checked.

          Shared Libraries is a Pipeline feature, only available in Pipeline. To get a similar feature in Job DSL it has to be implemented.

          And having an equivalent of Shared Libraries in Job DSL is not the same as importing arbitrary classes from the workspace as the summary and description suggest.

           

          Daniel Spilker added a comment - Shared Libraries is a Pipeline feature, only available in Pipeline. To get a similar feature in Job DSL it has to be implemented. And having an equivalent of Shared Libraries in Job DSL is not the same as importing arbitrary classes from the workspace as the summary and description suggest.  

          Jakub Bochenski added a comment - - edited

          > And having an equivalent of Shared Libraries in Job DSL is not the same as importing arbitrary classes from the workspace as the summary and description suggest.

          daspilker That's true. However what I really want is a way to share code between several DSL-scripts that are stored in a single git repo. I put the workspace import example because that's what used to work, but what I'm after is solving the problem described in previous sentence.

          > Shared Libraries is a Pipeline feature, only available in Pipeline. To get a similar feature in Job DSL it has to be implemented.

          I was hoping it's possible to reuse some of that code

          Jakub Bochenski added a comment - - edited > And having an equivalent of Shared Libraries in Job DSL is not the same as importing arbitrary classes from the workspace as the summary and description suggest. daspilker That's true. However what I really want is a way to share code between several DSL-scripts that are stored in a single git repo. I put the workspace import example because that's what used to work, but what I'm after is solving the problem described in previous sentence. > Shared Libraries is a Pipeline feature, only available in Pipeline. To get a similar feature in Job DSL it has to be implemented. I was hoping it's possible to reuse some of that code

          I opened a PR to allow importing Groovy files from the workspace when sandbox is enabled: https://github.com/jenkinsci/job-dsl-plugin/pull/1078

          The user executing the seed job must have the "WORKSPACE" permission to be able to read files from the workspace. The files are resolved relative to the workspace root when using inline scripts or to the script's directory when using script files.

          Note that only Groovy source files can be imported, no compiled classes will be resolved.

          Daniel Spilker added a comment - I opened a PR to allow importing Groovy files from the workspace when sandbox is enabled: https://github.com/jenkinsci/job-dsl-plugin/pull/1078 The user executing the seed job must have the "WORKSPACE" permission to be able to read files from the workspace. The files are resolved relative to the workspace root when using inline scripts or to the script's directory when using script files. Note that only Groovy source files can be imported, no compiled classes will be resolved.

          > Note that only Groovy source files can be imported, no compiled classes will be resolved.
          daspilker can you elaborate on the reasons for that? Is it a security limitation?

          Jakub Bochenski added a comment - > Note that only Groovy source files can be imported, no compiled classes will be resolved. daspilker can you elaborate on the reasons for that? Is it a security limitation?

          Jesse Glick added a comment -

          The sandbox operates as a compiler hook.

          Jesse Glick added a comment - The sandbox operates as a compiler hook.

            jamietanna Jamie Tanna
            jbochenski Jakub Bochenski
            Votes:
            6 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated: