Skip to content

Conversation

@elithrar
Copy link
Contributor

@elithrar elithrar commented Dec 24, 2025

This PR adds an allow_tmpdir permission that allows file operations in the system's temporary directory without requiring external_directory approval prompts.

The permission.allow_tmpdir: boolean (defaults to false) and is in both global/merged config and per-agent config/schemas.

specifically:

  • external_directory defaults to "ask", prompting for permission on any file operation outside the current working directory
  • In CI/CD and CLI environments, this prompt causes indefinite hangs (see Opencode Hangs when used as CLI tool #5888)
  • The existing workaround (external_directory: "allow") permits access to ALL external directories, which is overly broad
  • Requiring users to create a custom agent just to allow tmpdir access is high friction

security:

  • Symlink resolution prevents traversal attacks (critical on macOS where /tmp/private/tmp)
  • Default false maintains current security model (opt-in)
  • Only affects tmpdir; other external directories still follow external_directory settings

tests:

  • Filesystem.tmpdir(), isInTmpdir(), containsResolved() utilities tested for symlink resolution and non-existent paths
  • Bash tool tests verify allow_tmpdir: true permits tmpdir workdir while external_directory: deny is set
  • Bash tool tests verify allow_tmpdir: true does not bypass external_directory for non-tmpdir paths

usage example:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "allow_tmpdir": true,
    "external_directory": "ask"
  }
}

Or per-agent:

{
  "agent": {
    "build": {
      "permission": {
        "allow_tmpdir": true
      }
    }
  }
}

related:

@rekram1-node
Copy link
Collaborator

@elithrar do you think is is preferable to something like:

"external_directory": {
  "/tmp*": "allow",
  "*": "deny"
  }

@thdxr has been working on a revamp of our permissions and part of it was making every permission (that makes sense) "glob-able" like this

Other examples for other permissions:

"read": {
  "*.md": "allow",
  "*.env": "deny"
}

@elithrar
Copy link
Contributor Author

TBH I actually like both + tried to leave room for custom permission objects.

thoughts:

  • tmpdir is widely used and isn’t always /tmp/ depending on your OS (yes, users can use {env:var} but extra cognitive burden
  • tmpdir is “safe” - trust opencode to use it as a sandbox (and not follow symlinks, etc)
  • glob-style patterns can be additive - use tmpdir as the sandbox but read-only other dirs or file patterns - with more risk if you get it slightly off / too permissive
  • I otherwise like the { glob, ask | allow | deny } API proposed and feels easy to tackle.

As a user: I want opencode to be able to work within the cwd and use tmpdir as a sandbox.

I do not want it to accidentally (through config) end up having wider access to the rest of my machine. Especially in an enterprise env, but also as a regular privacy conscious user.

@rekram1-node
Copy link
Collaborator

hmm okay good point about the tmpdir differences across different os, I will send this to Dax since he has been thinking about these things lately

@thdxr
Copy link
Contributor

thdxr commented Dec 25, 2025

let me merge my permissions branch (it's close) and i'll look at this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants