Static groovy script and java security access control issue


I want to use a groovy script:
1.) to calculate a value (this works) and
2.) to add the newly calculated value to the document using the update API

The script is stored in /etc/elasticsearch/scripts and I understood that in this case I do not have to think about the Java Security Manager. Is this right?

The first part of the script is working fine. However things are not working when I add the second part of the script:

def url = "http://elk:9200/testindex/testdocument/" + doc['id'] + "/_update"
def json = '{ "doc": { "testvalue":"999" } }'
def response = ["curl", "-X", "POST", "-H", "Content-Type: application/json", "-d", "${json}", "${url}"].execute().text

Executing the script I get following error message:
1.)Output from script

"reason": {
"caused_by": {
"reason": "access denied ("" "<>" "execute")",
"type": "access_control_exception"
"reason": "failed to run file script [vm_lifetime_deleted] using lang [groovy]",
"type": "script_exception"

2.) In /var/log/elasticsearch/elasticsearch.log

[2016-04-27 10:05:12,435][DEBUG][ ] [elk] [8] Failed to execute fetch phase
RemoteTransportException[[elk][][indices:data/read/search[phase/fetch/id]]]; nested: ScriptException[failed to run file script [vm_lifetime_deleted] using lang [groovy]]; nested: AccessControlException[access denied ("" "<>" "execute")];
Caused by: ScriptException[failed to run file script [vm_lifetime_deleted] using lang [groovy]]; nested: AccessControlException[access denied ("" "<>" "execute")];
at org.elasticsearch.script.groovy.GroovyScriptEngineService$
at org.elasticsearch.transport.TransportRequestHandler.messageReceived(
at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(
at org.elasticsearch.transport.TransportService$4.doRun(
at java.util.concurrent.ThreadPoolExecutor.runWorker(
at java.util.concurrent.ThreadPoolExecutor$
Caused by: access denied ("" "<>" "execute")
at java.lang.SecurityManager.checkPermission(
at java.lang.SecurityManager.checkExec(
at java.lang.ProcessBuilder.start(
at java.lang.Runtime.exec(
at java.lang.Runtime.exec(
at org.codehaus.groovy.runtime.ProcessGroovyMethods.execute(
at org.codehaus.groovy.runtime.ProcessGroovyMethods.execute(
at org.codehaus.groovy.runtime.dgm$895.doMethodInvoke(Unknown Source)
at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(
at org.elasticsearch.script.groovy.GroovyScriptEngineService$GroovyScript$
at Method)
at org.elasticsearch.script.groovy.GroovyScriptEngineService$

The same script works fine If I run it from within groovyConsole. In addtion, I tried to define a java.policy which grants all permissions (although this is not needed to my understanding).


grant {

But I still get the error message.

I highly appreciate any help.


Can you post your script (and perhaps an example document) so we can try to reproduce this?

Yes, following you can see the query, the script and an example document.

"query" : {
"query_string" : {
"query": "vm_state:deleted OR vm_state:active",
"script_fields": {
"lifetime": {
"script": {
"file": "vm_lifetime_deleted"

The script:

if(doc['vm_state'].value == "deleted") {
l1 = (doc['deleted_at'].value - doc['created_at'].value) / (1000 * 3600 * 24)
} else if(doc['vm_state'].value == "active") {
def d1 = new Date()
l1 = (d1.getTime() - doc['created_at']) / (1000 * 3600 * 24)

def url = "http://elk:9200/openstack/openstack/" + doc['id'] + "/_update"
def json = '{ "doc": { "lifetime":"$l1" } }'
def response = ["curl", "-X", "POST", "-H", "Content-Type: application/json", "-d", "${json}", "${url}"].execute().text

lifetime = Math.round(l1 *100)/100.0

And finally, one document:

"_id": "123",
"_index": "openstack",
"_source": {
"@timestamp": "2016-04-28T15:52:00.131Z",
"@version": "1",
"created_at": "2015-04-23T09:51:14.000Z",
"deleted": 123,
"deleted_at": "2015-04-23T14:16:28.000Z",
"id": 123,
"lifetime": 0,
"memory_mb": 4096,
"vm_state": "deleted"
"_type": "openstack",
"_version": 205,
"found": true

Wait, it looks like you are trying to execute a curl command from within the groovy script itself? Is this correct? If so, this is definitely not something we want to encourage! This is probably something best left to logic outside of the groovy scripting in Elasticsearch, or perhaps inplemented as a native script (see:

Ok, I'll take a look at the script linked.