On 18 May 2010 14:52, Rajith Attapattu <rajit...@gmail.com> wrote:
>
> Andrew, I have added your proposal and the text you pasted here in
> https://cwiki.apache.org/confluence/display/qpid/andrew+acl+proposal
>
> This page is linked off,
> https://cwiki.apache.org/confluence/display/qpid/ACL+Design
> And the above is linked off the developer pages.
>
> I will get out my proposal a bit later in the week.

Thanks.

For completeness, I have tried to put together another page covering
the recent discussion on the 'METHOD' object and management
operations, the text of which is attached below. Rajith, could you
stick it in another wiki page, please? I think this is a useful
compromise, although there may be some further work required to
straighten out the QMF and JMX bindings anyway...

h1. Method Redux

_"Though this be madness, yet there is method in't."_
*Polonius, Hamlet Act 2, scene 2*

h2. Introduction

The main point of contention in the ACL debate seems to centre around
the mechanism used to permission non AMQP entities, the current
_METHOD_ method is felt to be unsuitable. This document proposes an
update to this syntax and describes exactly how it should be
interpreted across brokers.

h2. Access Control

The things that are being controlled or permissioned by entries in the
access control list are objects that form part of the Qpid broker.
These entities could reasonably be said to be _children_ of the
broker, although I don't feel that a tree-type structure is either
helpful or necessary here, since there is no parallel in the Qpid or
AMQP internals. A flat _object type_ space has therefore been assumed,
continuing current behavior. These types of object have until now
simply represented the major types of object that exist and are
manipulable inside a broker. The only addition is that of the broker
itself, since there are some operations and actions that can only
realistically be said to be performed globally.  This is the rationale
behind such proposed ACL entries as:

{noformat}
ACL ALLOW robot ACCESS LOG
ACL DENY robot UPDATE CONFIG
ACL DENY kitten UPDATE USERS
ACL ALLOW kitten ADMIN LOG
{noformat}

The _LOG_, _CONFIG_ and _USERS_ object types here represent subsystems
or components or simply collections of management methods that perform
a similar set of tasks. They are *not* actual broker objects, although
(see later) they may be QMF classes, with their own management schema
and package.

A different approach to access control for these management methods
relies on the _BROKER_ object type being used for permissioning,
giving rise to ACL entries as follows:

{noformat}
ACL DENY robot ACCESS BROKER
ACL DENY kitten UPDATE BROKER subsystem=logging
ACL ALLOW kitten ACCESS BROKER method=get*
ACL ALLOW kitten ACCESS BROKER method=invoke*
ACL ALLOW kitten MANAGE BROKER subsystem=users
{noformat}

This _BROKER_ object type represents the entire runtime entity, and is
in fact represented in the QMF management schema, with properties,
statistics and methods available. This is not meant to indicate a
preference for QMF as a final reference point, it should be noted,
rather this is illustrative of the sorts of entities an access control
object type could map to.

{noformat}
<class name="Broker">
    <property name="name" />
    <property name="systemRef" />
    <property name="port" />
</class>
{noformat}

h3. Existing Syntax

The previous ACL entries would all be permissioned using the _METHOD_
object type in the current C++ broker, assuming a logical extension of
the existing syntax. The problem with this syntax is that it is very
closely coupled to the management framework, QMF. Also, the
granularity of the controls falls awkwardly between extremes, and
requires too much specificity to enumerate all methods dealing with a
particular area of interest when controlling that type of access, and
not distinguishing between *getName* methods on various different
managed objects. This makes it impossible to correctly permission
access to multiple objects with similarly named methods. Also, since
JMX provides access to properties using a method call, a permission
for that method would need to be created to allow _READ_ access to a
property, which blurs the distiction between methods and properties.

h3. Mechanism versus Meaning

