Jenkins/In-process Script Approval

From Ever changing code
Jump to navigation Jump to search

Documentation of script-approval contains all details about:

  • Script Security plugin (this is what we discussed here in this post)
  • Groovy sandbox
  • script approval

Approve scripts

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.


Approved scripts hash are stored in cat $JENKINS_HOME/scriptApproval.xml:

<?xml version='1.1' encoding='UTF-8'?>
<scriptApproval plugin="script-security@1.40">
  <approvedScriptHashes>
    <string>dbdd49c3b23c190f88daa4b57efc1adb29879044</string>
  </approvedScriptHashes>
  <approvedSignatures/>
  <aclApprovedSignatures/>
  <approvedClasspathEntries/>
  <pendingScripts/>
  <pendingSignatures/>
  <pendingClasspathEntries/>

Disable globally

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.

ClipCapIt-200328-145440.PNG


The caveat, it will not prompt for approval any first layer DSL Script inline or from a file, but still will call for approval if nested scripts validate Security Script rules. Eg. Jenkins DSL Plugin will process without approval the DSL code (layer1) but if there is a pipeline{} code that is considered as another script inline or from a file (layer2) it will need to be approved.


2-layer DSL script. It contains Utils.markStageSkippedForConditional that uses not whitelisted method.

pipelineJob('New_pipeline') {       // <- layer1 script will get executed
    parameters { 
        choiceParam( 'ACTION', ["plan","apply"],"terraform plan or apply")
    }
    definition {
        cps {
            script('''             // <- layer2, will require approval
                import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
                def hosts
                pipeline {
                    agent any
                    environment {
                        REGION = "eu-west-1"
                    }
                    stages {
                        stage('Build host lists') {
                            steps {
                                script {
                                    hosts = [ "node-1", "node-2" ]
                                }
                            }
                        }
                        stage('Display list') {
                            steps {
                                echo 'Print host[0]'
                                sh \'\'\'#!/bin/bash
                                    HOST=\'\'\' + hosts[0] + \'\'\'
                                    printf "HOST: $HOST";
                                \'\'\'
                            }
                        stage('SkipStage') {
                            steps {
                                // requires approval
                                Utils.markStageSkippedForConditional('SkipStage')
                            }
                        }
                        }
                    }
                }
            ''')
        }
    }
}

Approve scripts programatically

You can add this snippet after you processed all your job_dsl.groovy files and it will approve any outstanding script.

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

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

Resources:

Resources