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