.. include:: ../macros.inc

.. index:: securing AMPS; overview,


.. _#ug-securing:

.. _securing:

Securing AMPS
===============================


One of the most important considerations when using AMPS in production
is keeping your data safe. This means both ensuring that subscribers
only have access to the data that they are allowed to have access to and that
only authorized publishers are allowed to publish messages into the system.
This chapter describes the mechanisms within AMPS to protect access to
AMPS resources through client, administrative and replication
connections.


In this chapter, we describe the AMPS security infrastructure and
present general information about securing an AMPS installation. AMPS
uses a plugin model for providing authentication and entitlement, and
allows a great deal of freedom in how a given module implements
security checks. This chapter discusses the concepts, principles, and
guarantees that AMPS provides. The specific steps and configuration you
use to secure an installation of AMPS depend on the plugin you use to
secure AMPS.

There are three aspects to securing connections to AMPS:

1. Authentication assigns an identity to a connection and verifies that
   identity

2. Entitlement enforces permission to access AMPS and read or write AMPS
   resources, based on the identity assigned to a connection

3. The AMPS process may also need to provide credentials to another AMPS
   instance (for example, to secure outgoing replication)

AMPS installations typically create custom plugins for securing AMPS.
These plugins integrate with the enterprise authentication and
entitlement system, and are designed to enforce the policies for the
specific site. For more information on developing modules for use with
AMPS, contact 60East support for the AMPS Server SDK.

The AMPS distribution includes an auxiliary module that contacts a web
service for authentication and entitlement. This module is described in
the section :ref:`#ug-auth-module`.

The AMPS distribution also contains an entitlement module that can
be used to restrict access to specific topics for all users. This
module is described in the section :ref:`#ug-simple-access`.

For applications that need to connect with an existing Kerberos or LDAP system
for authentication, the AMPS distribution includes an auxiliary module that can 
use either a Kerberos or LDAP system for authentication. This module is described 
in the section :ref:`#ug-multi-authentication`.

If an installation uses Kerberos for replication security, the AMPS server must
be able to provide a Kerberos token to authenticate itself to a downstream instance. 
For this situation, the AMPS distribution includes an authenticator that can provide 
Kerberos tokens, as described in the section :ref:`#ug-multi-authenticator`.

.. index:: authentication, securing AMPS; verifying identity,

.. _#ug-authentication:

Authentication
--------------

The first part of securing AMPS is developing a strategy to verify the
identity of connected clients. AMPS maintains an identity for each
client connection, and uses that identity for entitlement requests. Once
an identity is assigned to a connection, that identity stays the same
for the lifetime of the connection. If an application needs to use
different identities to work with AMPS, that application needs to make a
separate connection for each identity.

There are two ways that AMPS assigns an identity to a client:

1. When an application explicitly sends a ``logon`` command, AMPS uses
   the credentials in the message for the authentication process. If
   authentication is successful, AMPS associates the username provided
   in the initial logon with the connection. If authentication fails,
   AMPS closes the connection.

2. When an application issues any other command after connecting, but
   before sending a ``logon`` command, AMPS treats this as an *implicit*
   logon and begins the authentication process with an empty username
   and password. If authentication is successful, AMPS associates an
   empty username with the connection. If authentication fails, AMPS
   closes the connection. AMPS does not allow implicit logon by default
   in 5.0 and later versions. However, you can enable implicit logon as
   described below.

In both cases, authentication occurs through the AMPS security
infrastructure.

When authenticating a client, AMPS locates the authentication module in
use for the client's ``Transport`` (or, for the admin interface, the special
``amps-admin`` transport). If there is an authentication module
specified for that ``Transport``, AMPS uses that module. Otherwise, the
``Transport`` uses an instance of the authentication module specified for
the instance. When the configuration for the instance doesn't include an
instance level authentication module, the default module for the
``Transport`` is ``amps-default-authentication-module``, which requires a
logon, but accepts any username and password provided and sets the
authenticated username to an empty string.

Once AMPS has located the module instance, AMPS provides the username
and the password to that instance of the module. The module can accept
the credentials, reject the credentials, or return a challenge that the
application must respond to. When the module returns a challenge, the
connection remains unauthenticated until the application requesting
authentication responds to the challenge and the module accepts the
response.

For most production systems, AMPS security is integrated with the
overall security fabric of the organization. 60East provides the *AMPS
Server SDK* to help developers create authentication modules that
implement the unique policies and procedures required by a particular
organization.

AMPS does not, itself, enforce an explicit timeout on the authentication
process. However, the thread used to authenticate is managed by AMPS, so
if the authentication process takes an extended period of time, AMPS 
may report a potentially stuck thread or (in extreme cases) prompt a
server shutdown. 60East recommends that the authentication process
complete as quickly as possible, especially since the authentication
process will limit how quickly clients can connect to AMPS. The process
should generally be subsecond if possible, and 60East recommends that the
process not take longer than 30 seconds, even if the authentication
server is under load.

Simple Authentication Modules
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

AMPS includes three simple authentication modules in the AMPS
distribution. These modules provide very simple policies for
authentication, and are most useful in testing and development
environments.

.. list-table:: *Simple Authentication Modules*
     :header-rows: 1

     * - Module

       - Description

     * - ``amps-default-authentication-module``
         

       - Allows any username and password.
         Does not allow implicit logon by
         default. Does not provide the
         username to AMPS by default.

     * - ``amps-implicit-authentication-module``
         

       - Allows any username and password.
         Allows implicit logon by default.
         Does not provide the username to
         AMPS by default.

     * - ``amps-default-no-authentication-module``
         

       - Does not allow authentication
         regardless of the username and
         password provided. This can be
         useful for testing application
         behavior when logon is denied, or
         for setting a policy for the
         instance that individual transports
         must override.



Enabling Implicit Logon
^^^^^^^^^^^^^^^^^^^^^^^^

60East recommends using explicit logon commands in your applications
wherever possible, and the default authentication module disallows
implicit logons. For backward compatibility with older versions of AMPS,
AMPS includes the ``amps-implicit-authentication-module`` which allows
implicit logon to restore the behavior of the previous AMPS versions. To
use the ``amps-implicit-authentication-module`` for all of the
transports in the instance, set the instance level ``Authentication`` to use
this module, as shown below:

.. code-block:: xml

    <AMPSConfig>
      ...
      <Authentication>
         <Module>amps-implicit-authentication-module</Module>
      </Authentication>
      ...
    </AMPSConfig>

.. index:: entitlement, securing AMPS; enforcing permissions,

.. _#ug-entitlement:

Entitlement
------------

The AMPS entitlement system controls access to individual resources in
AMPS. Each entitlement request consists of a user, a specific action
and, where applicable, the type of resource and the resource name. For
example, an entitlement request might arrive for the user ``Janice`` to
``write`` (that is, publish) to the ``topic`` named
``/orders/northamerica``. Another entitlement request might be for the
user ``Phil`` to ``logon`` to the instance. A third request might be for
the user ``Jill`` to ``read`` (that is, subscribe or run a SOW query)
from the topic named ``/orders/pacific/palau``.

When checking entitlements, AMPS locates the entitlement module in use
for the ``Transport`` that the client is connecting on (or, for the admin
interface, the special ``amps-admin`` transport). If there is an
entitlement module specified for the ``Transport``, AMPS uses that module.
Otherwise, AMPS uses an instance of the entitlement module specified for
the instance. When the configuration file for the instance doesn't
specify an instance level entitlement module, the default module for the
``Transport`` is ``amps-default-entitlement-module``, which allows all
permissions for any user.

AMPS caches the results of the entitlement check until the cache
is explicitly reset, the transport is disabled, entitlements
are disabled and re-enabled, or the AMPS server restarts. You can clear the
entitlement cache for all users using the AMPS Administrative Actions.
You can clear the entitlement cache for a single user using the AMPS
external API. When the entitlement cache is cleared, AMPS disconnects
the user. This ensures that, when the user reconnects, the user only has
access to resources that match the current set of entitlements.

AMPS checks entitlements for a command when processing the command, and
does not recheck permissions after the command is processed. For
example, when ``Jill`` subscribes to ``/orders/pacific/palau``, AMPS
checks entitlements when creating the subscription. If the entitlement
check returns an entitlement content filter, AMPS includes that
entitlement filter on the subscription. Once the subscription has been
created, AMPS applies the filter as a part of the standard filtering
process, but AMPS does not check entitlements for the subscription as
further messages arrive.

