This is a prerelease version.

View latest

Client Authorization

To protect your members from a malicious client, you can allow them to identify clients and restrict their permissions to access data in data structures or use features such as user code deployment.

The Authentication overview describes how authentication is used for verifying credentials, and roles mapping. This section describes how the assigned role names are used to map permissions to clients.

Hazelcast client authorization is configured by a client permission policy. Hazelcast has a default permission policy implementation that uses permission configurations defined in the Hazelcast security configuration. Default policy permission checks are made against instance types (map, queue, etc.), instance names, instance actions (put, read, remove, add, etc.), the client endpoint address (ClusterEndpointPrincipal), and client roles (ClusterRolePrincipal).

The default permission policy allows you to use comma separated names in the principal attribute configuration.

Unless part of the role name, don’t include spaces when adding names to the principal attribute.

Hazelcast doesn’t automatically remove spaces in role names. If you include spaces that aren’t part of the name, permission isn’t granted to the intended role.

For example, if you configure permissions for the admin and devel roles using principal=" admin ,devel", the admin role isn’t granted the permission.

You can define the instance and principal names as wildcards using the "*" character. For more information, see Using Wildcards.

The endpoint names can use range characters "-" and "*" as described in the Interfaces section.

  • XML

  • YAML

<hazelcast>
    ...
    <security enabled="true">
        <client-permissions>
            <!-- Principals 'admin' and 'root' from endpoint '127.0.0.1' have all permissions. -->
            <all-permissions principal="admin,root">
                <endpoints>
                    <endpoint>127.0.0.1</endpoint>
                </endpoints>
            </all-permissions>

            <!-- Principals named 'dev' from all endpoints have 'create', 'destroy',
            'put', 'read' permissions for map named 'myMap'. -->
            <map-permission name="myMap" principal="dev">
                <actions>
                    <action>create</action>
                    <action>destroy</action>
                    <action>put</action>
                    <action>read</action>
                </actions>
            </map-permission>

            <!-- All principals from endpoints '127.0.0.1' or matching to '10.10.*.*'
            have 'put', 'read', 'remove' permissions for map
            whose name matches to 'com.foo.entity.*'. -->
            <map-permission name="com.foo.entity.*">
                <endpoints>
                    <endpoint>10.10.*.*</endpoint>
                    <endpoint>127.0.0.1</endpoint>
                </endpoints>
                <actions>
                    <action>put</action>
                    <action>read</action>
                    <action>remove</action>
                </actions>
            </map-permission>

            <!-- Principals named 'dev' from endpoints matching either
            '192.168.1.1-100' or '192.168.2.*'
            have 'create', 'add', 'remove' permissions for all queues. -->
            <queue-permission name="*" principal="dev">
                <endpoints>
                    <endpoint>192.168.1.1-100</endpoint>
                    <endpoint>192.168.2.*</endpoint>
                </endpoints>
                <actions>
                    <action>create</action>
                    <action>add</action>
                    <action>remove</action>
                </actions>
            </queue-permission>

           <!-- All principals from all endpoints have transaction permission.-->
           <transaction-permission />
       </client-permissions>
    </security>
    ...
</hazelcast>
hazelcast:
  security:
    enabled: true
    client-permissions:
      on-join-operation: RECEIVE
      all:
        principal: admin,root
        endpoints:
          - 127.0.0.1
      map:
        - name: myMap
          principal: dev
          endpoints:
            - 127.0.0.1
          actions:
            - create
            - destroy
            - put
            - read
      map:
        - name: com.foo.entity
          principal: dev
          endpoints:
            - 10.10.*.*
            - 127.0.0.1
          actions:
            - put
            - read
            - remove
      queue:
        - name: "*"
          principal: dev
          endpoints:
            - 192.168.1.1-100
            - 192.168.2.*
          actions:
            - create
            - add
            - remove
      transaction:

You can also define your own policy by implementing com.hazelcast.security.IPermissionPolicy.

package com.hazelcast.security;
/**
 * IPermissionPolicy is used to determine any Subject's
 * permissions to perform a security sensitive Hazelcast operation.
 *
 */
public interface IPermissionPolicy {
  void configure( SecurityConfig securityConfig, Properties properties );

  PermissionCollection getPermissions( Subject subject,
                                       Class<? extends Permission> type );

  void destroy();
}

Permission policy implementations can access client-permissions that are in the configuration by using SecurityConfig.getClientPermissionConfigs() when Hazelcast calls the configure(SecurityConfig securityConfig, Properties properties) method.

The IPermissionPolicy.getPermissions(Subject subject, Class<? extends Permission> type) method is used to determine a client request that has been granted permission to perform a security-sensitive operation.

The permission policy should return a PermissionCollection containing permissions of the given type for the given Subject. The Hazelcast access controller calls PermissionCollection.implies(Permission) on returning PermissionCollection and decides whether the current Subject has permission to access the requested resources.

Permissions

All Hazelcast clients authorized to connect to a cluster are able to receive proxy information for data structures present on the cluster. This proxy only provides the client with the data structure’s type and name. Permissions for other actions related to these data structures can be configured as required.

The following is the list of client permissions that can be configured on the member:

All permissions

<all-permissions> grants clients access to all data and features. The client specified in the following code example is used by Hazelcast Management Center when it connects to clusters. To learn more about this client, see Cluster Connections.

  • XML

  • YAML

<all-permissions principal="principal">
    <endpoints>
        ...
    </endpoints>
</all-permissions>
all:
  principal: principal
  endpoints:
    - ..

Management Permission

<management-permission> defines which client principals/endpoints are allowed to perform management tasks.

For Hazelcast Management Center to work properly, management-permission is not sufficient. all-permissions is required.
  • XML

  • YAML

<management-permission principal="mcadmin">
    <endpoints>
        ...
    </endpoints>
</management-permission>
management:
  principal: mcadmin
  endpoints:
    - ..

Map permission

Actions: all, create, destroy, index, intercept, listen, lock, put, read, remove .

  • XML

  • YAML

<map-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</map-permission>
map:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Queue permission

Actions: add, all, create, destroy, listen, read, remove.

  • XML

  • YAML

<queue-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</queue-permission>
queue:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

MultiMap permission

Actions: all, create, destroy, listen, lock, put, read, remove.

  • XML

  • YAML

<multimap-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
     </actions>
</multimap-permission>
multimap:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Replicated map permission

Actions: all, create, destroy, index, intercept, listen, lock, put, read, remove.

  • XML

  • YAML

<replicatedmap-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
     </actions>
</replicatedmap-permission>
replicatedmap:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Topic permission

Actions: create, destroy, listen, publish.

  • XML

  • YAML

<topic-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</topic-permission>
topic:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Reliable topic permission

Actions: create, destroy, listen, publish.

  • XML

  • YAML

<reliable-topic-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</reliable-topic-permission>
reliable-topic:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

List permission

Actions: add, all, create, destroy, listen, read, remove.

  • XML

  • YAML

<list-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</list-permission>
list:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Set permission

Actions: add, all, create, destroy, listen, read, remove.

  • XML

  • YAML

<set-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</set-permission>
set:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Ringbuffer permission

Actions: add, put, read, create, destroy.

  • XML

  • YAML

<ringbuffer-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</ringbuffer-permission>
ringbuffer:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Lock permission

Actions: all, create, destroy, lock, read.

  • XML

  • YAML

<lock-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</lock-permission>
lock:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

AtomicLong permission

Actions: all, create, destroy, modify, read.

  • XML

  • YAML

<atomic-long-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</atomic-long-permission>
atomic-long:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

AtomicReference permission

Actions: all, create, destroy, modify, read.

  • XML

  • YAML

<atomic-reference-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</atomic-reference-permission>
atomic-reference:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

CountDownLatch permission

Actions: all, create, destroy, modify, read.

  • XML

  • YAML

<countdown-latch-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</countdown-latch-permission>
countdown-latch:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

FlakeIdGenerator permission

Actions: all, create, destroy, modify, read.

  • XML

  • YAML

<flake-id-generator-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</flake-id-generator-permission>
flake-id-generator:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Semaphore permission

Actions: all, acquire, create, destroy, read, release.

  • XML

  • YAML

<semaphore-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</semaphore-permission>
semaphore:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Executor Service Permission

Actions: all, create, destroy

  • XML

  • YAML

<executor-service-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</executor-service-permission>
executor-service:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Durable executor service permission

Actions: all, create, destroy.

  • XML

  • YAML

<durable-executor-service-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</durable-executor-service-permission>
durable-executor-service:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Scheduled executor service permission

Actions: all, create, destroy, read, modify.

  • XML

  • YAML

<scheduled-executor-service-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</scheduled-executor-service-permission>
scheduled-executor-service:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Cardinality estimator permission

Actions: all, create, destroy, read, modify.

  • XML

  • YAML

<cardinality-estimator-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</cardinality-estimator-permission>
cardinality-estimator:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

PN counter permission

Actions: all, create, destroy, read, modify.

  • XML

  • YAML

<pn-counter-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</pn-counter-permission>
pn-counter:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

Transaction permission

  • XML

  • YAML

<transaction-permission principal="principal">
    <endpoints>
        ...
    </endpoints>
</transaction-permission>
transaction:
  principal: principal
  endpoints:
    - ..

Cache permission

Actions: all, create, destroy, listen, put, read, remove.

  • XML

  • YAML

<cache-permission name="/hz/cache-name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</cache-permission>
cache:
  - name: /hz/cache-name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..
The name provided in cache-permission must be the Hazelcast distributed object name that corresponds to the Cache as described in the JCache - Hazelcast Instance Integration section.

Vector collection permission (Beta)

Actions: all, create, destroy, put, read, remove, optimize.

  • XML

  • YAML

<vector-collection-permission name="name" principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</vector-collection-permission>
vector-collection:
  - name: name
    principal: principal
    endpoints:
      - ..
    actions:
      - ..

User Code Deployment permission

Actions: all, deploy/

User Code Deployment has been deprecated and will be removed in the next major version. To continue deploying your user code after this time, Community Edition users can either upgrade to Enterprise Edition, or add their resources to the Hazelcast member class paths. Hazelcast recommends that Enterprise Edition users migrate their user code to use User Code Namespaces for all purposes other than Jet stream processing. For further information on migrating from User Code Deployment to User Code Namespaces, see Migrate from User Code Deployment.
  • XML

  • YAML

<user-code-deployment-permission principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</user-code-deployment-permission>
user-code-deployment:
  principal: principal
  endpoints:
    - ..
  actions:
    - ..

If you have migrated to User Code Namespaces, use the following permissions:

  • XML

  • YAML

<user-code-namespace-permission principal="principal">
    <endpoints>
        ...
    </endpoints>
    <actions>
        ...
    </actions>
</user-code-namespace-permission>
user-code-namespace:
  principal: principal
  endpoints:
    - ..
  actions:
    - ..

Configuration permission

This permission defines which client principals/endpoints are allowed to add data structure configurations at runtime.

  • XML

  • YAML

<config-permission principal="principal">
    <endpoints>
        <endpoint>...</endpoint>
    </endpoints>
</config-permission>
config:
  principal: principal
  endpoints:
    - ..

Job permission

Actions:

  • submit: Submit a new job, without uploading resources.

  • cancel: Cancel a running job.

  • read: Get or list information about a job (by ID or name) such as job configuration, job status, and submission time.

    When you query a streaming source with SQL, Hazelcast runs that query as a job. As a result, clients with the read permission for jobs can see the SQL query and any parameters.
  • restart: Suspend and resume a running job.

  • export-snapshot: Export or read snapshots.

  • add-resources: Upload resources and classes as well as jobs to members.

    Hazelcast can’t check permissions in code that’s uploaded with a job, If you enable this permission, clients can upload custom code that ignores any configured permissions.
  • all: Enable all actions.

All actions for job permissions also enable the read action. For example, if you enable the create action, the read action is automatically enabled as well.

  • XML

  • YAML

<job-permission principal="principal">
    <actions>
        <action>...</action>
    </actions>
</job-permission>
job:
  - principal: "principal"
    actions:
      - ..

Connector permission

You can give permissions to the following connectors:

  • File

  • Socket

Actions:

  • read: Read data from sources.

  • write: Write data to sinks.

  • all: Enable all actions.

  • XML

  • YAML

File Connector
<!-- It is currently only possible to give access to a whole directory, not to a single file. -->
<connector-permission name="file:directory_name">
    <actions>
        <action>...</action>
    </actions>
</connector-permission>
Socket Connector
<connector-permission name="socket:host:port">
    <actions>
        <action>...</action>
    </actions>
</connector-permission>
File Connector
connector:
  - name: "file:directory_name"
    actions:
      - ..
Socket Connector
connector:
  - name: "socket:host:port"
    actions:
      - ..
To protect external systems from being reached by external connectors (JDBC, Mongo, S3, …​), use other means than Hazelcast client permissions. Traditionally, this is done by enabling authentication on the external system and/or setting up firewall rules.

SQL permission

You can give clients permission to use the following SQL statements:

Actions:

  • create: Use the CREATE MAPPING statement to create new mappings or replace existing ones.

  • destroy: Use the DROP MAPPING statement to delete mappings.

  • create-index: Use the CREATE INDEX statement to create a new index for a map.

  • create-view: Use the CREATE VIEW statement to create new views or replace existing ones.

  • drop-view: Use the DROP VIEW statement to delete an existing view.

  • create-dataconnection: Use the CREATE DATA CONNECTION statement to create new data connections or replace existing ones.

  • drop-dataconnection: Use the DROP DATA CONNECTION statement to delete data connections.

  • view-dataconnection: Use the SHOW RESOURCES statement to view the resources and data types accessible via data connections.

  • all: Enable all actions.

To apply permissions to certain mappings or data connections, provide their names in the name attribute. Or, you can apply permissions to all mappings and data connections using the * wildcard.

  • XML

  • YAML

Apply permissions to a mapping
<sql-permission name="mapping_name">
  <actions>
    <action>create</action>
    <action>destroy</action>
  </actions>
</sql-permission>
Apply permissions to all mappings
<sql-permission name="*">
  <actions>
    <action>create</action>
    <action>destroy</action>
  </actions>
</sql-permission>
Apply permissions to a data connection
<sql-permission name="data_connection_name">
  <actions>
    <action>drop-dataconnection</action>
    <action>view-dataconnection</action>
  </actions>
</sql-permission>
Apply permissions to a mapping
sql:
  - name: "mapping_name"
    actions:
      - create
      - destroy
Apply permissions to all mappings
sql:
  - name: "*"
    actions:
      - create
      - destroy
Apply permissions to a data connection
sql:
  - name: "data_connection_name"
    actions:
      - drop-dataconnection
      - view-dataconnection

Handling permissions when a new member joins

By default, the set of permissions defined in the leader member of a cluster is distributed to new members that join, overriding their own permission configurations, if any. However, you can configure a new member to join but keep its own set of permissions and even send these to the existing members in the cluster. This can be done dynamically, without needing to restart the cluster, using either one of the following configuration options:

  • the on-join-operation configuration attribute

  • the setOnJoinPermissionOperation() method

You can use these options to choose whether a new member joining to a cluster will apply the client permissions stored in its own configuration, or use the ones defined in the cluster. The behaviors that you specify with the configuration are RECEIVE, SEND and NONE, which are described after the examples below.

The following examples show how to use both approaches:

Declarative configuration:

  • XML

  • YAML

<hazelcast>
    ...
    <security enabled="true">
        <client-permissions on-join-operation="SEND">
            <!-- ... -->
        </client-permissions>
    </security>
    ...
</hazelcast>
hazelcast:
  security:
    enabled: true
    client-permissions:
      on-join-operation: SEND

Programmatic configuration:

Config config = new Config();
config.getSecurityConfig()
    .setEnabled(true)
    .setOnJoinPermissionOperation(OnJoinPermissionOperationName.SEND);

