Configuring Cloud API access to third-party data

This topic only applies to BillingCenter.

Configuring contact authorization IDs

The contact authorization IDs resource access strategy assumes the following:

  • Every external user is associated with a contact authorization ID

  • Every resource the external user is attempting to access is somehow associated with a contact that has a contact authorization ID

For more information on how contact authorization IDs are assigned, see the Cloud API Developer Guide.

Configuring access to base configuration entities

The accessiblefields.yaml files define the types for which access can be filtered. Each type specifies additional edit and view restrictions imposed on users with filtered access.
  • Fields that the user can view or edit must be listed explicitly.

  • If the caller cannot view or edit any fields on the resource, an empty list ([ ]) must be specified.

The accessiblefields.yaml files are configurable. You can add and remove types and fields as needed to suit your implementation. To deploy the changes:

  • If you are in development mode, the file will hotswap a few seconds after it is saved.

  • If you are in production mode, you must restart the server.

Warning: You can edit the contents of the accessiblefields.yaml files. But, do not delete or rename the files, as this will prevent the base configuration resource access strategies from working as intended.

Configuring access for custom entities

If you create a custom entity that stores third-party information, and you want to restrict access to this information, you can add new additional accessible fields filters for the custom entity.

Configuration steps

To configure additional accessible fields filters for a custom third-party data entity, you must do the following:

  1. Generate endpoints for the custom entity

  2. Configure an additional accessible fields filter

  3. Configure the accessible fields in the accessiblefields.yaml file

Step 1: Generate endpoints for the custom entity

First, you must generate endpoints for the custom entity using the REST endpoint generator. For more information, see Generating endpoints for custom entities.

Step 2: Configure an additional accessible fields filter

Next, you must add an additional accessible fields filter to the appropriate resource access extension file. You must also configure any related logic used by your additional accessible fields filter expression.

To define the filter itself, edit the appropriate resource access extension file. For example, to configure the contactAuthorizationIds resource access strategy, edit the contactAuthorizationIds_ext-1.0.access.yaml file. To configure the producerCodes resource access strategy, edit the producerCodes_ext-1.0.access.yaml file.

In the appropriate resource access extension file, add a section that defines the custom type and a viewAndEdit expression. The expression can be defined in two ways.

Setting the filter to a Gosu expression

The expression can be a Gosu expression that returns null or a string.

  • If the expression returns null, no additional restrictions are placed on access to the given resource.

  • If the expression returns a string, Cloud API looks in the integration > roles > additionalaccessiblefieldsfilters directory for a file that starts with the returned string and ends with accessiblefields.yaml. It then adds any additional restrictions defined in that file.

This expression can use the following symbols:

  • user - The AuthorizedUser that Cloud API retrieved from the calling token

  • resource - The instance of the resource to be evaluated

The base configuration includes the following accessiblefields.yaml files:

  • accountprimarypayer.accessiblefields.yaml

  • invoiceitempayer.accessiblefields.yaml

  • producercoderestricted.accessiblefields.yaml

Your logic can reference any of these files. It can also reference a custom accessiblefields.yaml file. If you create a custom file, the name must end in accessiblefields.yaml.

Setting the filter to __inherit

You can also set the filter to __inherit. This means that the custom resource type inherits any additional accessible fields logic defined by its API parent. (The API parent is the resource that was defined as the parent when running the REST endpoint generator.)

Step 3: Configure the accessible fields in the accessiblefields.yaml file

Finally, in the appropriate accessiblefields.yaml files, add the new type to the accessibleFields section. Add both an edit: and view: subsection and specify the fields that are available when a caller has restricted access.

  • You can specify both fields directly on the resource (such as id) and child fields (such as Account.BillingPlan).

  • To specify no fields, use an empty list ([ ]).

BillingCenter throws a runtime exception if any of the following occur:

  • A type has an additional accessible fields filter expression, but the type is not listed in the accessiblefields.yaml file.

A type with a viewAndEdit additional accessible fields filter expression is listed in the accessiblefields.yaml file, but it does not have both edit and view subsections.

Sorting and filtering on accessible fields

Within a collection, a field can be sortable, which means that the collection is ordered based on the values of that field. A field can also be filterable, which means that the collection members can be filtered based on the field's value.

However, with additional accessible fields filters, a sortable or filterable field may not always be available to the caller. For example, suppose an account has four AccountContacts: the insured, the accounts clerk, and two additional insureds. Suppose that primaryPhone is sortable and filterable, but it is also restricted so that the producer cannot access primaryPhone for the third-party contacts. Sorting and filtering on primaryPhone could expose information about those values that the caller is not supposed to be allowed to see. What happens if the producer attempts to sort or filter on primaryPhone?