.. index:: permissions; login, permissions, login, permissions; replication, replication_login,
   permissions; topic, topic, permissions; admin, admin

The following table lists the resource types that AMPS provides:

.. list-table:: *AMPS Entitlement Resource Types*
     :header-rows: 1

     * - Resource Type

       - Description

     * - ``logon``

       - Permission to log on to the AMPS instance.

     * - ``replication_logon``
         

       - Permission to log on to the AMPS instance as a
         replication source.

     * - ``topic``
         

       - Permission to receive from or publish to a
         specific topic.

     * - ``admin``
         

       - Permission to read admin statistics or perform
         admin functions from the web interface.



For the ``topic`` and ``admin`` resource types, AMPS also provides the
name of the resource and whether the request is to ``read`` the resource
or ``write`` to the resource.

The table below shows how AMPS commands translate to entitlement types:

.. list-table:: *Entitlement Types for Commands*
     :header-rows: 1

     * - AMPS Command

       - Entitlement Type

     * - ``delta_subscribe``,
         
         ``sow``, ``sow_and_subscribe``,
         
         ``subscribe``,
         ``sow_and_delta_subscribe``

       - ``read``
         

     * - ``delta_publish``, ``publish``,
         
         ``sow_delete``

       - ``write``
         

     * - *Commands received over replication*

       - ``replication allowed``



Entitlement Caching
^^^^^^^^^^^^^^^^^^^

AMPS does not present a request to the entitlement module each time that
an entitlement check is needed. Instead, AMPS presents the request the
first time the entitlement is needed, and then caches the results from
the module for subsequent entitlement checks. This improves performance,
although it also means that when a module that reads entitlements from
an external source (such as a central directory of permissions), that may
change without requiring a restart of the AMPS instance, that module
will need to establish a policy for resetting the entitlement cache.

Regular Expression Subscriptions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Each request from AMPS is for a specific resource name. When a client
requests a regular expression subscription, AMPS makes a request for
each topic that matches the subscription at the point that AMPS has a
message to deliver for that topic. For example, if the user ``Nina``
enters a subscription for ``/parts/(mechanical|electrical)``, AMPS will
make a request to the entitlement module for ``/parts/mechanical`` when
there is a message to deliver for that topic, and will make a separate
request for ``/parts/electrical`` when there is a message to deliver for
that topic.

Content Filtered Entitlements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The entitlement system offers the ability to enforce content
restrictions on subscriptions. When AMPS requests ``read`` access to a
``topic``, the module that performs entitlement can also return a filter
to AMPS. This filter is evaluated independently of any filter on the
subscription, and messages must match both the subscription filter and
the filter provided by the entitlement to be returned to the
application. If a message does not match the entitlement filter, the
message is not delivered, regardless of whether the message matches the
filters provided by the application.

AMPS also offers the ability to enforce content restrictions on
``publish`` commands. When AMPS requests ``write`` access to a
``topic``, the module that performs entitlement can return a filter to
AMPS. This filter is then evaluated against messages published to that
topic by that user. If the message being published matches the filter,
AMPS allows the message. Otherwise, AMPS rejects the message. For
``delta_publish`` commands, the content filter applies to the incoming
delta message rather than the existing message in the SOW or the
merged message that is the result of the ``delta_publish``.

For ``sow_delete`` commands, content filtered entitlements apply to the
message being removed. If the message to be removed matches the content
filter, AMPS allows the delete. Otherwise, AMPS refuses to delete the message.

A ``sow_delete`` command can specify a regular expression topic,
which can match multiple topics. In this case, AMPS applies the
permissions and entitlement filter for each topic before deleting
messages in that topic. For example, in an instance that keeps
the State of the World for topics ``T1``, ``T2``, and ``T3``, a
``sow_delete`` command that specifies ``^T.$`` as the topic would
match all three of those topics. For this command, AMPS will check
the write entitlements for ``T1`` and apply the entitlement filter
for topic ``T1`` to the delete from that topic, check the write entitlements
for ``T2`` and apply the entitlement filter for ``T2`` to the delete from
that topic, and check the write entitlements for ``T3`` and apply the
write entitlement filter for ``T3`` to the delete from that topic. The
topics that the delete applies to and the entitlement filters applied,
are stored in the transaction log.