The behaviors are explained below:

  • RECEIVE: Applies the permissions from the leader member in the cluster before joining. This is the default value.

  • SEND: Doesn’t apply the permissions from the leader member before joining. If security is enabled, then it refreshes or replaces the cluster wide permissions with the ones in the new member after it joins. This option is suitable for scenarios where you need to replace the cluster-wide permissions without restarting the cluster.

  • NONE: Neither applies pre-join permissions nor sends the local permissions to the other members. It means that the new member doesn’t send its own permission definitions to the cluster, but keeps them when it joins. However, after the join, when you update the permissions in the other cluster members, those updates are also sent to the new member. Therefore, this option is suitable for scenarios where you need to elevate privileges temporarily on a single member (preferably a lite member) for a limited time period. The clients which need to use these temporary permissions have to access the cluster through this single new member, meaning that you need to configure the SINGLE_MEMBER cluster routing mode for such clients.

    Note that the create and destroy permissions won’t work when using the NONE option, since the distributed objects need to be created/destroyed on all the members.

    The following is an example for a scenario where NONE is used:

    // temporary member, in the below case a lite member
    Config config = new Config().setLiteMember(true);
    PermissionConfig allPermission = new PermissionConfig(PermissionType.ALL, "*", null);
    config.getSecurityConfig()
      .setEnabled(true)
      .setOnJoinPermissionOperation(OnJoinPermissionOperationName.NONE)
      .addClientPermissionConfig(allPermission);
    HazelcastInstance hzLite = Hazelcast.newHazelcastInstance(config);
    
    // temporary client connecting only to the lite member
    String memberAddr = ...;
    ClientConfig clientConfig = new ClientConfig();
    clientConfig.getNetworkConfig().setSmartRouting(false)
      .addAddress(memberAddr);
    HazelcastInstance client = HazelcastClient.newHazelcastClient(clientConfig);
    
    // do operations with escalated privileges:
    client.getMap("protectedConfig").put("master.resolution", "1920");
    
    // shutdown the client and lite member
    client.shutdown();
    hzLite.shutdown();

Deny permissions

Hazelcast employs additive access control as its default security mechanism. When a client connects to a security-enabled cluster, it is initially granted no permissions. As a result, access to protected resources is inherently denied unless explicit permissions are configured and granted to specific roles.

The additive access control approach has limited expression capabilities and is not well-suited for configurations involving simple exclusions. For example, it’s challenging to allow access to all maps except the one named "private".

To address this limitation, Hazelcast introduces the concept of deny permissions (or deny rules).

Within the permission configuration, there is a boolean flag called deny that enables permission subtraction.

  • XML

  • YAML

<hazelcast>
    ...
    <security enabled="true">
        <client-permissions>
            <!-- Grant access to all maps. -->
            <map-permission name="*">
                <actions>
                    <action>all</action>
                </actions>
            </map-permission>
            <!-- Deny access to the "private" map. -->
            <map-permission name="private" deny="true">
                <actions>
                    <action>all</action>
                </actions>
            </map-permission>
       </client-permissions>
    </security>
    ...
</hazelcast>
hazelcast:
  security:
    enabled: true
    client-permissions:
      map:
        - name: *
          actions:
            - all
        - name: private
          deny: true
          actions:
            - all

Priority of grant and deny permissions

By default, when a permission is both granted and denied, the denial takes precedence. In other words, if conflicting permissions exist, denial prevails.

In certain scenarios, it might be beneficial to reverse this behavior and give higher priority to permission grants. Hazelcast supports this by introducing the boolean flag priority-grant, which can be set to true.

  • XML

  • YAML

<hazelcast>
    ...
    <security enabled="true">
        <client-permissions  priority-grant="true">
        ...
       </client-permissions>
    </security>
    ...
</hazelcast>
hazelcast:
  security:
    enabled: true
    client-permissions:
      priority-grant: false

Permission evaluation table

The table below illustrates how permission evaluation changes when priority-grant is configured:

Permission Implication priority-grant=false (default) priority-grant=true

No Grant or Deny Implication

Implication from Grant only

Implication from Deny only

Both Grant and Deny Imply