---
title: Scripting environment
description: Configure the scripting engine in PingAM to execute server-side JavaScript or Groovy scripts with security settings, thread pool management, and Java class access controls
component: pingam
version: 7.5
page_id: pingam:am-scripting:scripting-env
canonical_url: https://docs.pingidentity.com/pingam/8.1/am-scripting/scripting-env.html
llms_txt: https://docs.pingidentity.com/pingam/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
page_aliases: ["script-engine-thread-pool.adoc", "script-engine-security.adoc", "scripting-guide:scripting-env.adoc"]
superseded_by: https://docs.pingidentity.com/pingam/8.1/am-scripting/scripting-env.html
section_ids:
  scripting_engine: Scripting engine
  scripting-env-java-classes: Access Java classes
  security_considerations: Security considerations
  thread_pools: Thread pools
---

# Scripting environment

AM supports server-side scripts written in either JavaScript or Groovy.

Next-generation scripts and client-side authentication scripts must be written in JavaScript.

## Scripting engine

PingAM implements a configurable scripting engine for each of the context types that are executed on the server.

![The scripting engines contain configuration for security settings and thread pool management.](_images/scripting-engine-overview.png)

PingAM uses the following libraries:

* Mozilla Rhino version 1.7.14 to run JavaScript.

  Rhino has limited support for ES6 / ES2015 (JavaScript version 1.7). For more information, refer to [Rhino ES2015 Support](https://mozilla.github.io/rhino/compat/engines.html).

* Groovy version 3.0.10 to support scripting in Groovy.

## Access Java classes

To access Java classes in a script, import classes in the following way:

* JavaScript

* Groovy

```javascript
var fr = JavaImporter(
    org.forgerock.openam.auth.node.api.Action,
    javax.security.auth.callback.NameCallback
);
// Now use fr.Action, fr.NameCallback, and so on.
```

```groovy
import org.forgerock.openam.auth.node.api.Action;
import javax.security.auth.callback.NameCallback;
```

Scripts can only import Java classes on the allowlist. PingAM defines an allowlist per script type.

Allowlists and denylists contain class names that are allowed or denied execution respectively.

Classes called by the script are checked against the allowlist first and must match at least one pattern in the list. The denylist is applied after the allowlist and classes matching any pattern are disallowed.

* Legacy scripts

  The legacy scripting engine lets you add classes to allowlists and denylists by specifying the class name or by using regular expressions.

  You can also configure the scripting engine to make an additional call to the JVM security manager for each class that is accessed. The security manager throws an exception if a class isn't allowed to execute.

  Learn more about allowlisting and configuring script engine security in the following topics:

  * [The scripting service](../reference/global-services-configuration.html#global-scripting)

  * [Access to Java class is prohibited error with scripts running in Advanced Identity Cloud and PingAM](https://support.pingidentity.com/s/article/Access-to-Java-class-is-prohibited-error-with-scripts-running-in-Advanced-Identity-Cloud-and-PingAM)

  |   |                                                                                                                                                                                                                                                                                                                               |
  | - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | To reduce the need to allowlist Java classes, consider migrating your scripts to use the [next-generation](next-generation-scripts.html) scripting engine, which includes enhanced built-in script bindings for accessing many common script operations and the ability to include third-party software with library scripts. |

* Next-generation scripts

  To enhance security, the next-generation scripting engine for decision node scripts doesn't support a configurable allowlist for Java classes.

  Instead, check if next-generation bindings provide the functionality you need or implement the functionality as a reusable library script.

  For information about next-generation bindings and library scripts, refer to:

  * [Migrate to next-generation scripts](next-generation-scripts.html#migrate-to-v2-steps)

  * [Reuse scripts](library-scripts.html)

  In cases where reimplementation isn't possible, you can [request](https://support.pingidentity.com/s/article/Raising-an-RFE) the functionality be included as a secure script binding in a future release.

## Security considerations

Consider the following points when configuring the security settings within each script engine:

* Use script bindings where possible

  The predefined script bindings provide a stable API without the need to allowlist Java classes. Different bindings are available to different script types, or *contexts*.

  For more information, refer to [Script bindings](script-bindings.html).

* The scripting engine only validates directly accessible classes

  The security settings only apply to classes that the script *directly* accesses. If the script calls `Foo.a()` and that method calls `Bar.b()`, the scripting engine will be unable to prevent it. You must consider the whole chain of accessible classes.

  |   |                                                                                                                                                                                                                                                                                                                                 |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | *Access* includes actions such as:- Importing or loading a class.

  - Accessing any instance of that class. For example, passed as a parameter to the script.

  - Calling a static method on that class.

  - Calling a method on an instance of that class.

  - Accessing a method or field that returns an instance of that class. |

* Potentially dangerous Java classes are denylisted by default

  All Java reflection classes (`java.lang.Class`, `java.lang.reflect.*`) are denylisted by default to avoid bypassing the security settings.

  The `java.security.AccessController` class is also denylisted by default to prevent access to the `doPrivileged()` methods.

  |   |                                                                    |
  | - | ------------------------------------------------------------------ |
  |   | Don't remove potentially dangerous Java classes from the denylist. |

* The allowlists and denylists match class or package names only

  The allowlist and denylist patterns apply only to the exact class or package names involved. The script engine does not know anything about inheritance, so it is best to allowlist known, specific classes.

## Thread pools

Each script is executed in an individual thread. Each scripting engine starts with an initial number of threads available for executing scripts. If no threads are available for execution, AM creates a new thread to execute the script, until the configured maximum number of threads is reached.

If the maximum number of threads is reached, pending script executions are queued in a number of buffer threads, until a thread becomes available for execution. If a created thread has completed script execution and has been idle for a configured time period, AM terminates the thread, shrinking the pool.

For more information on configuring script engine thread pools, refer to the [Scripting service](../reference/global-services-configuration.html#global-scripting).
