eclipse-zenoh / zenoh

zenoh unifies data in motion, data in-use, data at rest and computations. It carefully blends traditional pub/sub with geo-distributed storages, queries and computations, while retaining a level of time and space efficiency that is well beyond any of the mainstream stacks.
https://zenoh.io
Other
1.36k stars 142 forks source link

Update ACL config format to support AND/OR logic between subjects #1200

Open oteffahi opened 1 week ago

oteffahi commented 1 week ago

This PR reworks the ACL config to support boolean combinations of subjects. An examples of the new config format is the following:

{
  "access_control":
    {
      "enabled": true,
      "default_permission": "deny",

      "rules":
      [
        {
          "id": "allow pub/sub ingress on test/demo",
          "permission": "allow",
          "flows": ["ingress"],
          "actions": [
            "put",
            "declare_subscriber"
          ],
          "key_exprs": [
            "test/demo"
          ]
        },
        {
          "id": "allow get/queryable test/demo ingress/egress",
          "permission": "allow",
          "flows": ["ingress", "egress"],
          "actions": [
            "get",
            "declare_queryable"
          ],
          "key_exprs": [
            "test/demo"
          ]
        },
      ],

      "subjects":
      [
        {
          "id": "client1 or client2 on domain1 through en0/en1",
          "interfaces": [
            "en0",
            "en1",
          ],
          "cert_common_names": [
            "domain1.local"
          ],
          "usernames": [
            "client1name",
            "client2name"
          ]
        },
        {
          "id": "domain2",
          "cert_common_names": [
            "domain2.local"
          ]
        },
        {
          "id": "all interfaces"
          // no fields defined = wildcard (all interfaces)
        }
      ],

      "policy":
      [
        {
          "rules": ["allow pub/sub ingress on test/demo"],
          "subjects": [
            "client1 or client2 on domain1 through en0/en1",
            "domain2"
          ]
        },
        {
          "rules": ["allow get/queryable test/demo ingress/egress"],
          "subjects": [
            "all interfaces",
          ]
        },
      ]
    }
  }

Within each subject, a cartesian product is performed to produce the (interface, cert_common_name, username) combinations. Each combination is a logical AND between its components, and different combinations within the same subject in the subjects list represent a logical OR between them.

Rules are declared seperately, and applied to these subject logical combinations in the policy list. Unique identifiers (id fields) are used to represent the subjects and rules in the policy entries.

oteffahi commented 1 week ago

@Mallets This is ready for review.