43

I was trying to execute a seed job(having github url with groovy scripts) in jenkins and got following error.

First time build. Skipping changelog.
Processing DSL script APIServerDeployer.groovy
ERROR: script not yet approved for use
Finished: FAILURE

StephenKing
  • 36,187
  • 11
  • 83
  • 112
ricky
  • 471
  • 1
  • 5
  • 11
  • 3
    Could that be related to JobDSL 1.60 introducing [script security](https://github.com/jenkinsci/job-dsl-plugin/wiki/Script-Security)? – StephenKing Apr 29 '17 at 18:40

9 Answers9

47

In order to get past this Jenkins security feature, you will need to approve your script. Go to Manage Jenkins -> In-process Script Approval. In that screen, you will see the script that you are trying to execute. There should be an approve button that you'll need to click to approve that script.

enter image description here

Erwin Alberto
  • 1,064
  • 10
  • 7
28

Job DSL version 1.60 introduced Script Security; to restore old behavior, uncheck Enable script security for Job DSL scripts in the CSRF Protection section of the "Configure Global Security" page. This should only be done if you have another way of approving scripts, such as through git pull request approval if your seed job builds jobs living in git.

Nick Jones
  • 4,395
  • 6
  • 33
  • 44
edst
  • 1,074
  • 10
  • 20
  • 4
    unchecking that option did not have any effect for me (Jenkins 2.107.2). – Alex Apr 22 '18 at 17:11
  • 2
    Unchecking that option does not seem to remove the list of scripts that are already blocked/pending approval, so you do have to approve the scripts that were already there. It does prevent new job-dsl changes from having to be approved. – Willem M. Mar 25 '19 at 12:06
  • 1
    Unchecking that box did not work for me either (Jenkins 2.198) – Dexter Lakin Jul 24 '20 at 08:27
  • On my Jenkins 2.332.3 system that checkbox appears lower down, not under **CSRF Protection**. I'm guessing that it has no heading. – Generic Ratzlaugh May 27 '22 at 14:38
16

Here's a groovy script that we use to pre-populate script approvals:


import java.lang.reflect.*;
import jenkins.model.Jenkins;
import jenkins.model.*;
import org.jenkinsci.plugins.scriptsecurity.scripts.*;
import org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.*;

scriptApproval = ScriptApproval.get()
alreadyApproved = new HashSet<>(Arrays.asList(scriptApproval.getApprovedSignatures()))


// add all manual whitelist methods here.

approveSignature('method groovy.json.JsonBuilder call java.util.List')
approveSignature('method groovy.json.JsonSlurper parseText java.lang.String')
approveSignature('method groovy.json.JsonSlurperClassic parseText')
approveSignature('method groovy.lang.Binding getVariables')
approveSignature('method groovy.lang.Binding getVariable java.lang.String')
approveSignature('method groovy.lang.Binding hasVariable java.lang.String')
approveSignature('method groovy.lang.Closure getMaximumNumberOfParameters')
approveSignature('method groovy.lang.GString plus java.lang.String')
approveSignature('method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object')
approveSignature('method hudson.model.Actionable getAction java.lang.Class')
approveSignature('method hudson.model.Actionable getActions')
approveSignature('method hudson.model.Cause$UpstreamCause getUpstreamProject')
approveSignature('method hudson.model.Cause$UserIdCause getUserId')
approveSignature('method hudson.model.ItemGroup getItem java.lang.String')
approveSignature('method hudson.model.Item getUrl')
approveSignature('method hudson.model.Job getBuildByNumber int')
approveSignature('method hudson.model.Job getLastBuild')
approveSignature('method hudson.model.Job getLastSuccessfulBuild')
approveSignature('method hudson.model.Job isBuilding')
approveSignature('method hudson.model.Run getCauses')
approveSignature('method hudson.model.Run getEnvironment hudson.model.TaskListener')
approveSignature('method hudson.model.Run getParent')
approveSignature('method hudson.model.Run getNumber')
approveSignature('method hudson.model.Run getResult')
approveSignature('method hudson.model.Run getUrl')
approveSignature('method hudson.model.Run getLogFile')
approveSignature('method java.util.Map containsKey java.lang.Object')
approveSignature('method java.util.Map entrySet')
approveSignature('method java.util.Map get java.lang.Object')
approveSignature('method java.util.Map keySet')
approveSignature('method java.util.Map putAll java.util.Map')
approveSignature('method java.util.Map remove java.lang.Object')
approveSignature('method java.util.Map size')
approveSignature('method java.util.Map values')
// ... your list here ...

scriptApproval.save()

void approveSignature(String signature) {
    if (!alreadyApproved.contains(signature)) {
       scriptApproval.approveSignature(signature)
    }
}

// Utility methods
String printArgumentTypes(Object[] args) {
    StringBuilder b = new StringBuilder();
    for (Object arg : args) {
        b.append(' ');
        b.append(EnumeratingWhitelist.getName(arg));
    }
    return b.toString();
}
Jason Kulatunga
  • 5,814
  • 1
  • 26
  • 50
  • 4
    super useful, thanks! what do you use `printArgumentTypes` for? or did you just forget that there? – fersarr Aug 16 '19 at 10:43
10

If you're using the Jenkins Groovy DSL, here's a snippet you can use to approve every script that's pending:

import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval

ScriptApproval scriptApproval = ScriptApproval.get()
scriptApproval.pendingScripts.each {
    scriptApproval.approveScript(it.hash)
}

See: https://javadoc.jenkins.io/plugin/script-security/org/jenkinsci/plugins/scriptsecurity/scripts/ScriptApproval.html

jeffwtribble
  • 1,131
  • 1
  • 9
  • 6
  • 2
    I tried to use this snippet but ran into some concurrency exceptions. I modified it to get rid of the `each` iteration, which I suspected was involved in the issue, and it worked that way then: ``` import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval ScriptApproval scriptApproval = ScriptApproval.get() while (scriptApproval.pendingScripts) { scriptApproval.approveScript(scriptApproval.pendingScripts[0].hash) } ``` – mkorvas Jul 31 '20 at 20:30
  • 2
    Like @mkorvas I too got a **java.util.ConcurrentModificationException**. However I wanted to check the script content for a particular value _Some text_, and only then approve it. So I did it in 2 loops. The first adding the script hash to an array and 2nd for loop doing the approval. `ScriptApproval scriptApproval = ScriptApproval.get() def hashesToApprove = [] scriptApproval.pendingScripts.each { if (it.script.contains("Some text")) { hashesToApprove.add(it.hash) } } for (String hash : hashesToApprove) { scriptApproval.approveScript(hash) }` – ptha Aug 19 '21 at 14:25
  • 1
    Where can I put this piece of code ? in the end of the seed script file ? I would like to automate this task after each seed trigger – yarin Jan 10 '22 at 10:27
  • perfect for me ! – Bobax Jan 21 '22 at 11:59
  • @yarin Yes I put this at the end of a seed file. However you will run into the issue where a Script Approval is not generated until you actually try to run the job generated by your seed. So the first time you run the seed, there is nothing to approve. After if you try to run the job, it will fail because it hasn't been approved. If you then run the seed a 2nd time, it will approve this new script approval (and job can be run). So I'm not sure how you can fully automate this. – ptha Oct 28 '22 at 17:04
8

Job DSL version 1.60 introduced Script Security, which requires you to whitelist scripts.

Read also the hints about migrating to 1.60.

StephenKing
  • 36,187
  • 11
  • 83
  • 112
7

If you want to disable it programatically, drop the following script into $JENKINS_HOME/init.groovy.d/disable-script-security.groovy:

import javaposse.jobdsl.plugin.GlobalJobDslSecurityConfiguration
import jenkins.model.GlobalConfiguration

// disable Job DSL script approval
GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).useScriptSecurity=false
GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).save()
al.
  • 1,296
  • 13
  • 14
  • 8
    Maybe you don't want the entire setting disabled, but an individual script pre-approved programmatically? – Highway of Life Jun 22 '18 at 00:18
  • 3
    This did not work for me. I dropped that file and restarted Jenkins but it still required me to do approve the script from the UI. – jeffreyveon Jan 02 '19 at 05:30
  • Worked for me; @HighwayofLife's suggestion would definitely be preferred, but I'm running in a test sandbox so not necessarily concerned in my use case. – kian May 29 '19 at 20:57
3

Give a try with disabling script security for Job DSL scripts under Configure Global Security settings. Disable script security for Job DSL scripts

Amal CP
  • 31
  • 2
0

make sure you have enabled groovy sand box below the pipeline

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 22 '22 at 23:58
0

Manage Jenkins -> Security -> disable Enable script security for Job DSL scripts