The behavior depends upon whether the collection is query-backed or stream-backed.

Query-backed collections

When a collection is query-backed, Cloud API lets you sort and filter on a field only if the field is available to all callers. In other words, every reference to the collection type in every accessiblefields.yaml file must specify that access to the field is always allowed. If access to the field is not granted to all callers, then sorting and filtering is not allowed on that field.

For example, suppose the AccountContacts collection is query-backed and that name and primaryPhone are sortable and filterable. Also, the restricted.accessiblefields.yaml file specifies the following:
accessibleFields:
 ...
 AccountContact:
   edit: []
   view:
   - id
   - name
 ...

name is available to all callers, even to callers with additional accessible field restrictions. Therefore, sorts and filters on name are allowed.

primaryPhone is not available to all callers. Those with additional accessible fields restrictions cannot see this field. Therefore, sorts and filters on primaryPhone are not allowed, even for callers with no additional accessible fields restrictions.

This behavior exists because a query-backed collection is not loaded into memory all at once. Rather, the collection is loaded one page at a time. Cloud API begins to build the response before it has loaded every page of the collection. Cloud API cannot know whether any member of the collection will be restricted by an additional accessible fields filter. Therefore, because there could be a member of the collection that requires restricted access, it cannot allow access to sorting and filtering on that field.

Stream-backed collections

When a collection is stream-backed, Cloud API lets you sort and filter on all sortable and filterable fields. However, if a field on a given resource is restricted to the caller, Cloud API treats the field's value as if it were null for the purpose of sorting and filtering.

For example, suppose the AccountContacts collection is stream-backed and that lastName and primaryPhone are sortable and filterable. Also, the appropriate accessiblefields.yaml file specifies the following:
accessibleFields:
 ...
 AccountContact:
   edit: []
   view:
   - id
   - lastName
 ...

Finally, suppose there are four AccountContacts in a collection:

  • Ray Newton (the insured); primary phone: 111-1111

  • Arnold Johnson (the accounts clerk); primary phone: 333-3333

  • Sue Thompson (an additional insured); primary phone: 222-2222

  • Virginia Green (an additional insured); primary phone: 444-4444

Aaron Applegate is a billing clerk who is not bound by additional accessible fields filters. If he sorts the collection based on primaryPhone, he will see this:

  1. Ray Newton; primary phone: 111-1111

  2. Sue Thompson; primary phone: 222-2222

  3. Arnold Johnson; primary phone: 333-3333

  4. Virginia Green; primary phone: 444-4444

Arnold Johnson is an accounts clerk who is bound by additional accessible fields filters and cannot view primaryPhone on additional insured contacts. If he sorts the collection based on primary phone, he will see this:

  1. Sue Thompson; primary phone: (null)

  2. Virginia Green; primary phone: (null)

  3. Ray Newton; primary phone: 111-1111

  4. Arnold Johnson; primary phone: 333-3333

Note that the Sue Thompson and Virginia Green AccountContacts have been sorted as if their primary phone values were null.

This behavior exists because the entire stream-backed collection is loaded into memory at one time. Thus, Cloud API knows which members of the collection are restricted by an additional accessible fields filter before it starts to build the response. It can permit sorting and filtering on the field, and it simply obfuscates the restricted information by treating it as null.

Filtering fields in a POST

It is possible to add an additional accessible fields filter that restricts which fields can be specified when POSTing a given type of resource. However, there are no instances of this in the base configuration.

The resource access extension file

The resource access extension file must specify the collection resource type. This is the resource name using a plural, such as Activities. The type must have an additionalAccessibleFieldsFilter property with a create sub-property. The syntax for this is:
<CollectionResourceType>:
  additionalAccessibleFieldsFilter:
    create: <expression>

The expression must return null or a string.

  • If the expression returns null, no additional restrictions are placed on the fields that can be specified when POSTing an instance of the given type.

  • If the expression returns a string, Cloud API looks in the integration > roles > additionalaccessiblefieldsfilters directory for a file that starts with the returned string and ends with accessiblefields.yaml. It then restricts the POST from specifying any fields not defined in that file.

The expression can make use of the following symbols:

  • user - The AuthorizedUser that Cloud API retrieved from the calling token

  • resource - The instance of the resource to be evaluated

  • data - The data envelope of the request payload.

The accessiblefields.yaml file

The accessiblefields.yaml file must specify the type. The type must have an edit property that defines the fields the caller cannot specify in the POST. If the caller cannot edit any fields on the resource, an empty list ([ ]) is specified. (Note that if the type must also have a view property if the resource access extension file specifies a viewAndEdit expression for that type.)

If the caller has an additional accessible fields filter restriction placed upon them and the caller specifies a restricted field in the POST, Cloud API throws an error.