How to protect a set from being accessed

The Aerospike Knowledge Base has moved to https://support.aerospike.com. Content on https://discuss.aerospike.com is being migrated to either https://support.aerospike.com or https://docs.aerospike.com. Maintenance on articles stored in this repository ceased on December 31st 2022 and this article may be stale. If you have any questions, please do not hesitate to raise a case via https://support.aerospike.com.

How to protect a set from being accessed

Problem Description

Given all users with a role that allow read/write access to a namespace, is it possible to modify the role to prevent all those users to access a particular set?

Example:

Let’s use the following example where the role RoleAll has complete read/write access to the namespace test:

sql> show role RoleAll
+-----------+-------------------+-----------+
| role      | privileges        | whitelist |
+-----------+-------------------+-----------+
| "RoleAll" | "read-write.test" | ""        |
+-----------+-------------------+-----------+
1 row in set (0.001 secs)

The following command to modify the RoleAll role to have read-write access to the namespace test except for the set SetA, will actually not prevent this role to read or write into set SetA despite it returning success:

revoke privilege read-write.test.SetA from RoleAll

Explanation

The revoke command actually requires an exact match for the string to be removed from the privileges list. It will not return any error if the specified privilege does not exist.

aql> show role RoleAll
[
    {
      "role": "RoleAll",
      "privileges": "read-write.test, read-write.test.Set2, read-write.test.Set9",
      "whitelist": ""
    }
]

A privilege without specifying any set is applied to the entire namespace. Therefore, in the example above, the extra privileges related to sets are redundant.

Solution

As the feature to block list a specific set from a namespace is not supported as of the writing of this article, there are a couple of potential workarounds, neither of which is very elegant:

1- Move the set to be block listed in its own namespace in order to separately control access to it

To move the set to a new namespace, you can use the asrestore command:

   asrestore --namespace originalNamespace,newNamespace --set-list SetA, ....

The new namespace would of course need to be sized accordingly.

2- Explicitly define the sets that would be allowed to be accessed (and disallow the use of the null set).

  • Refer to the disallow-null-setname in order to prevent records from being created without a set name specified.

  • Modify the existing role by the removing the global privilege for the entire namespace and add privileges for each specific set:

   revoke privilege read-write.test from RoleAll
   grant privilege read-write.test.set1 to RoleAll
   grant privilege read-write.test.set2 to RoleAll
   grant privilege read-write.test.set3 to RoleAll
   .
   .
   .
   grant privilege read-write.test.set9 to RoleAll

One caveat, though: a role with 256 or more privileges can be safely created as long as the privileges are added to the role in groups of less than 256 (e.g. one at a time as this example does). The privileges will be correctly enforced by the server. Nevertheless, if a client requests the description of the role, that server-client communication is broken because at this point, the security message protocol prevents more than 255 privileges from being sent to the client.

One way to workaround this and make the role somewhat query-able through AQL or any client, is to create separate roles and then add those to the user:

create role Role1  privileges read-write.test.set10,read-write.test.set11,read-write.test.set12,read-write.test.set13,read-write.test.set14,read-write.test.set15,read-write.test.set16,read-write.test.set17,read-write.test.set18,read-write.test.set19
grant role Role1 TO user1
create role Role2  privileges read-write.test.set20,read-write.test.set21,read-write.test.set22,read-write.test.set23,read-write.test.set24,read-write.test.set25,read-write.test.set26,read-write.test.set27,read-write.test.set28,read-write.test.set29
grant role Role2 TO user1
create role Role3  privileges read-write.test.set30,read-write.test.set31,read-write.test.set32,read-write.test.set33,read-write.test.set34,read-write.test.set35,read-write.test.set36,read-write.test.set37,read-write.test.set38,read-write.test.set39
grant role Role3 TO user1
create role Role4  privileges read-write.test.set40,read-write.test.set41,read-write.test.set42,read-write.test.set43,read-write.test.set44,read-write.test.set45,read-write.test.set46,read-write.test.set47,read-write.test.set48,read-write.test.set49
grant role Role4 TO user1
.
.
.

As the maximum number of sets in a namespace is 1023, with 10 sets per role, the maximum of 1023 sets could be covered.

Notes

  • We are considering block lists of sets and/or wildcard pattern match. Check Aerospike Release notes for potential future enhancements.

Keywords

ACCESS CONTROL SECURITY SET ROLE ROLES PRIVILEGE

Timestamp

April 2020