Configure trees
The following table summarizes the high-level tasks required to configure authentication trees:
Task | Resources | ||
---|---|---|---|
Design your user authentication journey Authentication trees are flexible. For example, the same tree can branch for different use cases, or users can be forced to loop though branches until they’re able to present the required credentials. It’s easy to create a massive tree that’s difficult to understand, read, and maintain in the UI. For this reason, AM lets you nest trees within trees. The best way to tackle the design decision is to write down a list of required steps users would need to take to sign on to your environment. Then, check the list of nodes available in AM.
|
|
||
Decide if you need custom nodes If the nodes available in AM or in the Marketplace don’t meet your needs, you can create your own scripted node types or build your own nodes in Java. |
|||
Decide if you need webhooks or tree hooks You can create custom webhooks or post-authentication hooks for nodes that need them. |
|||
Configure your authentication trees Use the authentication tree designer to quickly configure a tree or use the REST API. |
|||
Configure webhooks, if required If you have configured the |
Create an authentication tree in the UI
-
In the AM admin UI, go to Realms > Realm Name > Authentication > Trees and click Create Tree.
-
Enter a tree name, for example
myAuthTree
, and click Create.The authentication tree designer displays with the Start entry point connected to the Failure exit point.
The authentication tree designer provides the following features on the toolbar:
Authentication tree designer toolbar Button Usage Lay out and align nodes according to the order they’re connected.
Toggle the designer window between normal and full screen layout.
Remove the selected node. You can’t delete the Start entry point.
-
Add a node to the tree by dragging the node from the Components panel on the left-hand side, and dropping it into the designer area.
The list of authentication nodes is divided into categories. Click the category title to expand and collapse the categories.
Use the filter text field to restrict the list of authentication nodes. This will match on the node’s name and any tags applied to the node:
-
Configure the node properties by using the right-hand panel.
You can find more information on the available properties for each node in Node reference.
-
Connect the node to the tree as follows:
-
Select and drag the output connector from an existing node and drop it onto the new node.
-
Select and drag the output connector from the new node and drop it onto an existing node.
Nodes have one or more connectors, displayed as dots on the node. Unconnected connectors appear red until you connect them to other nodes in the tree.
Input connectors appear on the left of the node, output connectors appear on the right. A line is drawn between the connectors of connected nodes, and the connectors no longer appear red.
-
-
To change a connection, select and drag the green connector in the connection and drop it onto the new location.
-
Continue adding, connecting and removing nodes until the tree is complete, then click Save.
-
Test your authentication tree by navigating to a URL similar to the following:
https://am.example.com:8443/am/XUI/?realm=/alpha&service=myAuthTree#login
Create an authentication tree over REST
To create an authentication tree over REST, send individual PUT requests to create each node. Then send a PUT request to update the tree configuration, including the tree ID and all the nodes in the tree. You can find information on the required parameters in the online REST API reference.
Consider the following when creating authentication trees using the REST API:
-
You must re-create each node when creating a new authentication tree.
-
Each node must have a valid UUID as its identifier. You can generate UUIDs online, for example, using the Online UUID Generator.
If you don’t use a valid UUID, authentication will fail with the following error:
ERROR: Could not get SMS service: authenticationTreesService java.lang.IllegalArgumentException: Invalid UUID string: 12345
-
The
entryNodeId
field specified when creating the authentication tree is the UUID of the first node in the tree. -
The
outcome
field specified when creating the authentication tree is the UUID of the next node. This allows you to move between nodes. -
The Success and Failure nodes have the following static UUIDs:
-
Success node:
70e691a5-1e33-4ac3-a356-e7b6d60d92e0
-
Failure node:
e301438c-0bd0-429c-ab0c-66126501069a
These UUIDs remain constant across all authentication trees and AM versions.
-
Example
Complete these steps to create a simple authentication tree consisting of three nodes: Username Collector node, Password Collector node, and Data Store Decision node.
-
Generate UUIDs for each of the nodes you want to create. This example uses the following UUIDs:
-
Username Collector node:
8f9d2280-caa7-433f-93a9-1f64f4cae60a
-
Password Collector node:
54f14341-d1b7-436f-b159-d1f9b6c626eb
-
Data Store Decision node:
3fc7ce22-fc79-4131-85f2-f1844709d042
-
-
Authenticate to AM as the
amAdmin
user:$ curl \ --request POST \ --header "Content-Type: application/json" \ --header "X-OpenAM-Username: amadmin" \ --header "X-OpenAM-Password: password" \ --header "Accept-API-Version: resource=2.0, protocol=1.0" \ 'https://am.example.com:8443/am/json/realms/root/realms/alpha/authenticate' { "tokenId":"AQIC5wM…TU3OQ*", "successUrl":"/am/console", "realm":"/alpha" }
-
Create the Username Collector node, where the UUID is the one you generated in step 1:
$ curl \ --request PUT \ --header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: protocol=2.1,resource=1.0" \ --header "If-None-Match: *" \ --data '{ "_id": "8f9d2280-caa7-433f-93a9-1f64f4cae60a", "_type": { "_id": "UsernameCollectorNode", "name": "Username Collector" } }' \ "https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/UsernameCollectorNode/8f9d2280-caa7-433f-93a9-1f64f4cae60a" { "_id": "8f9d2280-caa7-433f-93a9-1f64f4cae60a", "_rev": "280717409", "_type": { "_id": "UsernameCollectorNode", "name": "Username Collector", "collection": true }, "_outcomes": [ { "id": "outcome", "displayName": "Outcome" } ] }
-
Create the Password Collector node, where the UUID is the one you generated in step 1:
$ curl \ --request PUT \ --header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: protocol=2.1,resource=1.0" \ --header "If-None-Match: *" \ --data '{ "_id": "54f14341-d1b7-436f-b159-d1f9b6c626eb", "_type": { "_id": "PasswordCollectorNode", "name": "Password Collector" } }' \ "https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PasswordCollectorNode/54f14341-d1b7-436f-b159-d1f9b6c626eb" { "_id": "54f14341-d1b7-436f-b159-d1f9b6c626eb", "_rev": "792175357", "_type": { "_id": "PasswordCollectorNode", "name": "Password Collector", "collection": true }, "_outcomes": [ { "id": "outcome", "displayName": "Outcome" } ] }
-
Create the Data Store Decision node, where the UUID is the one you generated in step 1:
$ curl \ --request PUT \ --header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: protocol=2.1,resource=1.0" \ --header "If-None-Match: *" \ --data '{ "_id": "3fc7ce22-fc79-4131-85f2-f1844709d042", "_type": { "_id": "DataStoreDecisionNode", "name": "Data Store Decision" } }' \ "https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/DataStoreDecisionNode/3fc7ce22-fc79-4131-85f2-f1844709d042" { "_id": "3fc7ce22-fc79-4131-85f2-f1844709d042", "_rev": "2145625368", "_type": { "_id": "DataStoreDecisionNode", "name": "Data Store Decision", "collection": true }, "_outcomes": [ { "id": "true", "displayName": "True" }, { "id": "false", "displayName": "False" } ] }
-
Create the authentication tree with these three nodes, where the UUIDs are the ones you used to create the nodes. Make sure you set
entryNodeId
to the UUID of the first node and set theoutcome
of each node to the UUID of the next node:$ curl \ --request PUT \ --header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: protocol=2.1,resource=1.0" \ --header "If-None-Match: *" \ --data '{ "entryNodeId": "8f9d2280-caa7-433f-93a9-1f64f4cae60a", "nodes": { "8f9d2280-caa7-433f-93a9-1f64f4cae60a": { "displayName": "Username Collector", "nodeType": "UsernameCollectorNode", "connections": { "outcome": "54f14341-d1b7-436f-b159-d1f9b6c626eb" } }, "54f14341-d1b7-436f-b159-d1f9b6c626eb": { "displayName": "Password Collector", "nodeType": "PasswordCollectorNode", "connections": { "outcome": "3fc7ce22-fc79-4131-85f2-f1844709d042" } }, "3fc7ce22-fc79-4131-85f2-f1844709d042": { "displayName": "Data Store Decision", "nodeType": "DataStoreDecisionNode", "connections": { "false": "e301438c-0bd0-429c-ab0c-66126501069a", "true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0" } } } }' \ "https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myNewTree" { "_id": "myNewTree", "_rev": "2061817222", "uiConfig": {}, "entryNodeId": "8f9d2280-caa7-433f-93a9-1f64f4cae60a", "innerTreeOnly": false, "nodes": { "8f9d2280-caa7-433f-93a9-1f64f4cae60a": { "displayName": "Username Collector", "nodeType": "UsernameCollectorNode", "connections": { "outcome": "54f14341-d1b7-436f-b159-d1f9b6c626eb" } }, "54f14341-d1b7-436f-b159-d1f9b6c626eb": { "displayName": "Password Collector", "nodeType": "PasswordCollectorNode", "connections": { "outcome": "3fc7ce22-fc79-4131-85f2-f1844709d042" } }, "3fc7ce22-fc79-4131-85f2-f1844709d042": { "displayName": "Data Store Decision", "nodeType": "DataStoreDecisionNode", "connections": { "false": "e301438c-0bd0-429c-ab0c-66126501069a", "true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0" } } }, "enabled": true }
-
Verify the tree has been created in the AM admin UI. It should look similar to this:
Enable and disable an authentication tree
Custom authentication trees are enabled by default when you save them. For security purposes, you can disable custom authentication trees during development and testing to prevent accidentally allowing access through these trees. Rather than having unused authentication trees enabled, you should disable the default authentication trees until you need them.
When a user attempts to authenticate through a disabled tree, AM returns a No configuration found
error.
To enable or disable an authentication tree, send a PUT request to update the tree configuration. Include the tree ID
and all the nodes in the tree, and set the enabled
property.
You can find information on the required parameters in the
online REST API reference.
Example
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"nodes": {
...
},
"enabled": false
}' \
"https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myAuthTree"
{
"_id": "myAuthTree",
"_rev": "2070284866",
"uiConfig": {},
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"innerTreeOnly": false,
"nodes": {
...
},
"staticNodes": {
"startNode": {
"x": 50,
"y": 25
},
"70e691a5-1e33-4ac3-a356-e7b6d60d92e0": {
"x": 570,
"y": 30
},
"e301438c-0bd0-429c-ab0c-66126501069a": {
"x": 573,
"y": 107
}
},
"enabled": false
}
Disable direct access through an inner tree
An inner tree or child tree lets you nest authentication logic. There is no limit to the depth of nesting.
You configure an inner tree like any other tree then call it from a parent tree using an Inner Tree Evaluator node.
You could want to hide inner trees as complete services. In other words, you could want to prevent users from authenticating directly through an inner tree, either for security reasons or because the inner tree is insufficient as a complete authentication service.
To prevent a tree from being used outside of its parent tree, set the innerTreeOnly
property to true
in the tree
configuration. Send a PUT request to update the tree configuration, including the tree ID and all the nodes in the tree.
You can find information on the required parameters in the
online REST API reference.
Example
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"nodes": {
...
},
"innerTreeOnly": true
}' \
"https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myAuthTree"
{
"_id": "myAuthTree",
"_rev": "1081620278",
"uiConfig": {},
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"innerTreeOnly": true,
"nodes": {
...
},
"staticNodes": {
"startNode": {
"x": 50,
"y": 25
},
"70e691a5-1e33-4ac3-a356-e7b6d60d92e0": {
"x": 570,
"y": 30
},
"e301438c-0bd0-429c-ab0c-66126501069a": {
"x": 573,
"y": 107
}
},
"enabled": true
}
Specify IDM identity resources in trees
When running AM as part of an integrated platform with IDM,
trees configured to use the platform need to identify
the type of identity resource or object the tree is working with.
To do this, use the identityResource
configuration property.
If the property isn’t included in the tree configuration, it defaults to managed/user
.
To update identityResource
on a tree, use the REST API to update the tree:
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId":"e301438c-0bd0-429c-ab0c-66126501069a",
"nodes":{},
"staticNodes":{},
"description":"Example tree description",
"identityResource":"managed/newObjectType"
}' \
"https://am.example.com:8443/am/json/realms/root/realm-config/authentication/authenticationtrees/trees/ExampleTree"
In the previous example, the tree ExampleTree
has no nodes added to it yet.
It includes the identityResource
property, set to use a managed object in IDM called newObjectType
.
Because this is a PUT
request, you must include the entire tree as part of the request.
You can find more information about using the REST API in REST in AM.
Configure an authentication tree to always run
You can configure a tree to always run, whether a user authenticated successfully and a session exists or not. If enabled, the tree runs even when the session was created through a different tree and irrespective of the value of the ForceAuth parameter.
You can’t set a tree to always run when it’s set as the default authentication service. Also, to prevent unexpected behavior in the authentication flow, don’t configure the tree to always run when it’s mapped to the default acr. |
If a user successfully signs on using a specific authentication tree and then tries to reauthenticate to the same tree while the session is still valid, the default behavior is for the authentication flow to skip the processing of the tree. For example, the Set Session Properties node is never run in this scenario:

