Skip to content

How are permissions applied in order? #16157

@mprasil

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)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions