Skip to content

fix(deno): default permissions so env/inputFiles/outputFiles work on Script - #415

Merged
jymaire merged 1 commit into
mainfrom
fix/410-deno-script-permissions
Sep 3, 2026
Merged

fix(deno): default permissions so env/inputFiles/outputFiles work on Script#415
jymaire merged 1 commit into
mainfrom
fix/410-deno-script-permissions

Conversation

@jymaire

@jymaire jymaire commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • deno.Script built deno run <file> with no permission flags. Deno denies env, filesystem read and write by default, so env, inputFiles and outputFiles all failed at runtime with NotCapable errors — the three features every other script task supports were unusable.
  • Added a permissions property on deno.Script defaulting to --allow-env, --allow-read, --allow-write, giving parity with the rest of the module by default. Users can widen it (e.g. --allow-net) or set it to an empty list to run under Deno's secure-by-default sandbox.
  • deno.Commands is unaffected — users already control the full command there.
  • Updated the task Javadoc/@Schema, added a runnable example, and updated the plugin how-to doc.

closes: #410

Test plan

  • rtk test ./gradlew :plugin-script-deno:test passes (includes a new test reproducing the issue — first confirmed it failed with NotCapable: Requires env access to "MY_VAR" against the old code, then verified it passes with the fix; also exercises inputFiles/outputFiles)
  • rtk err ./gradlew :plugin-script-deno:compileJava :plugin-script-deno:compileTestJava — no errors
  • ./gradlew shadowJar

…/outputFiles work

deno.Script ran `deno run <file>` with no permission flags. Deno denies
env, filesystem read and write by default, so the env, inputFiles and
outputFiles properties that every other script task supports failed at
runtime with NotCapable errors.

Add a `permissions` property defaulting to --allow-env, --allow-read and
--allow-write, giving Script parity with the rest of the module while
still letting users scope permissions up (e.g. --allow-net) or down to
an empty list for Deno's secure-by-default sandbox.
@jymaire jymaire self-assigned this Sep 2, 2026
@kestrabot kestrabot Bot added this to Pull Requests Sep 2, 2026
@github-project-automation github-project-automation Bot moved this to To review in Pull Requests Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

📦 Artifacts

Name Size Updated Expiration
jar 56.82 MB Sep 2, 26, 2:54:35 PM UTC Sep 9, 26, 2:54:32 PM UTC

🧪 Java Unit Tests

TestsPassed ✅SkippedFailedTime ⏱
Java Tests Report247 ran247 ✅0 ⚠️0 ❌23m 1s 381ms

🔁 Unreleased Commits

8 commits since v1.9.8

