Welcome to the third lesson of "Customizing OpenCode for Your Projects." In the previous lessons, we taught OpenCode how to write code (standards) and what to look at (context). Now, we need to decide what it is allowed to do — a topic touched on briefly in the previous course that we will now explore in much more detail. This brings us to a common problem we call the "Permission Paradox."
Many new users feel nervous about an AI agent changing their files, so they try to lock it down completely. They block the agent from editing files, running commands, or installing packages. However, this creates a paradox: by trying to make the agent "safe," you make it useless. If you have to manually approve every single character the agent types, you are not saving any time.
In this lesson, we will shift your mindset from "restricting" the agent to "supervising" it. Our goal is to give OpenCode maximum autonomy to do its job while ensuring you have visibility into significant actions before they happen. We want the agent to work fast, but we also want it to pause and ask for confirmation before doing anything drastic.
OpenCode manages its actions using a simple permission system. Every time the agent tries to perform a task — like reading a file, running a terminal command, or writing new code — it checks a set of rules to see if it is allowed to proceed. These rules fall into three distinct categories.
The first level is Allow. When an action is set to allow, the agent executes it immediately without interrupting you. This is the "green light." You want most daily operations — like reading files or making small edits — to fall into this category so the agent can work quickly.
The second level is Ask. This is the "yellow light." When the agent tries an action in this category, it pauses and shows you exactly what it wants to do. It waits for you to type y (yes) or n (no). This gives you a chance to review the action before it happens. This is perfect for high-impact actions where you want final approval.
The third level is Deny. This is the "red light." If an action is denied, the agent is strictly blocked from doing it, and it will likely report an error saying it cannot complete the task. As we will discuss later, you will rarely use this level because it often breaks the agent's ability to solve problems creatively.
To configure these permissions, we edit the opencode.json file in the root of your project. This is a configuration file similar to the ones we used in previous lessons. We use the "permission" key (note the singular form) to define how each tool type should behave.
OpenCode's permission system covers several tool categories. The most commonly configured ones are read, edit, bash, and webfetch. Beyond those, two special safety guards — doom_loop (which prevents infinite agent loops) and external_directory (which controls access to paths outside your working directory) — default to "ask" automatically. You can also configure access to skill files. Think about what each core tool does. Reading a file never modifies anything, so it is always safe to auto-approve. The edit permission covers all file modification operations — creating new files, editing existing ones, applying patches — and in most projects you can trust the agent to handle these confidently. The bash tool, however, is the most powerful — it can run any shell command, including destructive ones — so it deserves more careful supervision.
Here is an example opencode.json file configured for maximum autonomy, with kept under your watch:
While we want the agent to be fast, we do not want it to be reckless. Some actions are destructive or hard to reverse, like deleting files or pushing code to a remote server. For these situations, the "ask" permission creates a "checkpoint" where you must verify the action before it proceeds.
The most powerful checkpoint you can set is on the bash tool. A single bash command can do almost anything on your system, from running tests to dropping a database. By setting bash to "ask", you ensure that no shell command runs without your explicit approval — and the agent will show you exactly what it intends to run before it executes.
If you work in a context where you also want to review every file write or edit — for example, on a production codebase where even small changes carry risk — you can set those tools to "ask" as well:
Code:
Output when the agent tries to run a shell command:
Notice the output above. Because bash was set to "ask", the agent paused before executing the remove command. It shows you exactly what it intends to run, giving you the opportunity to confirm or reject it before anything is deleted.
You might be tempted to set certain tools to "deny" to be extra safe, but this is usually a mistake. If you strictly deny a tool, the agent hits a wall. If the agent hits a wall, it cannot complete the task, and you have to take over manually.
For example, imagine you ask the agent to "Clean up the temporary files in this folder." If you have denied the bash tool, the agent cannot run any shell commands. It will tell you it cannot proceed because it lacks the permissions to use the terminal. You then have to do the work yourself.
However, if you set bash to "ask", the agent will say, "I want to run this command to remove those temporary files. Is that okay?" You can say yes, and the job is done. The "ask" permission gives you the same safety as "deny" (because nothing happens without your say-so), but it keeps the agent useful and helpful.
As you work with OpenCode, you might forget which rules are currently active. The most reliable way to review your permission strategy is to open your opencode.json file directly. The "permission" block is human-readable, so a quick glance tells you exactly what is allowed, what requires confirmation, and what is blocked.
Beyond reviewing the config file, OpenCode itself keeps you informed during a session. Every time the agent hits an "ask" checkpoint, the prompt appears directly in the chat window, giving you a live record of significant actions. If you want a history of what the agent did during a long task, you can scroll up through the conversation to see each approval request and how you responded.
This approach also doubles as an informal audit trail. If something unexpected happened — a file was modified or a command was run — you can trace it back through the conversation to understand exactly what the agent did and when.
In this lesson, we established a philosophy for agent permissions: Maximum Autonomy with Visibility. We learned that the Ask permission is much more powerful than Deny because it keeps the agent capable while keeping you in control. We also looked at how to configure the opencode.json file to auto-approve safe tasks like reading and editing files, while flagging shell commands for your review.
Key Takeaways:
- Allow the basics: Let the agent read and edit files without nagging you.
- Ask for risks: Force a pause before running any bash command.
- Avoid Deny: Don't break the agent's tools; just supervise them.
- Audit: Review your
opencode.jsonand scroll through the chat history to track what the agent did.
In the upcoming practice exercises, you will create an opencode.json file from scratch. You will configure the agent to auto-approve file reads but require permission for bash commands, and then test these rules to see the difference between a silent success and a helpful prompt.