Entitlement Select Lists
^^^^^^^^^^^^^^^^^^^^^^^^^

For ``read`` entitlements, AMPS also allows the ability to restrict access
to specific fields of a message. In this case, the entitlement module returns
a *select list*. That select list will be applied to all messages delivered on
that topic for that user.

When both a content filter and a select list are provided, the content filter
is applied before the select list is applied. This means that an entitlement
system can filter on fields that a given user is not allowed to view.

As with content filters in entitlements, an entitlement select list is
evaluated independently of any select list provided by the subscriber.
An entitlement select list is evaluated *before* a select list
provided by the subscriber, and the subscriber select list applies
to the output of the entitlement select list.

The following table shows some examples:

.. list-table:: 
     :header-rows: 1

     * - **Message**
         

       - **Entitlement
         Select
         List**

       - **Subscriber
         Select
         List**

       - **Result**
         

     * - .. code::

            {"a":1, "b":2}

       - .. code::
         
            -/a

       - .. code::
         
            +/a

       - .. code::
         
            {"b":2}

     * - .. code::

            {"a":1, "b":2}

       - .. code::
         
            -/,+/b

       -  (none)

       - .. code::
         
            {"b":2}


     * - .. code::
         
            {"a":1,
             "b":2,
             "c":
              {"c1":1,
               "c2":2,
               "c3":3}
            }

       - .. code::

           -/,+/b,+/c/c2
         

       - .. code::
         
           -/,+/c/c1,+/c/c2

       - .. code::
    
           {"c":{"c2":2}}
         

Message Queues
^^^^^^^^^^^^^^

Message queues, since they are implemented as views over topics in the
transaction log, present a special situation for the AMPS entitlement
system in two ways. First, receiving a message from a queue implies that
the subscriber has the ability to modify the contents of the queue.
Second, a queue can specify a ``DefaultPublishTopic`` to receive
publishes.

The AMPS entitlement system treats queues differently than other topics
as follows:

-  ``read`` entitlement on a queue also grants a user the ability to
   delete (acknowledge) messages from the queue. No other write permissions
   are implied.

-  ``write`` entitlement on a queue grants the ability to publish to the
   queue, even in cases where AMPS translates that publish to the
   ``DefaultPublishTopic`` configured for the queue. No other
   permissions are implied. In particular, granting the ``write``
   entitlement on a queue does not grant any entitlements on the
   ``DefaultPublishTopic`` directly. Even though the message is
   delivered to the ``DefaultPublishTopic``, the ``publish`` command
   must publish to the queue topic.

In all other respects, entitlements for message queues behave in the
same way as entitlements for any other topic.

.. include:: ./sow_regex_topic_permissions.inc


.. index:: resetting entitlements,

.. _#ug-entitlement-disable:


Disabling Entitlement
^^^^^^^^^^^^^^^^^^^^^^^

When AMPS starts, the entitlement system is always enabled. AMPS provides an administrative action,
``amps-do-disable-entitlements`` (see :ref:`#ug-actions-do-security`), that disables the 
entitlement system until AMPS is restarted, or the system is explicitly re-enabled with
an action.

When the entitlement system is disabled:

* AMPS no longer checks new requests for entitlements with the configured entitlement module
* All entitlement requests succeed (even requests for operations that have previously been disallowed)
* AMPS does not cache the entitlement results for any operation

Notice that this means that all subscriptions succeed, no entitlement filters or entitlement
select lists are applied to new subscriptions, and so on. In effect, any time that AMPS would
check the entitlement cache or query the entitlement module, the operation immediately
succeeds with full permissions.

Disabling entitlements is designed to help mitigate failures in the entitlement system
(including external systems that manage entitlements), allowing an administrator to maintain
system availability at the cost of allowing full access to AMPS. This is most commonly used
in shared development instances that are simultaneously doing application development and
testing while working on updates to the set of allowable actions and/or the entitlement
system itself.