SHA Title Author Date
e37e4bd chore(deps): bump gradle-wrapper from 9.7.0 to 9.7.1 (#409) dependabot[bot] Aug 27, 26, 8:24:16 AM UTC
7fff1ff chore(deps): bump com.github.ben-manes.versions from 0.60.0 to 0.61.0 (#408) dependabot[bot] Aug 27, 26, 8:24:26 AM UTC
8169b93 chore(deps): bump org.apache.groovy:groovy-jsr223 from 5.0.7 to 5.1.0 (#407) dependabot[bot] Aug 27, 26, 8:24:37 AM UTC
7c41b6b chore(deps): move from test-logger to kestra logger Ludovic DEHON Aug 28, 26, 4:23:17 PM UTC
4f8d706 chore(deps): bump org.apache.groovy:groovy-jsr223 from 5.1.0 to 5.1.1 (#413) dependabot[bot] Aug 31, 26, 8:26:37 AM UTC
a38e2d5 chore(deps): bump the kestra-gradle-plugins group with 4 updates (#412) dependabot[bot] Aug 31, 26, 8:26:48 AM UTC
4de3bc2 chore: use jvmargs for all plugins Ludovic DEHON Sep 2, 26, 12:36:14 PM UTC
9c73355 fix(groovy): default the Docker runner to root for Commands tasks (#414) jymaire Sep 2, 26, 2:46:59 PM UTC

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Tests report quick summary:

success ✅ > tests: 247, success: 247, skipped: 0, failed: 0

unfold for details
Project Status Success Skipped Failed
plugin-script-bun success ✅ 3 0 0
plugin-script-deno success ✅ 4 0 0
plugin-script-dotnet success ✅ 8 0 0
plugin-script-go success ✅ 18 0 0
plugin-script-groovy success ✅ 10 0 0
plugin-script-jbang success ✅ 2 0 0
plugin-script-julia success ✅ 2 0 0
plugin-script-jython success ✅ 5 0 0
plugin-script-lua success ✅ 3 0 0
plugin-script-node success ✅ 13 0 0
plugin-script-nashorn success ✅ 6 0 0
plugin-script-perl success ✅ 3 0 0
plugin-script-php success ✅ 3 0 0
plugin-script-powershell success ✅ 4 0 0
plugin-script-python success ✅ 75 0 0
plugin-script-r success ✅ 2 0 0
plugin-script-ruby success ✅ 39 0 0
plugin-script-shell success ✅ 47 0 0

@jymaire

jymaire commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Browser QA — deno.Script permission flags

Edition: OSS | Docker tag: develop (UI reports v2.1; issue was filed on 2.0.0-rc10, so QA runs against the development image)
Instance: http://3hiua.kestra.docker.localhost:1355/ui/ (left running for manual review — docker rm -f kestra-3hiua to stop)
Screenshots: https://claude.ai/code/artifact/7f944d7b-3950-4987-9a8d-d4cbf3334dcb
Plugin build: io_kestra_plugin__plugin-script-deno__1_9_9-SNAPSHOT.jar from fix/410-deno-script-permissions

Summary

# Flow Expected Result
1 deno_env_repro_410 (exact repro from #410) ENV=hello instead of NotCapable ✅ SUCCESS
2 deno_input_output_files inputFiles readable, outputFiles captured ✅ SUCCESS
3 deno_custom_permissions user-supplied --allow-net honored ✅ SUCCESS
4 deno_empty_permissions permissions: [] restores Deno's deny-all sandbox ✅ FAILED as designed
5 deno_commands_non_regression deno.Commands unchanged ✅ SUCCESS

The generated command line was verified in the logs: deno run --allow-env --allow-read --allow-write <script>.ts — the defaults are applied, and are overridden verbatim when permissions is set.


Flow 1: deno_env_repro_410 (✅ SUCCESS)

Flow YAML
id: deno_env_repro_410
namespace: qa.deno
tasks:
  - id: deno_env
    type: io.kestra.plugin.scripts.deno.Script
    taskRunner:
      type: io.kestra.plugin.scripts.runner.docker.Docker
    containerImage: denoland/deno:alpine
    env:
      MY_VAR: hello
    script: |
      console.log("ENV=" + Deno.env.get("MY_VAR"));

Gantt (screenshot)

Task Status Duration
deno_env SUCCESS ~0.5s
Total SUCCESS ~0.5s

Logs synthesis — the exact scenario from the issue now passes. Command: deno run --allow-env --allow-read --allow-write /tmp/.../8032887033266725774.ts; output INFO ENV=hello; Command succeed with exit code 0. Before the fix this failed with NotCapable: Requires env access to "MY_VAR".

Outputs — none (task produces no output files).


Flow 2: deno_input_output_files (✅ SUCCESS)

Flow YAML
id: deno_input_output_files
namespace: qa.deno
tasks:
  - id: deno_files
    type: io.kestra.plugin.scripts.deno.Script
    taskRunner:
      type: io.kestra.plugin.scripts.runner.docker.Docker
    containerImage: denoland/deno:alpine
    inputFiles:
      in.txt: "hello from input file"
    outputFiles:
      - out.txt
    script: |
      const content = Deno.readTextFileSync("in.txt");
      console.log("READ=" + content);
      Deno.writeTextFileSync("out.txt", content.toUpperCase());
      console.log("WROTE out.txt");

Gantt (screenshot)

Task Status Duration
deno_files SUCCESS 0.60s
Total SUCCESS 0.60s

Logs synthesisINFO READ=hello from input file, INFO WROTE out.txt, then Captured 1 output file(s). Both the read and the write permissions that previously blocked this now apply.

Outputs synthesis (screenshot) — deno_files exposes { vars, exitCode, outputFiles, taskRunner } with outputFiles."out.txt" = kestra:///qa/deno/deno-input-output-files/executions/.../out.txt.


Flow 3: deno_custom_permissions (✅ SUCCESS)

Flow YAML
id: deno_custom_permissions
namespace: qa.deno
tasks:
  - id: deno_net
    type: io.kestra.plugin.scripts.deno.Script
    taskRunner:
      type: io.kestra.plugin.scripts.runner.docker.Docker
    containerImage: denoland/deno:alpine
    permissions:
      - --allow-env
      - --allow-read
      - --allow-write
      - --allow-net
    env:
      MY_VAR: custom
    script: |
      console.log("ENV=" + Deno.env.get("MY_VAR"));
      console.log("NET=" + Deno.permissions.querySync({ name: "net" }).state);
      console.log("READ=" + Deno.permissions.querySync({ name: "read" }).state);

Gantt (screenshot)

Task Status Duration
deno_net SUCCESS 0.55s
Total SUCCESS 0.55s

Logs synthesisENV=custom, NET=granted, READ=granted. Deno itself confirms the user-supplied flag list reached the runtime, so the property is not cosmetic.


Flow 4: deno_empty_permissions (✅ FAILED — expected)

Flow YAML
id: deno_empty_permissions
namespace: qa.deno
tasks:
  - id: deno_sandboxed
    type: io.kestra.plugin.scripts.deno.Script
    taskRunner:
      type: io.kestra.plugin.scripts.runner.docker.Docker
    containerImage: denoland/deno:alpine
    permissions: []
    env:
      MY_VAR: denied
    script: |
      console.log("ENV=" + Deno.env.get("MY_VAR"));

Gantt (screenshot)

Task Status Duration
deno_sandboxed FAILED 0.52s
Total FAILED (expected) 0.52s

Logs synthesiserror: Uncaught (in promise) NotCapable: Requires env access to "MY_VAR", run again with the --allow-env flag, then TaskException: Command failed with exit code 1. This is the desired outcome: an empty list is respected rather than silently replaced by the defaults, so users who want Deno's secure-by-default sandbox can still have it.


Flow 5: deno_commands_non_regression (✅ SUCCESS)

Flow YAML
id: deno_commands_non_regression
namespace: qa.deno
tasks:
  - id: deno_cmd
    type: io.kestra.plugin.scripts.deno.Commands
    taskRunner:
      type: io.kestra.plugin.scripts.runner.docker.Docker
    containerImage: denoland/deno:alpine
    env:
      MY_VAR: cmdhello
    inputFiles:
      main.ts: |
        console.log("ENV=" + Deno.env.get("MY_VAR"));
    commands:
      - deno run --allow-all main.ts

Gantt (screenshot)

Task Status Duration
deno_cmd SUCCESS 0.50s
Total SUCCESS 0.50s

Logs synthesisENV=cmdhello. deno.Commands is untouched by this change, as intended.


Notes

  • No timeouts — every execution completed in well under a second once the denoland/deno:alpine image was pulled.
  • Topology/artifact scenarios were out of scope: this PR does not add or change a plugin artifact or custom UI.
  • Behavior change worth a reviewer's attention: the new default grants --allow-env --allow-read --allow-write to every deno.Script that does not set permissions. That is what makes the inherited task properties work (and matches every other scripts task), but it does widen the default sandbox compared to 1.9.8.

@jymaire
jymaire requested review from a team, aj-emerich and fdelbrayelle September 2, 2026 15:45

@aj-emerich aj-emerich left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs LGTM

@aj-emerich
aj-emerich self-requested a review September 2, 2026 15:54
@jymaire
jymaire merged commit c4b8d77 into main Sep 3, 2026
9 checks passed
@jymaire
jymaire deleted the fix/410-deno-script-permissions branch September 3, 2026 06:23
@github-project-automation github-project-automation Bot moved this from To review to Done in Pull Requests Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Bash2.0] deno.Script runs deno with no permission flags, so env, inputFiles and outputFiles all fail

3 participants