---
title: Property value substitution
description: In an environment with multiple IG instances, you can require similar but not identical configurations across the different instances.
component: pinggateway
version: 7.2
page_id: pinggateway:reference:PropertyValueSubstitution
canonical_url: https://docs.pingidentity.com/pinggateway/2026/reference/PropertyValueSubstitution.html
llms_txt: https://docs.pingidentity.com/pinggateway/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
revdate: 2022-04-12T12:16:42Z
superseded_by: https://docs.pingidentity.com/pinggateway/2026/reference/PropertyValueSubstitution.html
section_ids:
  ConfigToken: Configuration Tokens
  token-filesys: Configuration Tokens for File System
  token-syntax: Syntax
  JsonEval: JSON Evaluation
  Resolvers: Token Resolution
  tokensub-route-resolver: Route Token Resolvers
  tokensub-env-variables: Environment Variables Resolver
  tokensub-sys-properties: System Properties Resolver
  tokensub-prop-files: Token Source File Resolvers
  TokenTransformation: Transformations
  Transformations-desc: Usage
  token-functions-array: array
  token-functions-bool: bool
  token-functions-decodeBase64: decodeBase64
  token-functions-encodeBase64: encodeBase64
  token-functions-int: int
  token-functions-list: list
  token-functions-number: number
  token-functions-object: object
  token-functions-string: string
---

# Property value substitution

In an environment with multiple IG instances, you can require similar but not identical configurations across the different instances.

Property value substitution enables you to do the following:

* Define a configuration that is specific to a single instance, for example, setting the location of the keystore on a particular host.

* Define a configuration whose parameters vary between different environments, for example, the URLs and passwords for test, development, and production environments.

* Disable certain capabilities on specific nodes.

