#8855 · @robertfall · opened Jan 16, 2026 at 9:57 AM UTC · last updated Mar 21, 2026 at 10:47 AM UTC
feat(webfetch): Allow granular URL permissions
Score breakdown
Impact
Clarity
Urgency
Ease Of Review
Guidelines
Readiness
Size
Trust
Traction
Summary
This PR introduces granular URL permission rules for the webfetch tool, significantly enhancing security by allowing specific allow/block patterns. It expands existing permission configuration and includes dedicated tests for the new functionality.
Description
Summary
- allow granular URL permission rules for webfetch
- expand permission patterns to include protocol/host/path variants
- add tests for config + webfetch patterns
Testing
- bun test ./test/tool/webfetch.test.ts ./test/permission/next.test.ts ./test/config/config.test.ts
Issue
- Fixes #7445
Linked Issues
#7445 [FEATURE]: webfetch allowed/blocked URLs
View issueComments
PR comments
wolffberg
Would it make sense to add the rules to the context so the LLM doesn't have to bruteforce fetches?
robertfall
Done. Another look?
wolffberg
LGTM 🎉
wolffberg
I just did a few more tests. Can you elaborate on how the permissions should work if you want to allow only specific URLs?
Say I want to allow github.com but block everything else, how can this be achieved?
robertfall
Say I want to allow
github.combut block everything else, how can this be achieved?
If I understand the rules engine correctly, this should be:
{
"permissions": {
"webfetch": {
"*": "deny",
"github.com": "allow"
}
}
}
I've added tests here. I hope I've understood everything.
wolffberg
I can't get it to work. I tested the following:
webfetch tool is not available at all
{ "permission": { "webfetch": { "github.com": "allow", "*": "deny" } } }
no URL's work
{ "permission": { "webfetch": { "*": "deny", "github.com": "allow" } } }
all URL's work
{ "permission": { "webfetch": { "github.com": "allow" } } }
Could it be model specific? I'm only testing with the free models available by default.
robertfall
I can't get it to work. I tested the following:
What does not working look like? The tool is completely ignored?
I've only been driving it from the tests... I'll figure out how to run it locally.
wolffberg
Yes, all the models I try do not list the webfetch tool as available at all.
If you have Docker installed you can test by:
- Check out your branch locally and
cdto the root of the repo - Run
docker run --rm -it -v $(pwd):/home/bun/app oven/bun bash - Add a working config file to
~/.config/opencode/opencode.json - Run
bun install && bun dev
robertfall
@wolffberg I've fixed this. I had misunderstood the permissions system.
This simplifies the feature and uses only the existing globbing from permissions.
Worth noting that if "deny": "*" is the last rule for a tool, the tool is disabled. This seems to be the current pattern. eg.
{
"permission": {
"webfetch": {
"github.com": "allow",
"*": "deny"
}
}
}
I have this working with the following config now:
"webfetch": {
"*": "ask",
"*://github.com*": "allow"
},
Because of the simplified globbing we need a * for protocol if we want to support all protocols. The ask command currently adds the *://${host}* when always is chosen.
I think trying to be too smart here means this gets complex quickly. This approach is backwards compatible and allows users to allow specific URLs using globbing with ask and deny available.
w0rp
I would love to see a tested and working version of this! I will watch the PR. This is a very useful security feature to have, which has an equivalent in Claude Code.
robertfall
@w0rp this PR has tests, but has been pretty much ignored since being opened. I'm not sure how to get attention on it and I stopped trying to get it picket up and over the line because there has genuinely been no movement on it in months.
Changed Files
packages/opencode/src/config/config.ts
+1−1packages/opencode/src/session/prompt.ts
+12−1packages/opencode/src/tool/webfetch.ts
+2−1packages/opencode/test/config/config.test.ts
+29−0packages/opencode/test/permission/next.test.ts
+30−0packages/opencode/test/tool/webfetch.test.ts
+131−0packages/sdk/openapi.json
+1−1