# 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.

The following table lists the resource types that AMPS provides:

| 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:

| AMPS Command                                                                                                                                                    | Entitlement Type      |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| <p><code>delta_subscribe</code>,</p><p><code>sow</code>, <code>sow_and_subscribe</code>,</p><p><code>subscribe</code>, <code>sow_and_delta_subscribe</code></p> | `read`                |
| <p><code>delta_publish</code>, <code>publish</code>,</p><p><code>sow_delete</code></p>                                                                          | `write`               |
| _Commands received over replication_                                                                                                                            | `replication allowed` |

{% hint style="info" %}
Notice that topics that contain messages and requests to the administrative interface are considered to be a different resource type, and are treated differently by most entitlement systems.

This allows you to set permissions to statistics and administrative actions separately from access to message data.

For example, a system administrator could have access to all of the information in the administrative interface by being granted access to any resource of `admin` type, but could be denied access to any `topic` resource to disallow access to message data.
{% endhint %}

## 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:

| Message                                          | Entitlement Select List | Subscriber Select List | Result           |
| ------------------------------------------------ | ----------------------- | ---------------------- | ---------------- |
| `{"a":1, "b":2}`                                 | `-/a`                   | `+/a`                  | `{"b":2}`        |
| `{"a":1, "b":2}`                                 | `-/,+/b`                | (none)                 | `{"b":2}`        |
| `{"a":1, "b":2, "c": {"c1":1, "c2":2, "c3":3} }` | `-/,+/b,+/c/c2`         | `-/,+/c/c1,+/c/c2`     | `{"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.

## Multiple Logical Topics in a Physical SOW Topic

As described in the section on [using a single physical topic to hold multiple logical topics](../sow/pattern_topics), entitlements for the topic are applied to the physical topic -- that is, the set of logical topics as whole. When entitlements are checked for this topic, AMPS provides the `Name` of the physical topic to the entitlement system. AMPS uses the permissions returned for that `Name` for every topic in the physical topic.

AMPS does not support providing different entitlements to individual topics within a physical topic. However, an entitlement filter that uses the `TOPIC_NAME()` function (as described in the section on [Message Functions](../amps-functions/message-functions) in the [AMPS Functions](../amps-functions) section) can be used to restrict access to specific topics, since the `TOPIC_NAME()` will return the logical topic name.

## Disabling Entitlement

When AMPS starts, the entitlement system is always enabled. AMPS provides an administrative action, `amps-do-disable-entitlements` (see the [Manage Security](../actions/choosing-what-an-action-does/do-manage-security) topic in the section on [Configuring AMPS for Automation with Actions](../actions)), 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 [Manage Security](../actions/choosing-what-an-action-does/do-manage-security) in the section on [Configuring AMPS for Automation with Actions](../actions)).

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 [Manage Security](../actions/choosing-what-an-action-does/do-manage-security) in the section on [Configuring AMPS for Automation with Actions](../actions)) 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).

## Provided Entitlement Modules

AMPS loads two simple entitlement modules by default. These modules provide very simple policies for entitlements, and are most useful in testing and development environments.

| Module                               | Description                                   |
| ------------------------------------ | --------------------------------------------- |
| `amps-default-entitlement-module`    | Allows any user to access any resource.       |
| `amps-default-no-entitlement-module` | Denies access to all resources for all users. |

AMPS also includes two modules that can be used to manage entitlements. These modules must be explicitly loaded and configured.

| Module                                 | Description                                                                                                                                                                                                                                                 |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `libamps_simple_access_entitlement.so` | This module provides a simple allow/deny list for all users on the transport. See [Simple Access Entitlements Module](auth-entitle/simple-access-module) for details.                                                                                       |
| `libamps_http_entitlement.so`          | This module makes requests to an external RESTful service for authentication. This module will typically also handle entitlements for the Transports that use it. See [RESTful Authentication and Entitlements](auth-entitle/http-auth-module) for details. |
