blob: 7f25d15406ece1c8e45fd21ee840128ae93abfc9 [file] [log] [blame]
<div class="docbook"><div class="navheader"><table summary="Navigation header" width="100%"><tr><th align="center" colspan="3">8.3.&#160;Access Control Providers</th></tr><tr><td align="left" width="20%"><a accesskey="p" href="Java-Broker-Security-Group-Providers.html">Prev</a>&#160;</td><th align="center" width="60%">Chapter&#160;8.&#160;Security</th><td align="right" width="20%">&#160;<a accesskey="n" href="Java-Broker-Security-Configuration-Encryption.html">Next</a></td></tr></table><hr /></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="Java-Broker-Security-AccessControlProviders"></a>8.3.&#160;Access Control Providers</h2></div></div></div><p>
The Access Control Provider governs the actions that a user may perform.
</p><p>There are two points within the hierarchy that enforce access control: the Broker itself and at each Virtual
Host. When an access decision needs to be made, the nearest control point configured with a provider is consulted
for a decision. The example, when making a decision about the ability to say, consume from, a Queue, if the
Virtual Host is configured with Access Control Provider it is consulted. Unless a decision is made, the decision
is delegated to the Access Control Provider configured at the Broker.
</p><p>Access Control Providers are configured with a list of ACL rules. The rules determine to which objects
the user has access and what actions the user may perform on those objects. Rules are ordered and are considered
top to bottom. The first matching rule makes the access decision.
</p><p>
ACL rules may be written in terms of user or group names. A rule written in terms of a group name applies to the
user if he is a member of that group. Groups information is obtained from the
<a class="link" href="Java-Broker-Security.html#Java-Broker-Security-Authentication-Providers" title="8.1.&#160;Authentication Providers">Authentication Providers</a>
and
<a class="link" href="Java-Broker-Security-Group-Providers.html" title="8.2.&#160;Group Providers">Group Providers</a>. Writing ACL in terms of groups is
recommended.
</p><p>
The Access Control Providers can be configured using
<a class="link" href="Java-Broker-Management-Channel-REST-API.html" title="6.3.&#160;REST API">REST Management interfaces</a>
and <a class="link" href="Java-Broker-Management-Channel-Web-Console.html" title="6.2.&#160;Web Management Console">Web Management Console</a>.
</p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="Java-Broker-Security-AccessControlProviders-Types"></a>8.3.1.&#160;Types</h3></div></div></div><p>There are currently two types of Access Control Provider implementing ACL rules.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><span class="emphasis"><em>RulesBased</em></span> - a provider that stores the rules-set within
the Broker's or VirtualHost's configuration. When used with HA, the Virtualhost
rules automatically propagated to all nodes participating within the HA group.</p></li><li class="listitem"><p>
</p><p><span class="emphasis"><em>ACLFile</em></span> - an older provider that references an externally provided
ACL file (or data url). This provider is deprecated.</p><p>
</p></li></ul></div><p>
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="Java-Broker-Security-AccessControlProviders-ACLRules"></a>8.3.2.&#160;
ACL Rules
</h3></div></div></div><p>
An ACL rule-set is an ordered list of ACL rules.</p><p>An ACL rule comprises matching criteria that determines if a rule applies to a situation and a decision
outcome. The rule produces an outcome only if the all matching criteria are satisfied.
</p><p>Matching criteria is composed of an ACL object type (e.g. <code class="literal">QUEUE</code>), an ACL action
(e.g. <code class="literal">UPDATE</code>) and other properties that further refine if a match is made. These properties
restrict the match based on additional criteria such as name or IP address. ACL Object type <code class="literal">ALL</code>
matches any object. Likewise ACL Action <code class="literal">ALL</code> matches any action.
</p><p>Let's look at some examples.</p><pre class="programlisting">
ACL ALLOW alice CREATE QUEUE # Grants alice permission to create all queues.
ACL DENY bob CREATE QUEUE name="myqueue" # Denies bob permission to create a queue called "myqueue"
</pre><p>
As discussed, the ACL rule-set is considered in order with the first matching rule taking precedence over all those
that follow. In the following example, if the user bob tries to create an exchange "myexch", the action
will be allowed by the first rule. The second rule will never be considered.
</p><pre class="programlisting">
ACL ALLOW bob ALL EXCHANGE
ACL DENY bob CREATE EXCHANGE name="myexch" # Dead rule
</pre><p>
If the desire is to allow bob to create all exchanges except "myexch", order of the rules must be reversed:
</p><pre class="programlisting">
ACL DENY bob CREATE EXCHANGE name="myexch"
ACL ALLOW bob ALL EXCHANGE
</pre><p>
If a rule-set fails to make a decision, the result is configurable. By default, the <code class="literal">RuleBased</code>
provider defers the decision allowing another provider further up the hierarchy to make a decision (i.e. allowing
the VirtualHost control point to delegate to the Broker). In the case of the ACLFile provider, by default, its
rule-set implicit have a rule denying all operations to all users. It is as if the rule-set ends with
<code class="literal">ACL DENY ALL ALL</code>. If no access control provider makes a decision the default is to
deny the action.
</p><p>
When writing a new ACL, a useful approach is to begin with an rule-set containing only
</p><pre class="programlisting">ACL DENY-LOG ALL ALL</pre><p> at the Broker control point which will cause the Broker to
deny all operations with details of the denial logged. Build up the ACL rule by rule, gradually working through
the use-cases of your system. Once the ACL is complete, consider switching the DENY-LOG actions to DENY.
</p><p>
ACL rules are very powerful: it is possible to write very granular rules specifying many broker objects and their
properties. Most projects probably won't need this degree of flexibility. A reasonable approach is to choose to apply permissions
at a certain level of abstractions and apply them consistently across the whole system.
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="Java-Broker-Security-AccessControlProviders-Syntax"></a>8.3.3.&#160;
Syntax
</h3></div></div></div><p>
ACL rules follow this syntax:
</p><pre class="programlisting">
ACL {permission} {&lt;group-name&gt;|&lt;user-name&gt;|ALL} {action|ALL} [object|ALL] [property="&lt;property-value&gt;"]
</pre><p>
Comments may be introduced with the hash (#) character and are ignored. Long lines can be broken with the slash (\) character.
</p><pre class="programlisting">
# A comment
ACL ALLOW admin CREATE ALL # Also a comment
ACL DENY guest \
ALL ALL # A broken line
</pre></div><div class="table"><a id="table-Java-Broker-Security-AccessControlProviders-Syntax_permissions"></a><p class="title"><strong>Table&#160;8.1.&#160;List of ACL permission</strong></p><div class="table-contents"><table border="1" summary="List of ACL permission"><colgroup><col /><col /></colgroup><tbody><tr><td><span class="command"><strong>ALLOW</strong></span></td><td><p>Allow the action</p></td></tr><tr><td><span class="command"><strong>ALLOW-LOG</strong></span></td><td><p> Allow the action and log the action in the log </p></td></tr><tr><td><span class="command"><strong>DENY</strong></span></td><td><p> Deny the action</p></td></tr><tr><td><span class="command"><strong>DENY-LOG</strong></span></td><td><p> Deny the action and log the action in the log</p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table"><a id="table-Java-Broker-Security-AccessControlProviders-Syntax_actions"></a><p class="title"><strong>Table&#160;8.2.&#160;List of ACL actions</strong></p><div class="table-contents"><table border="1" summary="List of ACL actions"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th><p>Action</p></th><th><p>Description</p></th><th><p>Supported object types</p></th><th><p>Supported properties</p></th></tr></thead><tbody><tr><td> <span class="command"><strong>CONSUME</strong></span> </td><td> <p> Applied when subscriptions are created </p> </td><td><p>QUEUE</p></td><td><p>name, autodelete, temporary, durable, exclusive, alternate, owner, virtualhost_name</p></td></tr><tr><td> <span class="command"><strong>PUBLISH</strong></span> </td><td> <p> Applied on a per message basis on publish message transfers</p> </td><td><p>EXCHANGE</p></td><td><p>name, routingkey, virtualhost_name</p></td></tr><tr><td> <span class="command"><strong>CREATE</strong></span> </td><td> <p> Applied when an object is created, such as bindings, queues, exchanges</p> </td><td><p>VIRTUALHOSTNODE, VIRTUALHOST, EXCHANGE, QUEUE, USER, GROUP</p></td><td><p>see properties on the corresponding object type</p></td></tr><tr><td> <span class="command"><strong>ACCESS</strong></span> </td><td> <p> Applied when a connection is made for messaging or management</p> </td><td><p>VIRTUALHOST, MANAGEMENT</p></td><td><p>name (for VIRTUALHOST only)</p></td></tr><tr><td> <span class="command"><strong>BIND</strong></span> </td><td> <p> Applied when queues are bound to exchanges</p> </td><td><p>EXCHANGE</p></td><td><p>name, routingKey, queue_name, virtualhost_name, temporary, durable</p></td></tr><tr><td> <span class="command"><strong>UNBIND</strong></span> </td><td> <p> Applied when queues are unbound from exchanges</p> </td><td><p>EXCHANGE</p></td><td><p>name, routingKey, queue_name, virtualhost_name, temporary, durable</p></td></tr><tr><td> <span class="command"><strong>DELETE</strong></span> </td><td> <p> Applied when objects are deleted </p> </td><td><p>VIRTUALHOSTNODE, VIRTUALHOST, EXCHANGE, QUEUE, USER, GROUP</p></td><td><p>see properties on the corresponding object type</p></td></tr><tr><td> <span class="command"><strong>PURGE</strong></span> </td><td>
<p>Applied when the contents of a queue is purged</p> </td><td><p>QUEUE</p></td><td><p> </p></td></tr><tr><td> <span class="command"><strong>UPDATE</strong></span> </td><td> <p> Applied when an object is updated </p> </td><td><p>VIRTUALHOSTNODE, VIRTUALHOST, EXCHANGE, QUEUE, USER, GROUP</p></td><td><p>see EXCHANGE and QUEUE properties</p></td></tr><tr><td> <span class="command"><strong>CONFIGURE</strong></span> </td><td> <p> Applied when a Broker/Port/Authentication Provider/Access Control Provider/BrokerLogger is created/update/deleted.</p> </td><td><p>BROKER</p></td><td><p> </p></td></tr><tr><td><span class="command"><strong>ACCESS_LOGS</strong></span> </td><td><p>Allows/denies the specific user to download log file(s).</p> </td><td><p>BROKER, VIRTUALHOST</p></td><td><p>name (for VIRTUALHOST only)</p></td></tr><tr><td><span class="command"><strong>SHUTDOWN</strong></span> </td><td><p>Allows/denies the specific user to shutdown the Broker.</p> </td><td><p>BROKER</p></td><td><p /></td></tr><tr><td><span class="command"><strong>INVOKE</strong></span> </td><td><p>Allows/denies the specific user to invoke the named operation.</p> </td><td><p>BROKER, VIRTUALHOSTNODE, VIRTUALHOST, EXCHANGE, QUEUE, USER, GROUP</p></td><td><p>method_name, name and virtualhost_name</p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table"><a id="table-Java-Broker-Security-AccessControlProviders-Syntax_objects"></a><p class="title"><strong>Table&#160;8.3.&#160;List of ACL objects</strong></p><div class="table-contents"><table border="1" summary="List of ACL objects"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th><p>Object type</p></th><th><p>Description</p></th><th><p>Supported actions</p></th><th><p>Supported properties</p></th><th><p>Allowed in Virtualhost ACLs?</p></th></tr></thead><tbody><tr><td> <span class="command"><strong>VIRTUALHOSTNODE</strong></span> </td><td> <p>A virtualhostnode or remote replication node</p> </td><td><p>ALL, CREATE, UPDATE, DELETE, INVOKE</p> </td><td><p>name</p> </td><td><p>No</p> </td></tr><tr><td> <span class="command"><strong>VIRTUALHOST</strong></span> </td><td> <p>A virtualhost</p> </td><td><p>ALL, CREATE, UPDATE, DELETE, ACCESS, ACCESS_LOGS, INVOKE</p> </td><td><p>name</p> </td><td><p>No</p> </td></tr><tr><td> <span class="command"><strong>QUEUE</strong></span> </td><td> <p>A queue </p> </td><td><p>ALL, CREATE, DELETE, PURGE, CONSUME, UPDATE, INVOKE</p></td><td><p>name, autodelete, temporary, durable, exclusive, alternate, owner, virtualhost_name</p></td><td><p>Yes</p> </td></tr><tr><td> <span class="command"><strong>EXCHANGE</strong></span> </td><td><p>An exchange</p></td><td><p>ALL, ACCESS, CREATE, DELETE, BIND, UNBIND, PUBLISH, UPDATE, INVOKE</p></td><td><p>name, autodelete, temporary, durable, type, virtualhost_name, queue_name(only for BIND and UNBIND), routingkey(only for BIND and UNBIND, PUBLISH)</p></td><td><p>Yes</p> </td></tr><tr><td> <span class="command"><strong>USER</strong></span> </td><td> <p>A user</p> </td><td><p>ALL, CREATE, DELETE, UPDATE, INVOKE</p></td><td><p>name</p></td><td><p>No</p> </td></tr><tr><td> <span class="command"><strong>GROUP</strong></span> </td><td> <p>A group</p> </td><td><p>ALL, CREATE, DELETE, UPDATE, INVOKE</p></td><td><p>name</p></td><td><p>No</p> </td></tr><tr><td> <span class="command"><strong>BROKER</strong></span> </td><td> <p>The broker</p> </td><td><p>ALL, CONFIGURE, ACCESS_LOGS, INVOKE</p></td><td><p /></td><td><p>No</p> </td></tr></tbody></table></div></div><br class="table-break" /><div class="table"><a id="table-Java-Broker-Security-AccessControlProviders-Syntax_properties"></a><p class="title"><strong>Table&#160;8.4.&#160;List of ACL properties</strong></p><div class="table-contents"><table border="1" summary="List of ACL properties"><colgroup><col /><col /></colgroup><tbody><tr><td><span class="command"><strong>name</strong></span> </td><td> <p> String. Object name, such as a queue name or exchange name.</p> </td></tr><tr><td> <span class="command"><strong>durable</strong></span> </td><td> <p> Boolean. Indicates the object is durable </p> </td></tr><tr><td> <span class="command"><strong>routingkey</strong></span> </td><td> <p> String. Specifies routing key </p> </td></tr><tr><td> <span class="command"><strong>autodelete</strong></span> </td><td> <p> Boolean. Indicates whether or not the object gets deleted when the connection is closed </p> </td></tr><tr><td> <span class="command"><strong>exclusive</strong></span> </td><td> <p> Boolean. Indicates the presence of an <em class="parameter"><code>exclusive</code></em> flag </p> </td></tr><tr><td> <span class="command"><strong>temporary</strong></span> </td><td> <p> Boolean. Indicates the presence of an <em class="parameter"><code>temporary</code></em> flag </p> </td></tr><tr><td> <span class="command"><strong>type</strong></span> </td><td> <p> String. Type of object, such as topic, or fanout</p> </td></tr><tr><td> <span class="command"><strong>alternate</strong></span> </td><td> <p> String. Name of the alternate exchange </p> </td></tr><tr><td> <span class="command"><strong>queue_name</strong></span> </td><td> <p> String. Name of the queue (used only when the object is EXCHANGE for BIND and UNBIND actions)</p> </td></tr><tr><td> <span class="command"><strong>component</strong></span> </td><td> <p> String. component name</p> </td></tr><tr><td> <span class="command"><strong>from_network</strong></span> </td><td>
<p>
Comma-separated strings representing IPv4 address ranges.
</p>
<p>
Intended for use in ACCESS VIRTUALHOST rules to apply firewall-like restrictions.
</p>
<p>
The rule matches if any of the address ranges match the IPv4 address of the messaging client.
The address ranges are specified using either Classless Inter-Domain Routing notation
(e.g. 192.168.1.0/24; see <a class="link" href="http://tools.ietf.org/html/rfc4632" target="_top">RFC 4632</a>)
or wildcards (e.g. 192.169.1.*).
</p>
</td></tr><tr><td> <span class="command"><strong>from_hostname</strong></span> </td><td>
<p>
Comma-separated strings representing hostnames, specified using Perl-style regular
expressions, e.g. .*\.example\.company\.com
</p>
<p>
Intended for use in ACCESS VIRTUALHOST rules to apply firewall-like restrictions.
</p>
<p>
The rule matches if any of the patterns match the hostname of the messaging client.
</p>
<p>
To look up the client's hostname, Qpid uses Java's DNS support, which internally caches its results.
</p>
<p>
You can modify the time-to-live of cached results using the *.ttl properties described on the
Java <a class="link" href="http://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html" target="_top">Networking
Properties</a> page.
</p>
<p>
For example, you can either set system property sun.net.inetaddr.ttl from the command line
(e.g. export QPID_OPTS="-Dsun.net.inetaddr.ttl=0") or networkaddress.cache.ttl in
$JAVA_HOME/lib/security/java.security. The latter is preferred because it is JVM
vendor-independent.
</p>
</td></tr><tr><td><span class="command"><strong>virtualhost_name</strong></span></td><td>
<p>
String. A name of virtual host to which the rule is applied.
</p>
</td></tr><tr><td><span class="command"><strong>method_name</strong></span></td><td>
<p>
String. The name of the method. A trailing wildcard (*) is permitted. Used with INVOKE ACL action.
</p>
</td></tr><tr><td><span class="command"><strong>attribute_names</strong></span></td><td>
<p>
Specifies attribute name criteria. Used by UPDATE ACL actions only. Rules with this criteria will match
if and only if the set of attributes being updated Comma separated list of attribute names . This criteria
will match if all attributes included within the update appear in the set described by
<code class="literal">attribute_names</code>.
</p>
</td></tr></tbody></table></div></div><br class="table-break" /><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="Java-Broker-Security-AccessControlProviders-WorkedExamples"></a>8.3.4.&#160;
Worked Examples
</h3></div></div></div><p>
Here are some example ACLs illustrating common use cases.
</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="Java-Broker-Security-AccessControlProviders-WorkedExample1"></a>8.3.4.1.&#160;
Worked example 1 - Management rights
</h4></div></div></div><p>
Suppose you wish to permission two users: a user <code class="literal">operator</code> must be able to perform all
Management operations, and a user 'readonly' must be enable to perform only read-only actions. Neither
<code class="literal">operator</code> nor <code class="literal">readonly</code> should be allowed to connect clients for
messaging.
</p><div class="example"><a id="d0e5451"></a><p class="title"><strong>Example&#160;8.1.&#160;Worked example 1 - Management rights</strong></p><div class="example-contents"><pre class="programlisting">
# Deny operator/readonly permission to connect for messaging.
ACL DENY-LOG operator ACCESS VIRTUALHOST
ACL DENY-LOG readonly ACCESS VIRTUALHOST
# Give operator permission to perfom all actions
ACL ALLOW operator ALL ALL
# Give readonly access permission to virtualhost. (Read permission for all objects implicit)
ACL ALLOW readonly ACCESS MANAGEMENT
...
... rules for other users
...
</pre></div></div><br class="example-break" /></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="Java-Broker-Security-AccessControlProviders-WorkedExample2"></a>8.3.4.2.&#160;
Worked example 2 - Simple Messaging
</h4></div></div></div><p>
Suppose you wish to permission a system for application messaging. User <code class="literal">publisher</code>
needs permission to publish to <code class="literal">appqueue</code> and consumer needs permission to consume
from the same queue object. We also want <code class="literal">operator</code> to be able to inspect messages
and delete messages in case of the need to intervene. This example assumes that the queue exists on
the Broker.
</p><p>
We use this ACL to illustrate separate Broker and Virtualhost access control providers.
</p><p>
The following ACL rules are given to the Broker.
</p><div class="example"><a id="d0e5474"></a><p class="title"><strong>Example&#160;8.2.&#160;Worked example 2 - Simple Messaging - Broker ACL rules</strong></p><div class="example-contents"><pre class="programlisting">
# This gives the operate permission to delete messages on all queues on all virtualhost
ACL ALLOW operator ACCESS MANAGEMENT
ACL ALLOW operator INVOKE QUEUE method_name="deleteMessages"
ACL ALLOW operator INVOKE QUEUE method_name="getMessage*"
</pre></div></div><br class="example-break" /><p>
And the following ACL rule-set is applied to the Virtualhost. The default outcome of the
Access Control Provider must be <code class="literal">DEFERED</code>. This means that if a request for
access is made for which there are no matching rules, the decision will be deferred to the
Broker so it can make a decision instead.
</p><div class="example"><a id="d0e5484"></a><p class="title"><strong>Example&#160;8.3.&#160;Worked example 2 - Simple Messaging - Virtualhost ACL rules</strong></p><div class="example-contents"><pre class="programlisting">
# Configure the rule-set to DEFER decisions that have no matching rules.
CONFIG DEFAULTDEFER=TRUE
# Allow client and server to connect to the virtual host.
ACL ALLOW publisher ACCESS VIRTUALHOST
ACL ALLOW consumer ACCESS VIRTUALHOST
ACL ALLOW publisher PUBLISH EXCHANGE name="" routingKey="appqueue"
ACL ALLOW consumer CONSUME QUEUE name="appqueue"
# In some addressing configurations, the Qpid JMS AMQP 0-x client, will declare the queue as a side effect of creating the consumer.
# The following line allows for this. For the Qpid JMS AMQP 1.0 client, this is not required.
ACL ALLOW consumer CREATE QUEUE name="appqueue"
</pre></div></div><br class="example-break" /></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a id="Java-Broker-Security-AccessControlProviders-WorkedExample3"></a>8.3.4.3.&#160;
Worked example 3 - firewall-like access control
</h4></div></div></div><p>
This example illustrates how to set up an ACL that restricts the IP addresses and hostnames
of messaging clients that can access a virtual host.
</p><div class="example"><a id="d0e5494"></a><p class="title"><strong>Example&#160;8.4.&#160;Worked example 3 - firewall-like access control</strong></p><div class="example-contents"><pre class="programlisting">
################
# Hostname rules
################
# Allow messaging clients from company1.com and company1.co.uk to connect
ACL ALLOW all ACCESS VIRTUALHOST from_hostname=".*\.company1\.com,.*\.company1\.co\.uk"
# Deny messaging clients from hosts within the dev subdomain
ACL DENY-LOG all ACCESS VIRTUALHOST from_hostname=".*\.dev\.company1\.com"
##################
# IP address rules
##################
# Deny access to all users in the IP ranges 192.168.1.0-192.168.1.255 and 192.168.2.0-192.168.2.255,
# using the notation specified in RFC 4632, "Classless Inter-domain Routing (CIDR)"
ACL DENY-LOG messaging-users ACCESS VIRTUALHOST \
from_network="192.168.1.0/24,192.168.2.0/24"
# Deny access to all users in the IP ranges 192.169.1.0-192.169.1.255 and 192.169.2.0-192.169.2.255,
# using wildcard notation.
ACL DENY-LOG messaging-users ACCESS VIRTUALHOST \
from_network="192.169.1.*,192.169.2.*"
</pre></div></div><br class="example-break" /></div></div></div><div class="navfooter"><hr /><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="Java-Broker-Security-Group-Providers.html">Prev</a>&#160;</td><td align="center" width="20%"><a accesskey="u" href="Java-Broker-Security.html">Up</a></td><td align="right" width="40%">&#160;<a accesskey="n" href="Java-Broker-Security-Configuration-Encryption.html">Next</a></td></tr><tr><td align="left" valign="top" width="40%">8.2.&#160;Group Providers&#160;</td><td align="center" width="20%"><a accesskey="h" href="Apache-Qpid-Broker-J-Book.html">Home</a></td><td align="right" valign="top" width="40%">&#160;8.4.&#160;Configuration Encryption</td></tr></table></div></div>