Property value substitution uses *configuration tokens* to introduce variables into the server configuration. For information, see [Configuration Tokens](#ConfigToken).

The substitution follows a process of token resolution, JSON evaluation, and data transformation, as described in the following sections:

* [JSON Evaluation](#JsonEval)

* [Token Resolution](#Resolvers)

* [Transformations](#TokenTransformation)

## Configuration Tokens

A configuration token is a simple reference to a value. When configuration tokens are resolved, the result is always a string. Transformation described in [Transformations](#TokenTransformation) can be used to coerce the output type.

### Configuration Tokens for File System

IG provides `ig.instance.dir` and `ig.instance.url` to define the file system directory and URL for configuration files.

Their values are computed at startup, and evaluate to a directory such as `$HOME/.openig` (`%appdata%\OpenIG`). You can use these tokens in your configuration without explicitly setting their values.

For information about how to change the default values, see [Configure default location](../installation-guide/configure.html#configure-default-location).

### Syntax

Configuration tokens follow the syntax `&{token[|default]}`, as follows:

* Are preceded by an ampersand, `&`

* Are enclosed in braces, `{}`

* Define default values with a vertical bar (`|`) after the configuration token

* Are in lowercase

* Use the period as a separator, `.`

When a configuration token is supplied in a configuration parameter, it is always inside a string enclosed in quotation marks, as shown in the following example:

```json
"&{listen.port|8080}"
```

To escape a string with the syntax of a configuration token, use a backslash (`\`). The following string is treated as normal text:

```json
"\&{listen.port|8080}"
```

A configuration property can include a mix of static values and expressions, as shown in the following example:

```json
"&{hostname}.example.com"
```

Configuration tokens can be nested inside other configuration tokens as shown in the following example:

```json
"&{&{protocol.scheme}.port}"
```

Default values or values in the property resolver chain can be nested, as shown in the following example:

```json
"&{&{protocol.scheme|http}.port|8080}"
```

## JSON Evaluation

JSON evaluation is the process of substituting configuration tokens and transforming JSON nodes for an entire JSON configuration. After JSON evaluation, all configuration tokens and transformations in the configuration are replaced by values.

At startup, IG evaluates the configuration tokens in `config.json` and `admin.json`. When routes are deployed, IG evaluates the configuration tokens in the route.

Configuration tokens are matched with tokens available in the chain of resolvers, and the configuration token is substituted with the value available in the resolver. For information about each of the resolvers mentioned in the following section, see [Token Resolution](#Resolvers).

IG searches for matching tokens in the chain of resolvers, using the following order of precedence:

1. Local resolver:

   The route resolver for the route being deployed

2. Intermediate resolver:

   All intermediate route resolvers (for example, for parent routes to the route being deployed) up to the bootstrap resolver

3. Bootstrap resolver:

   1. Environment variables resolver

   2. System properties resolver

   3. Token source file resolvers

   4. Hardcoded default values

The first resolver that matches the token returns the value of the token.

If the token can't be resolved, IG uses the default value defined with the configuration token. If there is no default value, the token can't be resolved and an error occurs:

* If the configuration token is in `config.json` or `admin.json`, IG fails to start up.

* If the configuration token is in a route, the route fails to load.

When configuration tokens are nested inside other configuration tokens, the tokens are evaluated bottom-up, or leaf-first. For example, if the following configuration token takes only the default values, it is resolved as follows:

1. `"&{&{protocol.scheme|http}.port|8080}"`

2. `"&{http.port|8080}"`

   When `&{protocol.scheme|http}` takes the default value `http`.

3. `"8080"`

   When `&{http.port|8080}` takes the default value `8080`.

If the configuration includes a transformation, IG applies the transformation after the token is substituted. When transformations are nested inside other transformations, the transformations are applied bottom-up, or leaf-first. For more information, see [Transformations](#TokenTransformation).

## Token Resolution

At startup, the bootstrap resolver builds a chain of resolvers to resolve configuration tokens included in `config.json` and `admin.json`. When a route is deployed, *route resolvers* build on the chain to add resolvers for the route.

### Route Token Resolvers

When a route is deployed in IG a route resolver is created to resolve the configuration tokens for the route. The resolvers uses token values defined in the `properties` section of the route.

If the token can't be resolved locally, the route resolver accesses token values recursively in a parent route.

For more information, about route properties, see [Route properties](Properties.html).

### Environment Variables Resolver

When the bootstrap resolver resolves a configuration token to an environment variable, it replaces the lowercase and periods (`.`) in the token to match the convention for environment variables.

Environment variable keys are transformed as follows:

* Periods (.) are converted to underscores

* All characters are transformed to uppercase

The following example sets the value of an environment variable for the port number:

```bash
$ export LISTEN_PORT=8080
```

In the following IG configuration, the value of `port` is `8080`:

```json
{
  "port": "&{listen.port}"
}
```

### System Properties Resolver

The system property name must match a configuration token exactly. The following example sets a system property for a port number:

```bash
$ java -Dlisten.port=8080 -jar start.jar
```

In the following IG configuration, the value of `port` is `8080`:

```json
{
  "port": "&{listen.port}"
}
```

### Token Source File Resolvers

Token source files have the `.json` or `.properties` extension. The bootstrap resolver uses the files to add file resolvers to the chain of resolvers:

* **JSON file resolvers**

  Token source files with the `.json` extension take a JSON format. The token name is mapped either to the JSON attribute name or to the JSON path.

  Each of the following `.json` files set the value for the configuration token `product.listen.port`:

  ```json
  {
    "product.listen.port": 8080
  }
  ```

  ```json
  {
    "product.listen": {
       "port": 8080
    }
  }
  ```

  ```json
  {
    "product": {
      "listen": {
        "port": 8080
      }
    }
  }
  ```

* **Properties file resolvers**

  Token source files with the `.properties` extension are Java properties files. They contain a flat list of key/value pairs, and keys must match tokens exactly.

  The following `.properties` file also sets the value for the tokens `listen.port` and `listen.address`:

  ```properties
  listen.port=8080
  listen.address=192.168.0.10
  ```

Token source files are stored in one or more directories defined by the environment variable `IG_ENVCONFIG_DIRS` or the system property `ig.envconfig.dirs`.

If token source files are in multiple directories, each directory must be specified in a comma-separated list. IG doesn't scan subdirectories. The following example sets an environment variable to define two directories that hold token source files:

```bash
$ export IG_ENVCONFIG_DIRS="/myconfig/directory1,/myconfig/directory2"
```

At startup, the bootstrap resolver scans the directories in the specified order, and adds a resolver to the chain of resolvers for each token source file in the directories.

Although the bootstrap resolver scans the directories in the specified order, within a directory it scans the files in a nondeterministic order.

Note the following constraints for using the same configuration token more than once:

* Do not define the same configuration token more than once in a single file. There is no error, but you won't know which token is used.

* Do not define the same configuration token in more than one file in a single directory. An error occurs.

  |   |                                                                                                                                          |
  | - | ---------------------------------------------------------------------------------------------------------------------------------------- |
  |   | This constraint implies that you can't have backup `.properties` and `.json` files in a single directory if they define the same tokens. |

* You can define the same configuration token once in several files that are located in different directories, but the first value that IG reads during JSON evaluation is used.

  |   |                                                                                                                                                                                                                                                                                                       |
  | - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | When logging is enabled at the DEBUG level for token resolvers, the origin of the token value is logged.If you are using the default logback implementation, add the following line to your `logback.xml` to enable logging:```xml
  <logger name="org.forgerock.config.resolvers" level="DEBUG" />
  ``` |

## Transformations

A set of built-in transformations are available to coerce strings to other data types. The transformations can be applied to any string, including strings resulting from the resolution of configurations tokens.

After transformation, the JSON node representing the transformation is replaced by the result value.

The following sections describe how to use transformations, and describe the transformations available:

### Usage

```json
{
   "$transformation": string or transformation
}
```

A transformation is a JSON object with a required main attribute, starting with a `$`. The following example transforms a string to an integer:

```json
{"$int": string}
```

The value of a transformation value can be a JSON string or another transformation that results in a string. The following example shows a nested transformation:

```json
{
  "$array": {
    "$base64:decode": string
  }
}
```

The input string must match the format expected by the transformation. In the previous example, because the final transformation is to an array, the input string must be a string that represents an array, such as `"[ \"one\", \"two\" ]"`.

In the first transformation, the encoded string is transformed to a base64-decoded string. In the second, the string is transformed into a JSON array, for example, `[ "one", "two" ]`.

### array

```json
{"$array": string}
```

Returns a JSON array of the argument.

| Argument                                      | Returns                                |
| --------------------------------------------- | -------------------------------------- |
| * string

  String representing a JSON array. | - array

  JSON array of the argument. |

The following example transformation results in the JSON array `[ "one", "two" ]`:

```json
{"$array": "[ \"one\", \"two\" ]"}
```

### bool

```json
{"$bool": string}
```

Returns `true` if the input value equals `"true"` (ignoring case). Otherwise, returns `false`.

| Argument                                                  | Returns                                                 |
| --------------------------------------------------------- | ------------------------------------------------------- |
| * string

  String containing the boolean representation. | - boolean

  Boolean value represented by the argument. |

If the configuration token `&{capture.entity}"` resolves to `"true"`, the following example transformation results in the value `true`:

```json
{"$bool": "&{capture.entity}"}
```

### decodeBase64

```json
{
  "$base64:decode": string,
  "$charset": "charset"
}
```

Transforms a base64-encoded string into a decoded string. If `$charset` is specified, the decoded value is interpreted with the character set.

| Argument                           | Parameters                                                                                                                                                                   | Returns                                                       |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| * string

  Base64-encoded string. | - $charset

  The name of a Java character set, as described in [Class Charset](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/charset/Charset.html). | * string

  Base64-decoded string in the given character set. |

The following example transformation returns the `Hello` string:

```json
{
 "$base64:decode": "SGVsbG8=",
 "$charset": "UTF-8"
}
```

### encodeBase64

```json
{
  "$base64:encode": string,
  "$charset": "charset"
}
```

Transforms a string into a base64-encoded string. Transforms to `null` if the string is `null`.

If `$charset` is specified, the string is encoded with the character set.

| Argument                                                   | Parameters                                                                                                                                                                   | Returns                            |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| * string

  String to encode with the given character set. | - $charset

  The name of a Java character set, as described in [Class Charset](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/charset/Charset.html). | * string

  Base64-encoded string. |

### int

```json
{"$int": string}
```

Transforms a string into an integer.

If the parameter is not a valid number in radix 10, returns `null`.

| Argument                                                  | Returns                                             |
| --------------------------------------------------------- | --------------------------------------------------- |
| * string

  String containing the integer representation. | - int

  Integer value represented by the argument. |

The following example transformation results in the integer `1234`:

```json
{"$int": "1234"}
```

### list

```json
{"$list": string}
```

Transforms a comma-separated list of strings into a JSON array of strings

| Argument                                                             | Returns                                                                                       |
| -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| * string

  A string representing a comma-separated list of strings. | - array

  The JSON array of the provided argument. Values are not trimmed of leading spaces. |

The following example transformation results in the array of strings `["Apple","Banana","Orange","Strawberry"]`:

```json
{"$list": "Apple,Banana,Orange,Strawberry"}
```

The following example transformation results in the array of strings `["Apple"," Banana"," Orange"," Strawberry"]`, including the untrimmed spaces:

```json
{"$list": "Apple, Banana, Orange, Strawberry"}
```

The following example transformation results in the array of strings `["1","2","3","4"]`, and not an array of JSON numbers `[1,2,3,4]`:

```json
{"$list": "1,2,3,4"}
```

### number

```json
{"$number": string}
```

Transform a string into a Java number, as defined in [Class Number](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Number.html).

| Argument                                                    | Returns                                                   |
| ----------------------------------------------------------- | --------------------------------------------------------- |
| * strings

  A string containing the number representation. | - number

  The number value represented by the argument. |

The following example transformation results in the number `0.999`:

```json
{"$number": ".999"}
```

### object

```json
{"$object": string}
```

Transforms a string representation of a JSON object into a JSON object.

| Argument                                            | Returns                                  |
| --------------------------------------------------- | ---------------------------------------- |
| * string

  String representation of a JSON object. | - object

  JSON object of the argument. |

The following example transformation

```json
{"$object": "{\"ParamOne\":{\"InnerParamOne\":\"InnerParamOneValue\",\"InnerParamTwo\": false}}"}
```

results in the following JSON object:

```json
{
  "ParamOne": {
    "InnerParamOne": "myValue",
    "InnerParamTwo": false
  }
}
```

### string

```json
{"$string": placeholder string}
```

Transforms a string representation of a JSON object into a placeholder string. Placeholder strings are not encrypted.

Use this transformation for placeholder strings that that must not be encrypted.

| Argument                                            | Returns                                     |
| --------------------------------------------------- | ------------------------------------------- |
| * string

  String representation of a JSON object. | - placeholder string

  Placeholder string. |

This example transformation:

```json
{
  "someAttributeExpectingString": { "$string": "&{ig.instance.dir}" }
}
```

results in this JSON object:

```json
{
  "someAttributeExpectingString": "/path/to/ig"
}
```
