Skip to content

How are permissions applied in order? #16157

Closed

Description

@mprasil

Question

I'm phrasing this as asking question, but I feel like there are some bugs lurking in how all this works.

The documentation says last matching rule winning but the rules are defined as set of key/value pairs. My understanding is that this recently changed from specificity-based matching to order based matching and the motivation was to make it more intuitive and natural. This IMO creates quite a bit of ambiguity and edge cases that are not intuitive at all:

Ordering

AFAIK order of keys in JSON is not guaranteed and many tools don't preserve it. (for example home-manager configuration would not)

This seems to be problematic for both configuration creation, but also when inspecting the config by user as some user friendly tools do not show the JSON keys in order they are written.

Semantically this is also a bit misleading as the object does not clearly communicate the fact that order matters.

Agents

Agent permissions are merged with the global config, and agent rules take precedence

How is ordering preserved here? If my main config specifies:

  bash:
    "*": allow
    "rm*": deny

but agent has:

  bash:
    "*": allow
    "git commit*": deny

What is the order of these rules after they are merged? From what I can tell from the code, this would allow rm* command because the rules seem to be appended rather than merged as docs suggest.

Actual internal logic seems to use array anyways

I had only cursory glance through the permissions code and to me (correct me if I'm wrong here) it seems like we're working with permissions as array anyways. This creates disconnection between how configuration looks like, what docs say and how it actually works.

What if we just used array in config?

To me the most natural way to handle permissions would be to configure it as array:

permission:
  - action: bash
    pattern: *
    rule: ask
  - action: bash
    pattern: rm*
    rule: deny

or the granular format:

permissions:
  - action: bash
  - rules:
      - pattern: *
        rule: ask
      - pattern: rm*
        rule: deny

And then specify in docs that rules are appended in this order: [defaults, global config, agent config]
This is pretty much how things work right now.

As it is user just has no good control over the ordering nor does the configuration format allow for intuitively understanding this. On top of that the documentation fights uphill battle because some terms have different meaning in certain contexts. (for example merged configuration comes with different expectation when merging objects vs merging arrays)

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Mar 5, 2026
  2. github-actions commented on Mar 5, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

  3. mindplay-dk commented on Apr 3, 2026

    @mindplay-dk

    The security model doesn't work. It never has.

    No one comments on these issues.

    I'm not sure anyone knows how this was supposed to work. The code is probably all slop at this point. 😐

  4. mindplay-dk commented on Apr 3, 2026

    @mindplay-dk

    Huh... TIL

    https://www.stefanjudis.com/today-i-learned/property-order-is-predictable-in-javascript-objects-since-es2015/

    I had no idea this was a thing.

    So apparently the documentation is just very bad.

    I need to test more, but from what I can gather, the order does matter, and the rule appears to be just "the last matching rule wins".

    Very, very confusing. 😐

    But looks like it might be a case of documentation slop rather than code slop?

  5. asuffield commented on Apr 18, 2026

    @asuffield
    Contributor

    It's not the documentation, it is indeed broken. You'll see the problem if multiple different config files include a sub-object, like "bash": {....}

  6. tsharks commented on Apr 23, 2026

    @tsharks

    If the documentation explains indeed how it is expected to work, then, yes there is an issue as it is inappropriate to talk about order of keys in JSON. This is not a matter of what library is used behind to parse the JSON. If the file extension is .json, it is just reasonable for people to assume that the JSON spec is respected.

    I agree arrays of rules would be correct.

    The handling of multiple config files is another problem.

  7. assigned and unassigned on Apr 26, 2026
  8. removed
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions