// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
= 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 link:https://docs.oracle.com/en/java/javase/11/security/java-se-platform-security-architecture.html#GUID-C203D80F-C730-45C3-AB95-D4E61FD6D89C[Java Sandbox model,window=_blank]
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
link:https://docs.oracle.com/javase/8/docs/technotes/guides/security/spec/security-spec.doc6.html#a19349[SecurityManager,window=_blank]
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 link:/docs/plugins[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:
[source,text]
----
[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 link:https://docs.oracle.com/en/java/javase/11/security/java-se-platform-security-architecture.html#GUID-DEA8EAB1-CF00-4658-AA6D-D2C9754C8B37[permissions,window=_blank]
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.

[source,java]
----
// 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:
[source,text]
----
java.security.AccessControlException: access denied ("java.util.PropertyPermission" "secret.property" "read")
----
