Welcome to the advanced course! As you scale up your projects with OpenCode, thoughtfully managing what the AI can do becomes critical. You probably remember the three basic permission levels from your earlier work: allow (AI acts freely), ask (AI requires your approval), and deny (AI is completely blocked).
In this lesson, we are moving beyond those basics. We will explore how to make smart permission choices using a systematic risk assessment framework. We will also learn advanced pattern matching, understand how to resolve priority conflicts when rules overlap, and look at how to properly structure your permission rules in opencode.json. Let's dive in and secure your OpenCode environment!
Before writing permission rules, you need a way to decide which actions get which permissions. Risk Assessment is a systematic way to evaluate how dangerous a specific command or action might be. This matters because giving OpenCode too much freedom can lead to accidents, while too many restrictions will constantly interrupt and slow down your work.
We evaluate actions on two main requirements: Reversibility (can the action be easily undone?) and Blast Radius (how much damage can the action cause?).
Once you understand the risk, you can map it directly to a permission level. Low-risk operations have high reversibility and a low blast radius, so they get an allow permission. Medium-risk operations have a moderate impact on either axis, requiring supervision with an ask permission. Finally, high-risk operations have low reversibility or a massive blast radius, demanding a strict deny permission.
Let's look at how this applies to real terminal commands you might run.
In this configuration, checking the git status is allowed because it simply reads data. It is fully reversible and has zero blast radius, meaning it cannot break anything.
On the other hand, the recursive remove command forcefully deletes files without a backup. This action has zero reversibility and a huge blast radius, so it gets a strict deny. When in doubt, you should always default to the ask permission so you can supervise the action safely.
To apply these risk rules effectively, you need to use Advanced Pattern Syntax. This is a special way of writing rules so they apply to groups of files or specific parts of a command. This matters because you cannot list every single file or command individually; you need flexible rules that grow with your project.
The two wildcards available are the asterisk (*), which matches any sequence of characters, and the question mark (?), which matches exactly one character.
The first line uses an asterisk to allow editing any Python file. The second line uses the ? wildcard to specifically require confirmation before editing test files with exactly one character in their identifier, like test_a.py or test_1.py. Any longer name, such as test_ab.py, would not be matched by the ? pattern.
We can also use syntax to limit network access and command-line actions.
Here, setting webfetch to ask requires confirmation before the AI fetches any web resource, adding a layer of security against untrusted websites. The bash tool specifies git commit*, which requires confirmation for the git commit command along with any extra flags or arguments added to it.
When you write many permission rules, they will often overlap and create a Priority Conflict. A priority conflict happens when one rule says an action is allowed, but another broader rule says it is denied or requires asking. This matters because you need to know exactly how OpenCode will behave when two rules clash.
The core rule OpenCode follows is simple: the last matching rule wins. This means you should always write your broad catch-all rules first, and your more specific rules after them, so the specific ones take effect.
A quick way to internalize this is to compare overlapping rules side by side, paying attention to their order:
OpenCode stores all permission rules in opencode.json. Understanding this format is important because you need to know how to correctly read and write permission rules in your projects.
The opencode.json file groups rules under a permission key, organized by the specific tool. For bash and edit, the command or file pattern is the key and the permission level is the value inside an object. For webfetch, the value is a single permission string directly.
Inside the bash section, the catch-all "*" rule is placed first so it applies as the default, and more specific rules are listed after it so they take effect last and win when they match. You can add as many tools as needed, each with their own set of pattern rules, keeping all your permissions organized in a single file.
Even with careful planning, you might encounter Permission Misconfigurations, where OpenCode behaves unexpectedly. Debugging these setups matters because a broken rule could either block you from getting work done or accidentally expose sensitive files.
There are three common mistakes to watch out for:
- Creating overlapping rules where you accidentally
denyan action you meant toallow. - Forgetting to include a catch-all baseline rule, leaving your system too open.
- Making simple syntax errors, like forgetting a required asterisk in a command.
The best way to debug is to actively test your configuration in the OpenCode terminal. Suppose you just fixed a conflict where docker build was accidentally allowed, and you want to verify it now asks for permission.
Seeing the prompt above proves your ask permission is correctly catching the docker build command. You should also try checking your git status to ensure it runs silently (verifying allow), and attempt to edit your .env file to ensure OpenCode completely blocks the action (verifying deny). Testing these three boundaries ensures your environment is secure and ready.
Great job! You have just mastered advanced permission strategies for OpenCode. We covered how to evaluate actions using Reversibility and Blast Radius to apply the correct risk levels. You learned how to use the two wildcard characters — * for any sequence of characters and ? for a single character — to write precise pattern rules, and how OpenCode resolves conflicts by applying the last matching rule, which is why catch-all rules should always be written first and specific rules after them. We also explored how to structure your permission rules in opencode.json.
In the upcoming hands-on exercises, you will jump into the CodeSignal IDE to inspect configurations and fix overlapping priority conflicts yourself. You will verify your fixes by testing commands like git status, running Docker builds, and ensuring secret .env files remain strictly protected. Let's head over to the practice environment!
