Control access to shopper data

The Oracle Commerce access control system can be used to manage internal users' access to shopper data, such as profile properties.

Access to these properties is controlled using metadata attributes of the properties. You assign roles and generic access rights to these attributes to specify, for each individual property, which groups of internal users can access the property, and the type of access granted (either read, write, or both).

You can use property access control to support compliance with privacy laws such as the European Union General Data Protection Regulation (GDPR), by enforcing restrictions on who can access a shopper’s personal data. For example, you might want to allow an administrator to see all of the properties in a shopper’s profile, but allow customer service agents to see only a subset of the profile properties.

The following are the primary attributes used to control which users can read or write the value of a property:

  • readRole – You can set this attribute to the ID of a role. Users with the specified role can see the property value.
  • writeRole – You can set this attribute to the ID of a role. Users with the specified role can set or change the property value.
  • readAccessRight – You can set this attribute to the ID of an access right. Users with the specified access right can see the property value.
  • writeAccessRight – You can set this attribute to the ID of an access right. Users with the specified access right can set or change the property value.

By default, these attributes are null for any given property, which means that any user who is logged in can see and modify the property’s value. When you set one or more of these attributes, you are actually revoking access from users who lack the specified role or access right. Note that each attribute can only be set to a single ID.

A user’s ability to access properties is determined both by the roles the user has and by the access rights those roles have:

  • A user has read access to a property if the user has the role that is specified by the property’s readRole attribute, or if the user has a role that has the access right that is specified by the property’s readAccessRight attribute.
  • A user has write access to a property if the user has the role that is specified by a property’s writeRole attribute, or if the user has a role that has the access right that is specified by the property’s writeAccessRight attribute.

You should make sure that your settings for these attributes do not result in any users having write access to a property but not read access. Such a user would be able to modify the property’s values but not be able to see the changes he or she makes.

To avoid this situation, be careful when you set these attributes to ensure that the users with write access to a given property are a subset of those with read access. Here are some examples:

  • If you want all users to be able to see a property’s values, but want only administrators to be able to modify the values, then you could set the writeRole attribute to adminRole, and leave readRole null.
  • If you do not want any users to be able to edit the values of a property, you could set the writeAccessRight attribute to an access right that is not assigned to any roles (and therefore is not associated with any users). You can then use readRole or readAccessRight to assign read access as desired.
  • If you want a certain group of users to have read and write access to a property, but for no other users to have either form of access, you could set writeRole and readRole to the same role.

Note: Subsystems of Commerce that exchange data with external systems (for example, webhooks and bulk export and import) are not affected by property access control settings. If you want to restrict property access in these subsystems, you may need to implement access control on the external systems.

In addition, the Freemarker email templates included with Commerce are not affected by property access control settings. If you want to restrict property access in emails your store sends, you must manually remove properties from the templates. (See Customize Email Templates for more information.)

Configure the data to return

Properties have two attributes, readSecurityLevel and writeSecurityLevel, that control how Commerce responds when a user lacking the necessary role or access right attempts to access the property.

The readSecurityLevel attribute can be set to one of the following values:

  • ignore – Return a masking value rather than the actual value of the property. If readSecurityLevel is not set, it defaults to ignore.
  • deny – Omit the property from the response entirely. This option is available only for custom properties.

The writeSecurityLevel attribute can be set to one of the following values:

  • ignore – Attempts to modify the property value will fail silently. If writeSecurityLevel is not set, it defaults to ignore.
  • deny – Attempts to modify the property value will result in errors. Note, however, if the user attempts to set the value to the same value that was originally returned (that is, either the current value of the property or a masking value, depending on the user’s read access), no error will result. This is to handle cases where a form populated with current values attempts to write all of those values back when it is submitted. This option is available only for custom properties.

Note that the values of these attributes have an effect only if read or write access attributes are set on the property as well. For example, if the readSecurityLevel attribute is set to deny for a custom property, the property is omitted from a response only if read access is restricted by the readRole or readAccessRight attribute, and the user does not have the specified role or access right.

Return masking values

If the value of a property’s readSecurityLevel attribute is ignore, then attempts to access the property by users lacking the necessary access right or role return a placeholder called a masking value. The logic for determining the value is as follows:

  • If the property is not required, null is returned.
  • If the property is required, and its default value is set, the default value is returned. (Note that for a custom property that is required, the default value must be set.)
  • If the property is required, and its default value is not set, a generic value is returned. The value depends on the data type of the property:
    • String – the empty string
    • Numeric value -- 0
    • Date or timestamp -- Jan 1 1970
    • Enumeration -- the first enumerated value

You can override this logic by explicitly specifying a placeholder value for the property using the securityMaskingValue attribute. For example, you might want to set the placeholder value for strings to “XXXXX,” to make it clear that the actual value is being suppressed rather than empty. Note that the securityMaskingValue you specify must match the data type of the property.

Set the values of access control attributes

To set the access control attributes on specific properties, you use the endpoints in the Admin API for modifying the item type for those properties. For example, to configure access control on profile properties, you use the updateShopperType endpoint to modify the user shopper type.

The following example illustrates setting the role and access right attributes of a property, as well as its securityMaskingValue:

PUT /ccadmin/v1/shopperTypes/user  HTTP/1.1
Authorization: Bearer <access_token>
x-ccasset-language: en
Content-Type: application/json

{
 "properties": {
     "lastName": {
         "readRole": "audit",
         "writeRole": "audit",
         "readAccessRight": "ar10",
         "writeAccessRight": "ar10",
         "shopperReadable": true,
         "shopperWriteable": true,
         "securityMaskingValue": "XXXXX"
    }
  }
}

The response shows the attribute values you set:

...
"lastName": {
    "shopperWriteable": true,
    "readRole": "audit",
    "readSecurityLevel": null,
    "readAccessRight": "ar10",
    "securityMaskingValue": "XXXXX",
    "length": 254,
    "shopperReadable": true,
    "label": "Last Name",
    "type": "shortText",
    "writeSecurityLevel": null,
    "writeAccessRight": "ar10",
    "required": false,
    "searchable": false,
    "writable": true,
    "internalOnly": false,
    "uiEditorType": "shortText",
    "default": null,
    "audienceVisibility": null,
    "localizable": false,
    "textSearchable": false,
    "writeRole": "audit",
    "dimension": false,
    "editableAttributes": [
        "shopperWriteable",
        "readRole",
        "readSecurityLevel",
        "readAccessRight",
        "securityMaskingValue",
        "shopperReadable",
        "label",
        "writeSecurityLevel",
        "writeAccessRight",
        "required",
        "searchable",
        "internalOnly",
        "default",
        "audienceVisibility",
        "textSearchable",
        "writeRole",
        "dimension",
        "multiSelect"
    ],
    "multiSelect": null
},
...

These settings restrict both read and write access to only users that either have the audit role or the ar10 access right. If a user has neither of these and attempts to view a shopper’s profile, the lastName property value is masked in the response. For example:

...
"lastName": "XXXXX",
"GDPRProfileP13nConsentDate": null,
"GDPRProfileP13nConsentGranted": false,
"gender": "female",
...

Note that you should not set access-control attributes on a property that points to another object or collection of objects. Instead, set the attributes on the individual properties of the objects.

For a property that holds an array of strings or numeric values, you can set access-control attributes to specify access rights and roles, but you cannot set the securityMaskingValue attribute.