Entitlements can be re-enabled with the ``amps-action-do-enable-entitlements`` action (see
:ref:`#ug-actions-do-security`). When entitlements are re-enabled, AMPS:

* Initializes new entitlement contexts for the instance and destroys previous contexts
* Clears the entitlement cache
* Again consults the entitlement module or the entitlement cache for new requests

Notice that when entitlements are re-enabled, AMPS *does not* validate the current client
logons or the current subscriptions to determine if the entitlement policy allows those
logons or subscriptions. Likewise, AMPS *does not* update entitlement filters or
entitlement select lists when entitlements are re-enabled. Unlike an entitlement
reset, AMPS does not disconnect connected clients when the entitlement system is
re-enabled. This means that any existing client connections are maintained (whether or
not they would be allowed with the entitlement system enabled) and any existing
subscriptions are maintained (whether or not they would be allowed with the
entitlement system enabled).

60East recommends running an entitlement reset (see :ref:`#ug-actions-do-security`) after re-enabling
entitlement to ensure that all connections and subscriptions use the current entitlement policy. Otherwise,
the state of connections and subscriptions may not match the current policy. This can lead to a client
receiving messages that it is not currently entitled to (if the current policy is more restrictive than
when the connection and subscription were created), or not receiving messages that it is currently
entitled to (if the current policy is less restrictive than when the connection and subscription were
created).

.. index:: authenticator,

.. _#ug-authenticator:

Providing an Identity for Outbound Connections (Authenticator)
---------------------------------------------------------------

For outgoing replication connections, AMPS may need to provide an
identity and credentials to the replication destination. AMPS uses a
module type called an authenticator to provide those credentials and
handle any challenge/response protocol required by the authentication
module in the remote system.

AMPS provides a default authenticator module,
``amps-default-authenticator-module``, that is automatically configured
as the Authenticator for the instance if no other instance Authenticator
is provided. This module provides a user name with no password. To
determine the user provided to AMPS, the module uses the value of the
User option to the module if one is provided. Otherwise, the module uses
the current user of the AMPS process. If the current user cannot be
determined by the system, the module falls back to the value of the
``USER`` environment variable.

The ``amps-default-authenticator-module`` provides the ability to send
a specific password (available in version 5.3.0.0 and higher). To provide
a specific password, use one of the following options:


.. list-table:: *Password Options for Simple Authenticator Module*
     :header-rows: 1

     * - Option

       - Description

     * - ``Password``

       - Provide the contents of this option as the password.

     * - ``PasswordFileName``

       - Read the password from the specified filename.

     * - ``PasswordEnvironmentVariable``

       - Read the password from the specified environment variable.



The Authenticator used for a replication Destination must provide
credentials that are accepted by the Transport of the remote instance
that the Destination is connecting to. See the |configref|
for information on configuring the Authenticator for a Destination.

If an installation uses Kerberos for replication security, the AMPS server
must be able to provide a Kerberos token to authenticate itself to
a downstream instance. For this situation, the AMPS distribution
includes an authenticator that can provide Kerberos tokens, as
described in the section :ref:`#ug-multi-authenticator`. The
multi-authenticator also provides the ability to provide
credentials to an LDAP server, with functionality similar
to the ``amps-default-authenticator-module``.


Protecting Data in Transit Using TLS/SSL
-------------------------------------------

AMPS provides the ability to use Secure Sockets Layer (SSL)/
Transport Layer Security (TLS) connections for communication with AMPS
clients. See the |confguide-transport| chapter in the |configref| and
the documentation for the AMPS clients for details.

AMPS uses TLS to encrypt network traffic between clients and servers. No
information about the transport is passed to the AMPS authentication and
entitlement system. Encryption at the network level is completely
independent of the AMPS authentication and entitlement system, and these
features can be used independently.

.. tip::

        In this version of AMPS, a transport configured to use TLS
        defaults to accepting only TLS version 1.1 and TLS version 1.2
        protocols. It is possible to enable older protocols using the
        ``SecureSocketProtocols`` configuration directive. 60East
        recommends using the default settings unless there is a
        specific reason to enable older protocols and the security
        implications of enabling older protocols are well understood.