Since the current C++ implementation is based exclusively on QMF, only
features supported and used by QMF are available. It is preferable to
have a mechanism-agnostic access control specification, since QMF and
JMX will not be the only management entry-points for ever, with SNMP
and other industry standards available as well as future JEE
development.  Also, it should be possible to permission access in a
manner that does not depend on the version of the QMF schema or API,
depending only on the existence or not of particular manageable
objects within the broker. This means that when a new method or
attribute is added at an API change, or a method name is changed,
existing ACLS will have the same meaning as before. This semantic
preservation is the aspect of the ACLs that is most important.

The existing object types all relate to the Qpid broker objects, and
the best way to move forward is to maintain that relationship, and
ensure that all operations have the correct meaning and are controlled
correctly in the broker, no matter how they are accessed. This means
that an _ACCESS QUEUE_ ACL entry would entail granting permission to
view the properties of a queue via the QMF console, via a JMX console
utility or the JMX API and by interrogating the queue over JMS or
through the C++ AMQP client.

h3. Operational Constraints

The _ACCESS_ operation is assumed here to map to some kind of
read-only access. Typically in a software management system the
following three types of operation are available:

* *Read* - Access the contents of an attribute, statistic or property.
* *Write* - Set the contents of an attribute or property.
* *Execute* - Call a method or take an action or operation.

It is proposed that the existing operations are maintained, along with
the mappings to object types they are allowed to manipulate (as
described in a previous text) and the three types described above are
mapped as follows:

* _ACCESS_ - *Read*
* _UPDATE_ - *Write*
* _EXECUTE_ - *Execute*

_ACCESS_ continues to describe simple, read-only property or attribute
access, mapping nicely a JMX intent of INFO or a *get* type of
operation. _UPDATE_ would be used for read-write access to properties,
when the operation carried out is a simple change of value with no
side effects. The new _EXECUTE_ operation replaces the contentious
_ADMIN_ or _MANAGE_ described previously, and more accurately
describes the execution or invocation of an administrative action or
operation with a particular effect on the broker.

h3. Brokerage

The _BROKER_ object type is to be used to control access to any new
set of features. For example, if it is desired to add an ACL entry
that will allow the _robots_ group to read and write properties on the
*Acl* QMF managed object, and additionally to execute all methods that
are present, this could be done as follows:

{noformat}
ACL ALLOW robots ACCESS BROKER package="org.apache.qpid.acl"
ACL ALLOW robots UPDATE BROKER package="org.apache.qpid.acl"
ACL ALLOW robots EXECUTE BROKER package="org.apache.qpid.acl"
{noformat}

If a logging subsystem was added, with the QMF management schema
package defined as *org.apache.qpid.log* and methods such as
*setLoggingLevel*, *getAvailableLoggingLevels*, *reloadLogFile*,
*rollLogFile* are defined, along with properties like *currentLevel*
and *lastLogEntryTime* then it could be permissioned this way:

{noformat}
ACL ALLOW robots ACCESS BROKER package="org.apache.qpid.log"
ACL ALLOW robots UPDATE BROKER package="org.apache.qpid.log"
ACL ALLOW kitten EXECUTE BROKER package="org.apache.qpid.log"
method="rollLogFile"
ACL ALLOW robots EXECUTE BROKER package="org.apache.qpid.log"
method="reloadLogFile"
ACL DENY robots EXECUTE BROKER package="org.apache.qpid.log"
{noformat}

In this example, the _robots_ group can only execute *reloadLogFile*
while _kitten_ (a member) can also execute *rollLogFile*, and the
group has read/write access to all properties and statistics. It
should be obvious that there is scope for adding arbitrary new
packages and then permissioning them. Also, if the contents of the
packages are well defined and they are suitably finely grained then it
will mostly suffice to permission at the package level for all
operations and properties. This gives freedom to update APIs and add
new methods without making ACL files obsolete or causing security
issues, since the *meaning* of the ACL entries should be unchanged.

Care will need to be taken with, for example, JMX *invoke* method,
which offers a level of indirection that could enable bypassing access
checks.  This is currently handled at a common JMX entry point, and
should suffice at present.

h3. Syntactic Sugar

