October 20th, Q&A session: Get you issues solved and questions answered!

GitHub logo
Edit

The Ignite Sandbox

Overview

Ignite allows executing custom logic via various APIs including compute tasks, event filters, message listeners. This user-defined logic can utilize Java APIs to get access to host resources. For example, it can create/update/delete files or system properties, open network connections, use reflection and other APIs to get full control of the host environment. Ignite Sandbox is based on the Java Sandbox model and allows you to restrict the scope of user-defined logic executed via Ignite APIs.

Ignite Sandbox Activation

The activation of Ignite Sandbox involves the configuration of an SecurityManager instance and creation of an GridSecurityProcessor implementation.

Install SecurityManager

Due to the fact, that Ignite Sandbox is based on the Java Sandbox model, and SecurityManager is an important part of that model, you need to have it installed. The SecurityManager is responsible for checking, which security policy is currently in effect. It also performs access control checks. The security manager is not automatically installed when an application is running. If you run Ignite as a separate application, you must invoke the Java Virtual Machine with the -Djava.security.manager command-line argument (which sets the value of the java.security.manager property). There is also a -Djava.security.policy command-line argument, defining, which policy files are utilized. If you don’t include -Djava.security.policy into the command line, then the policy files specified in the security properties file will be used.

Note
It may be convenient adding the security manager and the policy command-line arguments to {IGNITE-HOME}/bin/ignite.sh|ignite.bat script.
Note
Ignite should have enough permissions to work correctly. You may apply the most straightforward way that is granting to Ignite the java.security.AllPermission permission, but you should remember the "giving permissions as low as possible" security principle.

Provide GridSecurityProcessor Implementation

Currently, Apache Ignite does not provide an implementation of the GridSecurityProcessor interface out-of-the-box. But, you can implement this interface as a part of a custom plugin.

The GridSecurityProcessor interface has the sandboxEnabled method that manages a user-defined code execution inside the Ignite Sandbox. By default, this method returns false, which means no-sandbox. If you are going to use Ignite Sandbox, your overridden sandboxEnabled method needs to return true.

If the Ignite Sandbox is turned on, you can see the following trace line:

[INFO] Security status [authentication=on, sandbox=on, tls/ssl=off]

Permissions

A user-defined code is always executed on behalf of the security subject that initiates its execution. The security subject’s sandbox permissions define actions that a user-defined code can perform. The Ignite Sandbox retrieves those permissions using the SecuritySubject#sandboxPermissions method.

Note
A user-defined code, when running inside Ignite Sandbox, may use the public API of Ignite without granting any additional permissions.

If a security subject doesn’t have enough permissions to perform a security-sensitive operation, an AcccessControlException appears.

// Get compute instance over all nodes in the cluster.
IgniteCompute compute = Ignition.ignite().compute();

compute.broadcast(() -> {
    // If the Ignite Sandbox is turned on, the lambda code is executed with restrictions.

    // You can use the public API of Ignite without granting any permissions.
    Ignition.localIgnite().cache("some.cache").get("key");

    // If the current security subject doesn't have the java.util.PropertyPermission("secret.property", "read") permission,
    // a java.security.AccessControlException appears here.
    System.getProperty("secret.property");
});

In the case of accessing the system property shown in the snippet above, you can see the following trace line with an exception:

java.security.AccessControlException: access denied ("java.util.PropertyPermission" "secret.property" "read")