However, to make sure the tree always runs and sets the session property even when a valid authenticated session exists,
set the mustRun
property to true
in the tree configuration.
To do this, send a PUT request to update the tree configuration including the tree ID and all the nodes in the tree. Find information on the required parameters in the online REST API reference.
Example
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId": "83fa0ce2-1b0f-4f8f-83fb-0d2648339797",
"nodes": {
"83fa0ce2-1b0f-4f8f-83fb-0d2648339797": {
"displayName": "Page Node",
"nodeType": "PageNode",
"x": 437,
"y": 187,
"connections": {
"outcome": "8113abc2-9bbe-4510-a676-bb4cb1dba6a6"
}
},
"2e0fb163-98d1-4ae1-88da-24d7f39cee1e": {
"displayName": "Set Session Properties",
"nodeType": "SetSessionPropertiesNode",
"x": 468,
"y": 20,
"connections": {
"outcome": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0"
}
},
"adec5f3d-db07-4e2d-bd9e-2aedfe95b636": {
"displayName": "Scripted Decision",
"nodeType": "ScriptedDecisionNode",
"x": 38,
"y": 113,
"connections": {
"noSession": "83fa0ce2-1b0f-4f8f-83fb-0d2648339797",
"sessionExists": "2e0fb163-98d1-4ae1-88da-24d7f39cee1e"
}
},
"8113abc2-9bbe-4510-a676-bb4cb1dba6a6": {
"displayName": "Data Store Decision",
"nodeType": "DataStoreDecisionNode",
"x": 686,
"y": 214,
"connections": {
"false": "e301438c-0bd0-429c-ab0c-66126501069a",
"true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0"
}
}
},
"mustRun": true
}' \
"https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myAuthTree"
{
"_id": "myAuthTree",
"_rev": "71943491",
"uiConfig": {},
"entryNodeId": "83fa0ce2-1b0f-4f8f-83fb-0d2648339797",
"innerTreeOnly": false,
"nodes": {
"83fa0ce2-1b0f-4f8f-83fb-0d2648339797": {
"displayName": "Page Node",
"nodeType": "PageNode",
"x": 437,
"y": 187,
"connections": {
"outcome": "8113abc2-9bbe-4510-a676-bb4cb1dba6a6"
}
},
"2e0fb163-98d1-4ae1-88da-24d7f39cee1e": {
"displayName": "Set Session Properties",
"nodeType": "SetSessionPropertiesNode",
"x": 468,
"y": 20,
"connections": {
"outcome": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0"
}
},
"adec5f3d-db07-4e2d-bd9e-2aedfe95b636": {
"displayName": "Scripted Decision",
"nodeType": "ScriptedDecisionNode",
"x": 38,
"y": 113,
"connections": {
"noSession": "83fa0ce2-1b0f-4f8f-83fb-0d2648339797",
"sessionExists": "2e0fb163-98d1-4ae1-88da-24d7f39cee1e"
}
},
"8113abc2-9bbe-4510-a676-bb4cb1dba6a6": {
"displayName": "Data Store Decision",
"nodeType": "DataStoreDecisionNode",
"x": 686,
"y": 214,
"connections": {
"false": "e301438c-0bd0-429c-ab0c-66126501069a",
"true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0"
}
}
},
"staticNodes": {
"startNode": {
"x": 20,
"y": 20
},
"70e691a5-1e33-4ac3-a356-e7b6d60d92e0": {
"x": 913,
"y": 31
},
"e301438c-0bd0-429c-ab0c-66126501069a": {
"x": 932,
"y": 305
}
},
"mustRun": true,
"enabled": true
}
Configure journey session duration in a tree
The maximum duration of a journey session is derived by AM as described in Maximum duration.
You can override global and realm level duration values in an individual tree if required. For example, a tree that requires email verification could have a longer duration than a simple tree that authenticates users with a username and password.
Duration values set in a tree can be overridden at the node level. Learn more in Maximum duration. Additionally, duration values set on inner trees are ignored. |
Learn more in Suspend journey progress.
To change the authentication tree duration, set the treeTimeout
property to the required number of minutes in the tree configuration.
Send a PUT request to update the tree configuration, including the tree ID and all the nodes in the tree. You can find information on the
required parameters in the online REST API reference.
Example
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"nodes": {
...
},
"treeTimeout": 10
}' \
"https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myAuthTree"
{
"_id": "myAuthTree",
"_rev": "1081620278",
"uiConfig": {},
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"innerTreeOnly": false,
"nodes": {
...
},
"staticNodes": {
"startNode": {
"x": 50,
"y": 25
},
"70e691a5-1e33-4ac3-a356-e7b6d60d92e0": {
"x": 570,
"y": 30
},
"e301438c-0bd0-429c-ab0c-66126501069a": {
"x": 573,
"y": 107
}
},
"treeTimeout": 10,
"enabled": true
}
Configure authenticated session timeouts in a tree
Timeout settings for an authenticated session are derived by AM as described in Configure authenticated session timeout settings.
You can override global and realm level timeout values in an individual tree if required. For example, a tree that implements MFA could have a longer authenticated session timeout than a simple tree that authenticates users with a username and password.
Session timeouts set in a tree can be overridden at the node or user level. Learn more in Configure authenticated session timeout settings. Session timeout values set on inner trees are ignored. However, if session timeouts are set at the node level in an inner tree, the updated timeouts are used in the parent tree. |
Learn more in Session termination.
To change the session timeouts in a tree, set the maximumSessionTime
and maximumIdleTime
properties to the
required number of minutes in the tree configuration. Send a PUT request to update the tree configuration, including the tree ID and all the
nodes in the tree. You can find information on the required parameters in the
online REST API reference.
Example
The following example sets the maximumSessionTime
to an hour and the maximumIdleTime
to 15 minutes for
authenticated sessions established through this tree:
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"nodes": {
...
},
"maximumSessionTime": 60,
"maximumIdleTime": 15
}' \
"https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myAuthTree"
{
"_id": "myAuthTree",
"_rev": "1081620278",
"uiConfig": {},
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"innerTreeOnly": false,
"nodes": {
...
},
"staticNodes": {
"startNode": {
"x": 50,
"y": 25
},
"70e691a5-1e33-4ac3-a356-e7b6d60d92e0": {
"x": 570,
"y": 30
},
"e301438c-0bd0-429c-ab0c-66126501069a": {
"x": 573,
"y": 107
}
},
"maximumSessionTime": 60,
"maximumIdleTime": 15,
"enabled": true
}
Configure a no session tree
A no session tree doesn’t result in an authenticated session when it successfully completes.
A common use case for a no session tree is a delegated admin task, such as an administrator changing a user’s password. In this scenario, you don’t want an authenticated session to be created when the administrator enters the credentials of the user whose password they are changing.
This can also be achieved by setting the If the |
To configure a no session tree, set the noSession
property to true
in the tree configuration.
Send a PUT request to update the tree configuration, including the tree ID and all the nodes in the tree. You can find information on the
required parameters in the online REST API reference.
Example
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"nodes": {
...
},
"noSession": true
}' \
"https://am.example.com:8443/am/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myAuthTree"
{
"_id": "myAuthTree",
"_rev": "1081620278",
"uiConfig": {},
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"innerTreeOnly": false,
"nodes": {
...
},
"staticNodes": {
"startNode": {
"x": 50,
"y": 25
},
"70e691a5-1e33-4ac3-a356-e7b6d60d92e0": {
"x": 570,
"y": 30
},
"e301438c-0bd0-429c-ab0c-66126501069a": {
"x": 573,
"y": 107
}
},
"noSession": true,
"enabled": true
}