blob: a4eb99b7da9634b53e4494c0f6631cc93cc0a231 [file] [log] [blame]
////
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License
////
[id='policy']
= Policy
The Policy module is an optional authorization mechanism enforcing
user connection restrictions and AMQP resource access control.
Policy is assigned when a connection is created. The connection
properties *AMQP virtual host*, *authenticated user name*, and *connection
remote host* are passed to the policy engine for a connection
allow/deny decision. If the connection is allowed then the user is
assigned to a group that names a set of AMQP resource limits that are
enforced for the lifetime of the connection.
[NOTE]
====
Policy limits are applied only to incoming user network connections.
Policy limits are not applied to interrouter connections nor are they
applied to router connections outbound to waypoints.
====
== Definitions
=== vhost
A _vhost_ is typically the name of the host to which the client AMQP
connection is directed. For example, suppose a client application opens
connection URL:
[options="nowrap"]
----
amqp://bigbroker.example.com:5672/favorite_subject
----
The client will signal virtual host name _bigbroker.example.com_ to
the router during AMQP connection startup. Router Policy intercepts
the virtual host _bigbroker.example.com_ and applies a vhost policy
with that name to the connection.
== Policy Features
=== Total Connection Limit
A router may be configured with a total connection limit. This limit
controls the maximum number of simultaneous incoming user connections
that are allowed at any time. It protects the router from file
descriptor resource exhaustion in the face of many incoming client
connections. This limit is specified and enforced independently of
any other Policy settings.
=== Vhost Policy
Vhost policy defines users and assigns them to user groups. Each
user group defines the remote hosts from which the members may connect
to the router network, and what resources in the router network the
group members are allowed to access.
Vhost policy also defines connection count limits to control the
number of users that may be simultaneously connected to the vhost.
[NOTE]
====
A vhost user may be assigned to one user group only.
====
=== Default Vhost
A default vhost may be defined. The default vhost policy is used for
connections whose vhost is otherwise not defined in the policy database.
xref:example2[Example 2] illustrates how the default vhost feature can
be used to apply a single vhost policy set of restrictions to any
number of vhost connections.
=== Vhost Patterns
Policy vhost names may be interpreted as literal host names or
as host name patterns. Vhost name patterns are a convenience
for letting a single policy rule cover a wide range of vhosts.
Host name patterns consist of a series of host and domain name
labels and one or more tokens all concatenated with periods or dots.
A token can be one of the following:
[options="header"]
|====
| Token character | Match rule
| asterisk * | matches a single hostname label
| hash # | matches zero or more hostname labels
|====
Some simple examples show how given policy name patterns match
incoming connection vhost names.
[options="header"]
|====
| Policy pattern | Connection vhost | Policy match
| *.example.com | example.com | no
| *.example.com | www.example.com | yes
| *.example.com | srv2.www.example.com | no
| #.example.com | example.com | yes
| #.example.com | www.example.com | yes
| #.example.com | a.b.c.d.example.com | yes
| #.example.com | bighost.com | no
| www.*.test.example.com | www.test.example.com | no
| www.*.test.example.com | www.a.test.example.com | yes
| www.*.test.example.com | www.a.b.c.test.example.com | no
| www.#.test.example.com | www.test.example.com | yes
| www.#.test.example.com | www.a.test.example.com | yes
| www.#.test.example.com | www.a.b.c.test.example.com | yes
|====
Pattern matching applies the following precedence rules.
[options="header"]
|====
| Policy pattern | Precedence
| exact match | high
| asterisk * | medium
| hash # | low
|====
Policy vhost name patterns are optimised before they are used
in connection vhost name matching. As a result of this
optimisation the names stored for pattern match lookups are
not necessarily the same as the patterns specified in the
vhost policy hostname. The policy agent disallows vhost
name patterns that reduce to the same pattern as an existing name
pattern. For instance, name pattern _pass:[#.#.#.#.com]_ is reduced to _pass:[#.com]_.
Attempts to create a vhost name pattern whose optimised
name conflicts with an existing optimised name will be denied.
== Policy Schema
Policy configuration is specified in two schema objects.
[options="nowrap"]
----
policy = {
<global settings>
}
vhost = {
id: vhost-name
<connection limits>
groups: {
group-name: {
<user group settings>
}
}
}
----
The _policy_ object is a singleton. Multiple _vhost_ objects may be
created as needed.
=== Global Policy
[options="header", cols="35,15,50"]
|====
| attribute | default | description
| maxConnections | 65535 | Global maximum number of concurrent client connections allowed. This limit is always enforced even if no other policy settings have been defined. This limit is applied to all incoming connections regardless of remote host, authenticated user, or targeted vhost.
| enableVhostPolicy | false | Enable vhost policy connection denial, and resource limit enforcement.
| policyDir | "" | Absolute path to a directory that holds vhost definition .json files. All vhost definitions in all .json files in this directory are processed.
| defaultVhost | "$default" | Vhost rule set name to use for connections with a vhost that is otherwise not defined. Default vhost processing may be disabled either by erasing the definition of _defaultVhost_ or by not defining a _vhost_ object named _$default_.
| enableVhostNamePatterns | false | Enable vhost name patterns. When false vhost hostnames are treated as literal strings. When true vhost hostnames are treated as match patterns.
|====
=== Vhost Policy
[options="header", cols="35,15,50"]
|====
| attribute | default | description
| id | | Vhost name must be unique.
| maxConnections | 65535 | Maximum number of concurrent client connections allowed.
| maxConnectionsPerUser | 65535 | Maximum number of concurrent client connections allowed for any user.
| maxConnectionsPerRemoteHost | 65535 | Maximum number of concurrent client connections allowed for any remote host.
| allowUnknownUser | false | Allow unknown users who are not members of a defined user group. Unknown users are assigned to the '$default' user group and receive '$default' settings.
| groups | | A map where each key is a user group name and the value is a Vhost User Group Settings map.
|====
=== Vhost User Group Settings Map
This object is the data value contained in entries in the policy/groups map.
[options="header", cols="35,15,50"]
|====
| Section/Attribute | default | description
| *Group Membership* | |
| users | "" | Comma separated list of authenticated users in this group.
| *Connection Restrictions* | |
| remoteHosts | "" | List of remote hosts from which the users may connect. List values may be host names, numeric IP addresses, numeric IP address ranges, or the wildcard '*'. An empty list denies all access.
| *AMQP Connection Open Limits* | |
| maxFrameSize | 2^31-1 | Largest frame that may be sent on this connection. (AMQP Open, max-frame-size)
| maxSessions | 65535 | Maximum number of sessions that may be created on this connection. (AMQP Open, channel-max)
| *AMQP Session Begin Limits* | |
| maxSessionWindow | 2^31-1 |Incoming capacity for new sessions measured in octets. AMQP Begin, incoming-window measured in AMQP frames is calculated by (maxSessionWindow / maxFrameSize). (AMQP Begin, incoming-window)
| *AMQP Link Attach* | |
| maxMessageSize | 0 | Largest message size supported by links created on this connection. If this field is zero there is no maximum size imposed by the link endpoint. (AMQP Attach, max-message-size)
| maxSenders | 2^31-1 | Maximum number of sending links that may be created on this connection.
| maxReceivers | 2^31-1 | Maximum number of receiving links that may be created on this connection.
| allowDynamicSource | false | This connection is allowed to create receiving links using the Dynamic Link Source feature.
| allowAnonymousSender | false | This connection is allowed to create sending links using the Anonymous Sender feature.
| allowUserIdProxy | false | This connection is allowed to send messages with a user_id property that differs from the connection's authenticated user id.
| sources | "" | List of Source addresses allowed when creating receiving links. This list may be expressed as a CSV string or as a list of strings. An empty list denies all access.
| targets | "" | List of Target addresses allowed when creating sending links. This list may be expressed as a CSV string or as a list of strings. An empty list denies all access.
| sourcePattern | "" | List of Source address patterns allowed when creating receiving links. This list must be expressed as a CSV string. An empty string denies all access.
| targetPattern | "" | List of Target address patterns allowed when creating sending links. This list must be expressed as a CSV string. An empty string denies all access.
|====
== Policy Wildcard and User Name Substitution
Policy provides several conventions to make writing rules easier.
=== Remote Host Wildcard
Remote host rules may consist of a single asterisk character to
specify all hosts.
[options="nowrap"]
----
remoteHosts: *
----
The asterisk must stand alone and cannot be appended to a host name
or to an IP address fragment.
=== AMQP Source and Target User Name Substitution
The rule definitions for `sources`, `targets`, `sourcePattern`, and
`targetPattern` may include the username
substitution token
[options="nowrap"]
----
${user}
----
The username substitution token is replaced with the authenticated user name for
the connection. Using this token, an administrator may allow access to
some resources specific to each user without having to name each user
individually. This token is substituted once for the leftmost
occurrence in the link name.
=== AMQP Source and Target Link Name Match Wildcard
The rule definitions for `sources` and `targets` may contain a trailing
asterisk character.
The asterisk is recognized only if it is the last character in the
link name.
[options="nowrap"]
----
sources: tmp_${user}, temp*, ${user}-home-*
----
The rule definitions for `sourcePattern` and `targetPattern` use the same
patterns defined for router addresses and link routes. The patterns consist of one or more
tokens separated by a forward slash /. A token can be one of the following:
a * character, a # character, or a sequence of characters that do not
include /, *, or #. The * token matches any single token. The # token
matches zero or more tokens.
The user name substitution token may be used in a sourcePattern or in a
targetPattern subject to the following restrictions:
* The user name substitution token must be the first or last token in the rule clause.
* The user name substitution token must stand alone within its delimited field.
It may not be concatenated with literal text prefixes or suffixes.
For each rule definition multiple patterns may be specified in a comma
separated list.
[options="nowrap"]
----
sourcePattern: tmp.${user}, temp/#, ${user}.home/*
----
[NOTE]
====
A rule definition may contain `sources` or `sourcePattern` but not both.
A rule definition may contain `targets` or `targetPattern` but not both.
====
== Composing Policies
This section shows policy examples designed to illustrate some common use cases.
=== Example 1. User Policy Disabled
Policy is disabled when no policy configuation objects are defined.
Any number of connections are allowed and all users have
access to all AMQP resources in the network.
[id='example2']
=== Example 2. All Users Have Simple Connection Limits
This example shows how to keep users from overwhelming the router with
connections. Any user can create up to ten connections and the router
will limit the aggregated user connection count to 100 connections
total. No other restrictions apply.
This example also shows how to use a default vhost policy effectively.
Only one vhost policy is defined and all user connections regardless
of the requested vhost use that policy.
[options="nowrap"]
----
policy {
maxConnections: 100 <1>
}
vhost {
name: $default <2>
maxConnectionsPerUser: 10 <3>
allowUnknownUser: true <4>
groups: {
$default: {
remoteHosts: * <5>
sources: * <6>
targets: * <6>
}
}
}
----
<1> The global maxConnections limit of 100 is enforced.
<2> No normal vhost names are defined; user is assigned to default vhost '$default'.
<3> The vhost maxConnectionsPerUser limit of 10 is enforced.
<4> No groups are defined to have any users but allowUnknownUser is true so all users are assigned to group $default.
<5> The user is allowed to connect from any remote host.
<6> The user is allowed to connect to any source or target in the AMQP network. Router system-wide values are used for the other AMQP settings that are unspecified in the vhost rules.
=== Example 3. Admins Must Connect From Localhost
This example shows how an admin group may be created and restricted
to accessing a vhost only from localhost. The admin users are allowed
to connect to any AMQP resources while normal users are restricted.
In this example a user connects to vhost 'example.com'.
[options="nowrap"]
----
vhost {
name: example.com <1>
allowUnknownUser: true <3>
groups: {
admin: {
users: alice, bob <2>
remoteHosts: 127.0.0.1, ::1 <4>
sources: * <5>
targets: * <5>
},
$default: {
remoteHosts: * <6>
sources: news*, sports*, chat* <7>
targets: chat* <7>
}
}
}
----
<1> A connection to vhost 'example.com' locates this vhost rule set.
<2> If one of users _alice_ or _bob_ is connecting then she or he is assigned to the 'admin' user group.
<3> Any other user is not defined by a user group. However, since the _allowUnknownUser_ setting is true then this user is assigned to the '$default' user group.
<4> Users in the 'admin' user group must connect from localhost. Connections for an 'admin' user from other hosts on the network are denied.
<5> Users in the 'admin' user group are allowed to access any resource offered by the vhost service.
<6> Other users are allowed to connect from any host.
<7> Other users have source and target name lists that restrict the resources they are allowed to access.
=== Example 4. Limiting Possible Memory Consumption
Policy provides a mechanism to control how much system buffer memory a
user connection can potentially consume. The formula for computing
buffer memory consumption for each session is
set directly by _maxSessionWindow_.
By adjusting _maxSessions_, and _maxSessionWindow_ an
administrator can prevent a user from consuming too much memory by
buffering messages in flight.
[NOTE]
====
The settings passed into the AMQP protocol connection and session
negotiations. Normal AMQP session flow control limits buffer
consumption in due course with no processing cycles required by the
router.
====
In this example normal users, the traders, are given smaller buffer
allocations while high-capacity, automated data feeds are given a
higher buffer allocation. This example skips the details of settings
unrelated to buffer allocation.
[options="nowrap"]
----
vhost {
name: traders.com <1>
groups: {
traders: {
users: trader-1, trader-2, ... <2>
maxFrameSize: 10000 <3>
maxSessionWindow: 5000000 <3>
maxSessions: 1 <4>
...
},
feeds: {
users: nyse-feed, nasdaq-feed <5>
maxFrameSize: 60000 <6>
maxSessionWindow: 1200000000 <6>
maxSessions: 3 <7>
...
}
}
}
----
<1> These rules are for vhost traders.com.
<2> The 'traders' group includes trader-1, trader-2, and any other user defined in the list.
<3> _maxFrameSize_ and _maxSessionWindow_ allow for at most 5,000,000 bytes of data to be in flight on each session.
<4> Only one session per connection is allowed.
<5> In the 'feeds' group two users are defined.
<6> _maxFrameSize_ and _maxSessionWindow_ allow for at most 1,200,000,000 bytes of data to be in flight on each session.
<7> Up to three sessions per connection are allowed.
////
- Should we used signed ints for limits to allow for magic values?
- In example 3, alice and bob cannot connect from an outside server and
get the $default settings.
- Limits are enforced per router, so a vhost policy of maxConnections
10 across 10 routers will allow 100 connections to that vhost.
////