diff --git a/tests/integration/kubernetes/k8s-attach-handlers.bats b/tests/integration/kubernetes/k8s-attach-handlers.bats index 7fb96908b6..cdc16c2396 100644 --- a/tests/integration/kubernetes/k8s-attach-handlers.bats +++ b/tests/integration/kubernetes/k8s-attach-handlers.bats @@ -25,8 +25,8 @@ setup() { policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" display_message="cat /usr/share/message" - exec_command="sh -c ${display_message}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${display_message}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -40,7 +40,7 @@ setup() { kubectl wait --for=condition=Ready --timeout=$timeout pod $pod_name # Check postStart message - check_postStart=$(kubectl exec $pod_name -- sh -c "$display_message") + check_postStart=$(kubectl exec $pod_name -- "${exec_command[@]}") echo "check_postStart=$check_postStart" echo "$check_postStart" | grep "Hello from the postStart handler" } diff --git a/tests/integration/kubernetes/k8s-caps.bats b/tests/integration/kubernetes/k8s-caps.bats index 8786cc3b14..89d3ca5bd0 100644 --- a/tests/integration/kubernetes/k8s-caps.bats +++ b/tests/integration/kubernetes/k8s-caps.bats @@ -16,8 +16,8 @@ setup() { policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" command="cat /proc/self/status" - exec_command="sh -c ${command}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${command}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -52,7 +52,7 @@ setup() { waitForProcess "$wait_time" "$sleep_time" "$cmd" # Verify expected capabilities from exec context: - kubectl exec "$pod_name" -- sh -c "${command}" | grep -q "$expected" + kubectl exec "$pod_name" -- "${exec_command[@]}" | grep -q "$expected" } teardown() { @@ -61,7 +61,7 @@ teardown() { echo "$expected" echo "observed: " kubectl logs "pod/$pod_name" - kubectl exec "$pod_name" -- sh -c "${command}" | grep Cap + kubectl exec "$pod_name" -- "${exec_command[@]}" | grep Cap kubectl delete pod "$pod_name" delete_tmp_policy_settings_dir "${policy_settings_dir}" } diff --git a/tests/integration/kubernetes/k8s-configmap.bats b/tests/integration/kubernetes/k8s-configmap.bats index aada0e7b5e..8b38a7ce6d 100644 --- a/tests/integration/kubernetes/k8s-configmap.bats +++ b/tests/integration/kubernetes/k8s-configmap.bats @@ -13,8 +13,8 @@ setup() { policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" cmd="env" - exec_command="sh -c ${cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" configmap_yaml_file="${pod_config_dir}/configmap.yaml" @@ -40,8 +40,8 @@ setup() { kubectl wait --for=condition=Ready --timeout=$timeout pod "$pod_name" # Check env - kubectl exec $pod_name -- sh -c $cmd | grep "KUBE_CONFIG_1=value-1" - kubectl exec $pod_name -- sh -c $cmd | grep "KUBE_CONFIG_2=value-2" + kubectl exec $pod_name -- "${exec_command[@]}" | grep "KUBE_CONFIG_1=value-1" + kubectl exec $pod_name -- "${exec_command[@]}" | grep "KUBE_CONFIG_2=value-2" } teardown() { diff --git a/tests/integration/kubernetes/k8s-copy-file.bats b/tests/integration/kubernetes/k8s-copy-file.bats index 4d2ba21ed7..e8634e7cb3 100644 --- a/tests/integration/kubernetes/k8s-copy-file.bats +++ b/tests/integration/kubernetes/k8s-copy-file.bats @@ -35,8 +35,8 @@ setup() { add_copy_from_host_to_policy_settings "${policy_settings_dir}" cat_command="cat /tmp/$file_name" - exec_command="sh -c ${cat_command}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${cat_command}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" auto_generate_policy "${policy_settings_dir}" "${pod_config}" @@ -53,7 +53,7 @@ setup() { kubectl cp "$file_name" $pod_name:/tmp # Print environment variables - kubectl exec $pod_name -- sh -c "${cat_command}" | grep $content + kubectl exec $pod_name -- "${exec_command[@]}" | grep $content } @test "Copy from pod to host" { @@ -72,8 +72,8 @@ setup() { add_copy_from_guest_to_policy_settings "${policy_settings_dir}" "/tmp/file.txt" guest_command="cd /tmp && echo $content > $file_name" - exec_command="sh -c ${guest_command}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${guest_command}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" auto_generate_policy "${policy_settings_dir}" "${pod_config}" @@ -88,7 +88,7 @@ setup() { kubectl get pods --all-namespaces # Create a file in the pod - kubectl exec "$pod_name" -- sh -c "$guest_command" + kubectl exec "$pod_name" -- "${exec_command[@]}" kubectl logs "$pod_name" || true kubectl describe pod "$pod_name" || true diff --git a/tests/integration/kubernetes/k8s-cpu-ns.bats b/tests/integration/kubernetes/k8s-cpu-ns.bats index c84863f453..a130a8d298 100644 --- a/tests/integration/kubernetes/k8s-cpu-ns.bats +++ b/tests/integration/kubernetes/k8s-cpu-ns.bats @@ -34,23 +34,21 @@ setup() { # Add policy to the yaml file policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" - num_cpus_cmd='grep -e "^processor" /proc/cpuinfo |wc -l' - exec_command="sh -c ${num_cpus_cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + num_cpus_cmd="grep -e '^processor' /proc/cpuinfo |wc -l" + exec_num_cpus_cmd=(sh -c "${num_cpus_cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_num_cpus_cmd[@]}" quotasyspath_cmd="cat ${quotasyspath}" - exec_command="sh -c ${quotasyspath_cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_quotasyspath_cmd=(sh -c "${quotasyspath_cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_quotasyspath_cmd[@]}" - periodsyspath_cmd="cat $periodsyspath" - exec_command="sh -c ${periodsyspath_cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + periodsyspath_cmd="cat ${periodsyspath}" + exec_periodsyspath_cmd=(sh -c "${periodsyspath_cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_periodsyspath_cmd[@]}" - sharessyspath_cmd="cat $sharessyspath" - exec_command="sh -c ${sharessyspath_cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" - - add_exec_to_policy_settings "${policy_settings_dir}" "sh -c " + sharessyspath_cmd="cat ${sharessyspath}" + exec_sharessyspath_cmd=(sh -c "${sharessyspath_cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_sharessyspath_cmd[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -69,7 +67,7 @@ setup() { for _ in $(seq 1 "$retries"); do # Get number of cpus total_cpus_container=$(kubectl exec pod/"$pod_name" -c "$container_name" \ - -- sh -c "$num_cpus_cmd") + -- "${exec_num_cpus_cmd[@]}") # Verify number of cpus [ "$total_cpus_container" -le "$total_cpus" ] [ "$total_cpus_container" -eq "$total_cpus" ] && break @@ -79,7 +77,7 @@ setup() { # Check the total of requests total_requests_container=$(kubectl exec $pod_name -c $container_name \ - -- sh -c "$sharessyspath_cmd") + -- "${exec_sharessyspath_cmd[@]}") info "total_requests_container = $total_requests_container" [ "$total_requests_container" -eq "$total_requests" ] @@ -87,10 +85,10 @@ setup() { # Check the cpus inside the container total_cpu_quota=$(kubectl exec $pod_name -c $container_name \ - -- sh -c "$quotasyspath_cmd") + -- "${exec_quotasyspath_cmd[@]}") total_cpu_period=$(kubectl exec $pod_name -c $container_name \ - -- sh -c "$periodsyspath_cmd") + -- "${exec_periodsyspath_cmd[@]}") division_quota_period=$(echo $((total_cpu_quota/total_cpu_period))) diff --git a/tests/integration/kubernetes/k8s-credentials-secrets.bats b/tests/integration/kubernetes/k8s-credentials-secrets.bats index ba079688dc..5969c38b29 100644 --- a/tests/integration/kubernetes/k8s-credentials-secrets.bats +++ b/tests/integration/kubernetes/k8s-credentials-secrets.bats @@ -17,9 +17,9 @@ setup() { # Add policy to pod-secret.yaml. pod_yaml_file="${pod_config_dir}/pod-secret.yaml" pod_cmd="ls /tmp/secret-volume" - pod_exec_command="sh -c ${pod_cmd}" + pod_exec_command=(sh -c "${pod_cmd}") pod_policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" - add_exec_to_policy_settings "${pod_policy_settings_dir}" "${pod_exec_command}" + add_exec_to_policy_settings "${pod_policy_settings_dir}" "${pod_exec_command[@]}" add_requests_to_policy_settings "${pod_policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${pod_policy_settings_dir}" "${pod_yaml_file}" @@ -29,6 +29,7 @@ setup() { # https://github.com/kata-containers/kata-containers/issues/10033 pod_env_yaml_file="${pod_config_dir}/pod-secret-env.yaml" pod_env_cmd="printenv" + pod_env_exec_command=(sh -c "${pod_env_cmd}") add_allow_all_policy_to_yaml "${pod_env_yaml_file}" } @@ -50,8 +51,8 @@ setup() { kubectl wait --for=condition=Ready --timeout=$timeout pod "$pod_name" # List the files - kubectl exec $pod_name -- sh -c "$pod_cmd" | grep -w "password" - kubectl exec $pod_name -- sh -c "$pod_cmd" | grep -w "username" + kubectl exec $pod_name -- "${pod_exec_command[@]}" | grep -w "password" + kubectl exec $pod_name -- "${pod_exec_command[@]}" | grep -w "username" # Create a pod that has access to the secret data through environment variables kubectl create -f "${pod_env_yaml_file}" @@ -60,8 +61,8 @@ setup() { kubectl wait --for=condition=Ready --timeout=$timeout pod "$second_pod_name" # Display environment variables - kubectl exec $second_pod_name -- sh -c "$pod_env_cmd" | grep -w "SECRET_USERNAME" - kubectl exec $second_pod_name -- sh -c "$pod_env_cmd" | grep -w "SECRET_PASSWORD" + kubectl exec $second_pod_name -- "${pod_env_exec_command[@]}" | grep -w "SECRET_USERNAME" + kubectl exec $second_pod_name -- "${pod_env_exec_command[@]}" | grep -w "SECRET_PASSWORD" } teardown() { diff --git a/tests/integration/kubernetes/k8s-custom-dns.bats b/tests/integration/kubernetes/k8s-custom-dns.bats index c360079bdf..b665629ac9 100644 --- a/tests/integration/kubernetes/k8s-custom-dns.bats +++ b/tests/integration/kubernetes/k8s-custom-dns.bats @@ -21,8 +21,8 @@ setup() { # Add policy to the yaml file policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" - exec_command="cat ${file_name}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(cat "${file_name}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -36,8 +36,8 @@ setup() { kubectl wait --for=condition=Ready --timeout=$timeout pod $pod_name # Check dns config at /etc/resolv.conf - kubectl exec "$pod_name" -- cat "$file_name" | grep -q "nameserver 1.2.3.4" - kubectl exec "$pod_name" -- cat "$file_name" | grep -q "search dns.test.search" + kubectl exec "$pod_name" -- "${exec_command[@]}" | grep -q "nameserver 1.2.3.4" + kubectl exec "$pod_name" -- "${exec_command[@]}" | grep -q "search dns.test.search" } teardown() { diff --git a/tests/integration/kubernetes/k8s-env.bats b/tests/integration/kubernetes/k8s-env.bats index d667450183..96b117be2b 100644 --- a/tests/integration/kubernetes/k8s-env.bats +++ b/tests/integration/kubernetes/k8s-env.bats @@ -17,8 +17,8 @@ setup() { policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" - exec_command="sh -c ${cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -32,14 +32,14 @@ setup() { kubectl wait --for=condition=Ready --timeout=$timeout pod "$pod_name" # Print environment variables - kubectl exec $pod_name -- sh -c $cmd | grep "MY_POD_NAME=$pod_name" - kubectl exec $pod_name -- sh -c $cmd | \ + kubectl exec $pod_name -- "${exec_command[@]}" | grep "MY_POD_NAME=$pod_name" + kubectl exec $pod_name -- "${exec_command[@]}" | \ grep "HOST_IP=\([0-9]\+\(\.\|$\)\)\{4\}" # Requested 32Mi of memory - kubectl exec $pod_name -- sh -c $cmd | \ + kubectl exec $pod_name -- "${exec_command[@]}" | \ grep "MEMORY_REQUESTS=$((1024 * 1024 * 32))" # Memory limits allocated by the node - kubectl exec $pod_name -- sh -c $cmd | grep "MEMORY_LIMITS=[1-9]\+" + kubectl exec $pod_name -- "${exec_command[@]}" | grep "MEMORY_LIMITS=[1-9]\+" } teardown() { diff --git a/tests/integration/kubernetes/k8s-file-volume.bats b/tests/integration/kubernetes/k8s-file-volume.bats index 1a5a4b98e8..f35ab1decc 100644 --- a/tests/integration/kubernetes/k8s-file-volume.bats +++ b/tests/integration/kubernetes/k8s-file-volume.bats @@ -34,8 +34,8 @@ setup() { # Add policy to the yaml file policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" - command="cat $mount_path" - add_exec_to_policy_settings "${policy_settings_dir}" "${command}" + command=(cat "$mount_path") + add_exec_to_policy_settings "${policy_settings_dir}" "${command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${test_yaml}" @@ -51,7 +51,7 @@ setup() { kubectl wait --for=condition=Ready --timeout=$timeout pod "$pod_name" # Validate file volume body inside the pod - file_in_container=$(kubectl exec $pod_name -- $command) + file_in_container=$(kubectl exec $pod_name -- "${command[@]}") [ "$file_body" == "$file_in_container" ] } diff --git a/tests/integration/kubernetes/k8s-number-cpus.bats b/tests/integration/kubernetes/k8s-number-cpus.bats index f42b445fb5..b81143a6d0 100644 --- a/tests/integration/kubernetes/k8s-number-cpus.bats +++ b/tests/integration/kubernetes/k8s-number-cpus.bats @@ -19,8 +19,8 @@ setup() { policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" num_cpus_cmd='cat /proc/cpuinfo |grep processor|wc -l' - exec_command="sh -c ${num_cpus_cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${num_cpus_cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -40,7 +40,7 @@ setup() { for _ in $(seq 1 "$retries"); do # Get number of cpus number_cpus=$(kubectl exec pod/"$pod_name" -c "$container_name" \ - -- sh -c "$num_cpus_cmd") + -- "${exec_command[@]}") if [[ "$number_cpus" =~ ^[0-9]+$ ]]; then # Verify number of cpus [ "$number_cpus" -le "$max_number_cpus" ] diff --git a/tests/integration/kubernetes/k8s-optional-empty-configmap.bats b/tests/integration/kubernetes/k8s-optional-empty-configmap.bats index fdf3d77d73..a58c58dddc 100644 --- a/tests/integration/kubernetes/k8s-optional-empty-configmap.bats +++ b/tests/integration/kubernetes/k8s-optional-empty-configmap.bats @@ -15,12 +15,12 @@ setup() { policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" empty_command="ls /empty-config" - exec_command="sh -c ${empty_command}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_empty_command=(sh -c "${empty_command}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_empty_command[@]}" optional_command="ls /optional-missing-config" - exec_command="sh -c ${optional_command}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_optional_command=(sh -c "${optional_command}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_optional_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${pod_yaml}" @@ -40,8 +40,8 @@ setup() { kubectl wait --for=condition=Ready --timeout=$timeout pod "$pod_name" # Check configmap folders exist - kubectl exec $pod_name -- sh -c "${empty_command}" - kubectl exec $pod_name -- sh -c ls /optional-missing-config + kubectl exec $pod_name -- "${exec_empty_command[@]}" + kubectl exec $pod_name -- "${exec_optional_command[@]}" } teardown() { diff --git a/tests/integration/kubernetes/k8s-security-context.bats b/tests/integration/kubernetes/k8s-security-context.bats index 5d6b5380ee..8595a5ece3 100644 --- a/tests/integration/kubernetes/k8s-security-context.bats +++ b/tests/integration/kubernetes/k8s-security-context.bats @@ -15,8 +15,8 @@ setup() { policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" cmd="ps --user 1000 -f" - exec_command="sh -c ${cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -33,7 +33,7 @@ setup() { # Check user process="tail -f /dev/null" - kubectl exec $pod_name -- sh -c "$cmd" | grep "$process" + kubectl exec $pod_name -- "${exec_command[@]}" | grep "$process" } teardown() { diff --git a/tests/integration/kubernetes/k8s-shared-volume.bats b/tests/integration/kubernetes/k8s-shared-volume.bats index 1b2df09d59..2181e39ebc 100644 --- a/tests/integration/kubernetes/k8s-shared-volume.bats +++ b/tests/integration/kubernetes/k8s-shared-volume.bats @@ -24,8 +24,8 @@ setup() { # Add policy to the yaml file policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" - exec_command="sh -c ${cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -38,7 +38,7 @@ setup() { # Communicate containers msg="Hello from the $second_container_name" - kubectl exec "$pod_name" -c "$first_container_name" -- sh -c "$cmd" | grep "$msg" + kubectl exec "$pod_name" -c "$first_container_name" -- "${exec_command[@]}" | grep "$msg" } @test "initContainer with shared volume" { @@ -51,8 +51,8 @@ setup() { # Add policy to the yaml file policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")" - exec_command="sh -c ${cmd}" - add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command}" + exec_command=(sh -c "${cmd}") + add_exec_to_policy_settings "${policy_settings_dir}" "${exec_command[@]}" add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest" auto_generate_policy "${policy_settings_dir}" "${yaml_file}" @@ -63,7 +63,7 @@ setup() { # Check pods kubectl wait --for=condition=Ready --timeout=$timeout pod $pod_name - kubectl exec "$pod_name" -c "$last_container" -- sh -c "$cmd" + kubectl exec "$pod_name" -c "$last_container" -- "${exec_command[@]}" } teardown() { diff --git a/tests/integration/kubernetes/tests_common.sh b/tests/integration/kubernetes/tests_common.sh index 4e9d06d845..ca48de34f9 100644 --- a/tests/integration/kubernetes/tests_common.sh +++ b/tests/integration/kubernetes/tests_common.sh @@ -233,11 +233,22 @@ auto_generate_policy() { # Change genpolicy settings to allow "kubectl exec" to execute a command # and to read console output from a test pod. add_exec_to_policy_settings() { - declare -r settings_dir="$1" - declare -r allowed_exec="$2" - auto_generate_policy_enabled || return 0 + local -r settings_dir="$1" + + # TODO: teach genpolicy to work with an array of args, instead of joining the args here. + shift + if [ "${#@}" -gt "1" ]; then + # Join all the exec args. + local allowed_exec=$(printf '%s ' "${@}") + + # Remove the trailing space character. + allowed_exec="${allowed_exec::-1}" + else + local -r allowed_exec="$1" + fi + # Change genpolicy settings to allow kubectl to exec the command specified by the caller. info "${settings_dir}/genpolicy-settings.json: allowing exec: ${allowed_exec}" jq --arg allowed_exec "${allowed_exec}" \