In an attempt to divorce the ACL syntax from the mechanism further, it
could also be possible to remove references to the package and use a
different naming scheme, which would have a mapping to QMF, JMX
managed objects and any future management information repository. This
could work as follows, with *users* mapping to the JMX
*UserManagement* MBean and a QMF *org.apache.qpid.users* package with
a *Users* class. The change to the ACL syntax is trivial.
Additionally, changing all properties to simply _name_ would
standardise the syntax further, with only a small loss of readability.

{noformat}
ACL ALLOW kitten EXECUTE BROKER component="users" name="*"
ACL ALLOW kitten UPDATE BROKER component="users" name="fileName"
{noformat}

It is possible that another object could be chosen instead of
_BROKER_, such as _METHOD_ (however this gives the issue of changing
the meaning of existing files) but this would not change the
discussion presented above.  The only issue might be that it is
cumbersome to add a permission granting access to all management
methods, properties and statistics, both read and write, at the same
time. Even though _UPDATE_ will usually include _ACCESS_ permissions,
two lines are needed (for _EXECUTE_ separately) unless it is
satisfactory for _EXECUTE_ to include _UPDATE_ (and hence _ACCESS_)
rights.

{noformat}
ACL DENY robot EXECUTE METHOD component="config" name="reload*"
ACL ALLOW kitten ACCESS METHOD component="config" name="*"
{noformat}

It could be pointed out that _ACCESS METHOD_ ought more correctly to
read _ACCESS PROPERTY_ and similarly for _UPDATE_, however it is felt
that the number of object types should be kept to a minimum, which is
the purpose of this proposal.

h2. Conclusion

The ACL changes described above are fairly simple, but should provide
a sensible and easily extensible syntax that will allow both the Java
and C++ brokers to provide fine grained access control for custom
components that are specific to each implementation without
compromising cross- platform file compatibility. The actual access and
management mechanisms for the brokers do not impact the ACL syntax,
which remains agnostic, and also maintains its meaning through API
upgrades and extensions without compromising platform security.

There are several options for ACL file syntax describing access to
methods controlling a (for example) logging mechanism, which are
summarised below:

* Extra object type created for each set of management methods, with
unique per-object set of properties. This is the least extensible
mechanism.

{noformat}
ACL ALLOW kitten EXECUTE LOG
{noformat}

* Specify all method names to be permissioned as in the current C++
broker implementation, using _METHOD_ as the object type. This does
not allow property access to be permissioned or prevent name clashes
in different managed object classes.

{noformat}
ACL ALLOW kitten UPDATE METHOD name="methodNameOne"
ACL ALLOW kitten UPDATE METHOD name="methodNameTwo"
{noformat}

* Use _BROKER_ or _METHOD_ object type and specify the component or
subsystem by an arbitrary name, with the option to specify down to
individual methods by adding a wildcarded name pattern. Using _METHOD_
in this way is close to the current C++ syntax. Alternatively, the QMF
package name could be used to identify the component. Different
operations are used to describe access to properties or attributes.

{noformat}
ACL ALLOW kitten EXECUTE BROKER subsystem=logging
ACL ALLOW kitten EXECUTE BROKER package="org.apache.qpid.log"
{noformat}

{noformat}
ACL ALLOW kitten EXECUTE METHOD component="log" name="reload*"
ACL ALLOW kitten UPDATE METHOD component="log"
ACL ALLOW robot ACCESS METHOD component="log"
ACL ALLOW robot EXECUTE METHOD component="acl" name="reload*"
ACL DENY robot EXECUTE METHOD component="config" name="reload*"
ACL ALLOW robot EXECUTE METHOD component="config"
{noformat}

The last described syntax is close to a preferred option, and
incorporates features from recent *dev.qpid.apache.org* discussion,
although any updates or suggestions are welcome.

(*Note* this has the interesting/useful feature/bug of falling back to
C++ broker syntax if the _component_ property is omitted. This would
be legal in the Java broker, just not recommended due to the name
clashes.)

Andrew D Kennedy, _andrew.internatio...@gmail.com_, 2010-05-19

adk
-- 
-- andrew d kennedy ? edinburgh : +44 7941 197 134

---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:dev-subscr...@qpid.apache.org

Reply via email to