[ 
https://issues.apache.org/jira/browse/MESOS-3557?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14939659#comment-14939659
 ] 

James Fisher commented on MESOS-3557:
-------------------------------------

I felt that the current documentation for the ACL file was really hard to 
understand, so I've written it more formally, as follows. There's a FIXME for 
the ambiguity above. Of course, the below might be wrong; I'm working from a 
close reading of the current documentation and reasonable guessing.

{code}
You start Mesos with an ACL expression. The concrete syntax for the
ACL file is JSON. The schema for this is:

```
ACL ::=
  {
    "permissive": Bool,                                    // can be omitted 
and defaults to true
    "run_tasks": [RunTasksPredicate],                      // can be omitted 
and defaults to []
    "register_frameworks": [RegisterFrameworksPredicate],  // can be omitted 
and defaults to []
    "shutdown_frameworks": [ShutdownFrameworksPredicate]   // can be omitted 
and defaults to []
  }

RunTasksPredicate ::=
  {
    "principals": StringPredicate,
    "users": StringPredicate
  }

RegisterFrameworksPredicate ::=
  {
    "principals": StringPredicate,
    "roles": StringPredicate
  }

ShutdownFrameworksPredicate ::=
  {
    "principals": StringPredicate,
    "framework_principals": StringPredicate
  }

StringPredicate ::=
    { "type": "ANY" }
  | { "type": "NONE" }
  | { "values": [String] }
```

The `Predicate` syntax forms denote predicates in a "three-valued
logic", where the predicates either

1. accept their arguments, or
2. reject their arguments, or
3. do not match their arguments.

A `StringPredicate` denotes a predicate over strings, defined like so:

* The string predicate `{"type": "ANY"}` accepts all strings.

* The string predicate `{"type": "NONE"}` rejects all strings.

* A string predicate `{"values": [S1, S2, ..., SN]}` accepts the
  strings `S1` `S2,` ... `SN`, and does not match any other
  strings.

  For example, the expression `{"values": ["foo", "bar"]}` accepts the
  string `"bar"`, and does not match the string `"baz"`.

The other three predicate forms (`RunTasksPredicate`,
`RegisterFrameworksPredicate`, and `ShutdownFrameworksPredicate`) are
predicates over pairs of strings. They all work similarly, so we
illustrate with just the `RunTasksPredicate`.

A `RunTasksPredicate` of the form `{ "principals": P, "users": U }` is
a predicate over pairs of strings `(p,u)`, defined like so:

1. If `P` does not match `p`, or `U` does not match `u`, then `{ "principals": 
P, "users": U }` does not match `(p,u)`.

   For example,
   
       {
         "principals": {"type": "ANY"},
         "users": {"values": ["bob"]}
       }
   
   does not match `("admin","sue")`, because `{"values": ["bob"]}`
   does not match `"sue"`.

2. If `P` accepts `p` and `U` accepts `u`, then `{ "principals": P, "users": U 
}` accepts `(p,u)`.

   For example,

       {
         "principals": {"values": ["foo", "bar"]},
         "users": {"type": "ANY"}
       }
       
   accepts `("bar","jane")`, because `{"values": ["foo", "bar"]}`
   accepts `"bar"` and `{"type": "ANY"} }` accepts `"jane"`.

3. Otherwise, `{ "principals": P, "users": U }` rejects `(p,u)`.

   For example,

       {
         "principals": {"values": ["foo", "bar"]},
         "users": {"type": "NONE"}
       }

   rejects `("bar", "root")` because `{"values": ["foo", "bar"]}`
   accepts `"bar"`, and `{"type": "NONE"}` rejects `"root"`.

   FIXME: there is an ambiguity in my mind over what is supposed to
   happen if `P` rejects `p` *and* `U` rejects `u`, That is, I don't
   know what the following expression denotes: `{ "principals":
   {"type": "NONE"}, "users": {"type": "NONE"} }`. The corresponding
   English sentence, "no one can do nothing", is nonsense.
   
An array of `RunTasksPredicate` expressions also denotes a predicate
over pairs of strings `(p,u)`. It has the value of the first element
which matches `(p,u)`; or if there is no such element then it does not
match `(p,u)`. Some examples:

* The expression `[]` does not match `("foo","root")`.

* The expression

  [
    { "principals": {"type": "ANY"}, "users": {"values": ["bob"]} },
    { "principals": {"values": ["foo", "bar"]}, "users": {"type": "NONE"} }
  ]

  accepts `("foo","bob")`, rejects `("foo","root")`, and does not
  match `("baz","root")`.

An ACL expression `{"permissive": B, "run_tasks": RT,
"register_frameworks": RF, "shutdown_frameworks": SF}` denotes three
predicates in ordinary two-valued logic:

* `PrincipalCanRegisterFrameworkWithRole(Principal,Role)`.
* `PrincipalCanRunTasksAsUser(Principal,User)`.
* `PrincipalCanShutdownFrameworkWithPrincipal(User,Principal)`.

The value for `"permissive"` defines, for each of the three
predicates, how to convert from three-valued logic to an ordinary
boolean: non-matches are converted to the value `B`.

For example, the ACL expression

    {
      "permissive": false,
      "run_tasks": [
        { "principals": {"type": "ANY"}, "users": {"values": ["bob"]} },
        { "principals": {"values": ["foo", "bar"]}, "users": {"type": "NONE"} }
      ]
    }

rejects `("baz","root")`, because the `"run_tasks"` predicate does not
match `("baz","root")`.

The ACL expression passed to Mesos on start-up is used by Mesos like
so:

* When a framework/scheduler requests to register, it passes a
  principal `P` and role `R`, and Mesos permits the registration iff
  `PrincipalCanRegisterFrameworkWithRole(P,R)`.

* When a framework/scheduler previously registered with principal `P`
  requests to run a task as user `U`, Mesos permits it iff
  `PrincipalCanRunTasksAsUser(P,U)`.

* When someone authenticating with principal `P1` tries to shutdown a
  framework/scheduler which is registered with principal `P2`, Mesos
  permits it iff `PrincipalCanShutdownFrameworkWithPrincipal(P1,P2)`.
{code}

> Interpretation of { "type": "NONE" } in access control lists
> ------------------------------------------------------------
>
>                 Key: MESOS-3557
>                 URL: https://issues.apache.org/jira/browse/MESOS-3557
>             Project: Mesos
>          Issue Type: Documentation
>            Reporter: James Fisher
>
> I am trying to understand the documentation for the authentication system. 
> The interpretation of the
>     { "type": "NONE" }
> string predicate is strange. In particular I want to know what the 
> interpretation of the following ACL should be:
> {code}
>      {
>        "run_tasks": [
>                       {
>                         "principals": { "type": "NONE" },
>                         "users": { "type": "NONE" }
>                       }
>                     ]
>      }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to