Cloudentity Configuration Promotion
Making use of Cloudentity configuration APIs to promote your workspace/tenant configuration from lower-level to higher-level environments. Discover the benefits of adopting a structured approach to configuration management and gain insights on how to effectively implement it for your organization.
Note
Test use only. Subject to potential functionality limitations, breaking changes, future updates, and removal without notice.
Configuration Promotion
Configuration promotion is the process of migrating validated configuration settings from a lower-level environment (e.g., development) to a higher-level environment (e.g., production). It ensures consistency, control, and traceability by minimizing manual configuration changes in the production environment, reducing the risk of errors and ensuring proper validation before deployment. It streamlines the deployment process and helps maintain a stable and reliable production environment.
Whether you're a new customer starting from scratch or a long-standing customer with complex configurations, familiarizing yourself with Configuration Promotion APIs and tools enables you to leverage the advantages of configuration promotion and automated configuration management effectively.
Prerequisites
Familiarization with Cloudentity REST APIs and what is required to properly access them.
A general understanding of the new import, export, and patch configuration APIs, their intended use-cases, and known limitations.
A client application for the System workspace, as described in the article about getting started with Cloudentity REST APIs, in both the source and target Cloudentity tenants.
A valid access token from your source and target Cloudentity tenants, by calling each client application's token endpoint.
Prepare your terminal for the subsequent
curl
commands.export SRC_TID={your source tenant’s ID} export TGT_TID={your target tenant’s ID} export REGION={your source tenant’s region: us, eu or au} export WID={your workspace’s ID} export SRC_ACCESS_TOKEN={system access token from your source tenant} export TGT_ACCESS_TOKEN={system access token from your source tenant} export CREDENTIALS={true or false, depending on your needs, suggestion: false} export INSERT_MODE={ignore, fail, or update, depending on your needs, suggestion: update} export EXPORT_FILE={the .json file containing the output of your export} export IMPORT_FILE={the .json file that will be used as the input for your import}
Take note of the Sample Input provided (below), based on the description of the necessary 'env' parameters (above). The subsequent commands in this section assume these parameter values have been set, can be accessed, and have appropriate values.
For overall ease-of-use, it might make sense to add these parameters to a file, that can be sourced by scripts and/or the terminal where the remaining commands will be run.
Sample input:
export SRC_TID=source-tenant export TGT_TID=target-tenant export REGION=us export WID=test-workspace1 export SRC_ACCESS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhaWQiOiJzeXN0ZW0iLCJhbXIiOltdLCJhdWQiOlsiMTU2MDQwNjI4MmYzNDI3Nzg1NzQ1YWM1MDk2NjYzYWYiLCJzcGlmZmU6Ly9zb3VyY2UtdGVuYW50LnVzLmF1dGh6LmNsb3VkZW50aXR5LmlvL3NvdXJjZS10ZW5hbnQvc3lzdGVtL3N5c3RlbS1pZGVudGl0eSIsInNwaWZmZTovL3NvdXJjZS10ZW5hbnQudXMuYXV0aHouY2xvdWRlbnRpdHkuaW8vc291cmNlLXRlbmFudC9zeXN0ZW0vc3lzdGVtLW9hdXRoMiIsInNwaWZmZTovL3NvdXJjZS10ZW5hbnQudXMuYXV0aHouY2xvdWRlbnRpdHkuaW8vc291cmNlLXRlbmFudC9zeXN0ZW0vc3lzdGVtLW1hbmFnZW1lbnQiXSwiZXhwIjoxNjg4OTUyNzI3LCJpYXQiOjE2ODg5NDkxMjcsImlkcCI6IiIsImlzcyI6Imh0dHBzOi8vc291cmNlLXRlbmFudC51cy5hdXRoei5jbG91ZGVudGl0eS5pby9zb3VyY2UtdGVuYW50L3N5c3RlbSIsImp0aSI6IjU4Y2JjNDE3LTdmMmEtNDIzZS04ZGFlLTQyZGUwZTA0NDJlMiIsIm5iZiI6MTY4ODk0OTEyNywic2NwIjpbImlkZW50aXR5IiwiaWRlbnRpdHlfc2VsZl9yZWdpc3RyYXRpb24iLCJpbnRyb3NwZWN0X3Rva2VucyIsIm1hbmFnZV9jb25maWd1cmF0aW9uwicmV2b2tlX3Rva2VucyIsInZpZXdfY2xpZW50cyIsInZpZXdfc2NvcGVzIl0sInN0IjoicHVibGljIiwic3ViIjoiMTU2MDQwNjI4MmYzNDI3Nzg1NzQ1YWM1MDk2NjYzYWYiLCJ0aWQiOiJzb3VyY2UtdGVuYW50In0.K6tRxjeUXvxL1d2BrQVh24i0XqEiwaKRM7WLLQyD0Rw export TGT_ACCESS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhaWQiOiJzeXN0ZW0iLCJhbXIiOltdLCJhdWQiOlsiMTU2MDQwNjI4MmYzNDI3Nzg1NzQ1YWM1MDk2NjYzYWYiLCJzcGlmZmU6Ly90YXJnZXQtdGVuYW50LnVzLmF1dGh6LmNsb3VkZW50aXR5LmlvL3RhcmdldC10ZW5hbnQvc3lzdGVtL3N5c3RlbS1pZGVudGl0eSIsInNwaWZmZTovL3RhcmdldC10ZW5hbnQudXMuYXV0aHouY2xvdWRlbnRpdHkuaW8vdGFyZ2V0LXRlbmFudC9zeXN0ZW0vc3lzdGVtLW9hdXRoMiIsInNwaWZmZTovL3RhcmdldC10ZW5hbnQudXMuYXV0aHouY2xvdWRlbnRpdHkuaW8vdGFyZ2V0LXRlbmFudC9zeXN0ZW0vc3lzdGVtLW1hbmFnZW1lbnQiXSwiZXhwIjoxNjg4OTUyNzI3LCJpYXQiOjE2ODg5NDkxMjcsImlkcCI6IiIsImlzcyI6Imh0dHBzOi8vdGFyZ2V0LXRlbmFudC51cy5hdXRoei5jbG91ZGVudGl0eS5pby90YXJnZXQtdGVuYW50L3N5c3RlbSIsImp0aSI6IjU4Y2JjNDE3LTdmMmEtNDIzZS04ZGFlLTQyZGUwZTA0NDJlMiIsIm5iZiI6MTY4ODk0OTEyNywic2NwIjpbImlkZW50aXR5IiwiaWRlbnRpdHlfc2VsZl9yZWdpc3RyYXRpb24iLCJpbnRyb3NwZWN0X3Rva2VucyIsIm1hbmFnZV9jb25maWd1cmF0aW9uwicmV2b2tlX3Rva2VucyIsInZpZXdfY2xpZW50cyIsInZpZXdfc2NvcGVzIl0sInN0IjoicHVibGljIiwic3ViIjoiMTU2MDQwNjI4MmYzNDI3Nzg1NzQ1YWM1MDk2NjYzYWYiLCJ0aWQiOiJ0YXJnZXQtdGVuYW50In0.-vZl9mmbHB62Tqwtj0rBpTxhOn9A5Lzzc62YxMLRJag export CREDENTIALS=false export INSERT_MODE=update export EXPORT_FILE=source_export.json export IMPORT_FILE=target_import.json
Note
The
SRC_ACCESS_TOKEN
andTGT_ACCESS_TOKEN
are obtained from the source and target tenants respectively, in the previous step.While not strictly necessary, if you are going to be directly running any of the commands below, having jq installed is highly encouraged. The first example
curl
command shows how the standardcurl -o
flag can be used, but all subsequentcurl
samples include a pipe tojq
.
Preparing Tenants for Workspace Configuration Promotion
For new Customers, especially those that have not yet created their Production tenant, there is very little preparation required in order to ensure readiness for configuration promotion.
Existing customers with more complex configurations, particularly those that have been manually configured, may need to take additional considerations to ensure preparedness.
In the upcoming sections, you will discover multiple options for seeding your tenant's workspace(s), tailored to different scenarios. Choose the path that aligns with your specific requirements. Whichever approach you select, the outcome will be well-prepared Cloudentity tenants ready for configuration promotion.
Importing Into Tenant where the Target Workspace Doesn't Exist
It is highly recommended for the initial import to be performed against a "fresh" Cloudentity tenant. This approach ensures a clean and well-structured starting point for a configuration management process based on configuration promotion.
Additional terminal/config file preparation.
Ensure your 'env' variable is set to
CREDENTIALS=false
. This will ensure new credentials are created for the new workspace in the target tenant.
Make the call to export the configuration for your workspace from the source tenant.
curl -s -X GET \ "https://$SRC_TID.$REGION.authz.cloudentity.io/api/hub/$SRC_TID/workspaces/$WID/promote/config?with_credentials=$CREDENTIALS" \ -H "Accept: application/json" \ -H "Authorization: Bearer $SRC_ACCESS_TOKEN" \ -o "$EXPORT_FILE"
CLI Help
If you have jq installed, you can replace the last line
-o "$EXPORT_FILE"
with| jq '.' > "$EXPORT_FILE"
to havejq
"pretty-print" the JSON Output from the export API call.Copy the exported configuration and make the necessary updates to it.
Understanding the Exported JSON Content
If you are using these APIs for the first time or working with a Cloudentity workspace that has complex configurations, it is recommended to review the
export.json
file prior to performing a find and replace. Search for occurrences of the 'source tenant ID'. They are most likely to be found in the 'uri' parameters, such as the "redirect_uris" of client applications and the "custom_audience" of services. In these cases, you need to replace the 'source tenant ID' with the 'target tenant ID'.Familiarizing yourself with these potential replacements helps you identify when and where such modifications may be necessary, particularly if you are not fully acquainted with these API endpoints yet.
sed "s/${SRC_TID}/${TGT_TID}/g" $EXPORT_FILE > $IMPORT_FILE
Make the call to import the configuration into your target tenant:
curl -v -X POST \ "https://$TGT_TID.$REGION.authz.cloudentity.io/api/hub/$TGT_TID/workspaces/$WID/promote/config?mode=$INSERT_MODE" \ -H "Accept: application/json" \ -H "Authorization: Bearer $TGT_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d @"$IMPORT_FILE"
The workspace should now exist in the target tenant, seeded with the configuration exported from the source tenant. Your Cloudentity tenants are now prepared for workspace configuration promotions.
Promoting Configuration Into Tenant where Workspace Exists
For Customers with Cloudentity tenants that were created before the introduction of these new configuration APIs , preparing for configuration promotion is more complicated.
Cloudentity tenants and workspaces that were created/configured manually can face issues with component id
mismatches between their environments. These components include things such as:
clients
services
IDPs
gateways
webhooks
custom apps
scripts
script execution points
themes
organisations
developers
softwares
SAML service providers
identity pools
post authentication apps
embedded clients for: server consent, IDPs, gateways, CIBA authentication services and custom apps
other embedded objects.
etc.
If your highest level Cloudentity tenant had ever had manual configuration applied via the AdminUI, this situation almost certainly applies to you. You have two primary options for preparing your Cloudentity tenants for configuration promotion:
Both options have their pros and cons. They share the same major drawback: both options require far more consideration and effort than the ideal scenario already described above.
Option 1 - Recreating the Workspace
The option to recreate your workspace(s) provides an ideal solution for resolving this conflict in the long term. By recreating the workspaces, you can achieve a state in your Cloudentity tenants that closely resembles those that have been able to employ the ideal preparation scenario.
However, it's important to note that this option may result in downtime and outages for certain downstream consumers, such as client applications and services, as their IDs/Secrets change during the recreation process. While this may initially seem challenging, it is actually recommended to use your highest-level Cloudentity tenant as the source and recreate all lower-level Cloudentity tenants to match its IDs.
Although this migration approach goes against the normal configuration migration flow, it ensures that any unexpected downtime occurs in the lower-level Cloudentity tenants, where the immediate business impact is considerably less.
Overall, choosing the option to recreate workspaces requires careful consideration of the potential downtime and impact on downstream consumers, but it offers a strategic approach to align your Cloudentity tenants and mitigate configuration management overhead in the long run.
An Opportunity For Upkeep And Practice
There are two additional benefits to this approach that are worth highlighting. Firstly, it reinforces the good practice of regularly rotating credentials, which is essential for maintaining security. Secondly, it provides an opportunity to address the cleanup tasks that are often neglected in lower-level environments. This includes identifying and eliminating any leftover development clients that generate unnecessary traffic and generate tokens that are never used.
Ensure that you have completed everything in the prerequisites section for your source and target tenant.
Create a backup of the target tenant's configuration before proceeding any further!
It is important to ensure you pass the query parameter
with_credentials=true
for this call. This ensures your backup contains everything, including the Cloudentity tenant's current credentials.
Warning
This step is not strictly necessary it is highly recommended. It ensures that you have a complete backup of your configuration, should anything unexpected happen; however, you shouldn't leave this backup lying around as it contains all the credentials from that tenant.
curl -s -X GET \ "https://$TGT_TID.$REGION.authz.cloudentity.io/api/hub/$TGT_TID/promote/config?with_credentials=true" \ -H "Accept: application/json" \ -H "Authorization: Bearer $TGT_ACCESS_TOKEN" \ | jq '.' > "target_tenant_full-export.json"
Optional -- Export the configuration for just the workspace from the target tenant
When This Optional Step Makes Sense
The purpose of this is to have a smaller, more specific JSON export, containing just the configuration for the workspace in its current state. This makes it easier to identify any potential changes made directly in this tenant, which weren't promoted (yet), and you may want to keep.
curl -s -X GET \ "https://$TGT_TID.$REGION.authz.cloudentity.io/api/hub/$TGT_TID/workspaces/$WID/promote/config?with_credentials=$CREDENTIALS" \ -H "Accept: application/json" \ -H "Authorization: Bearer $TGT_ACCESS_TOKEN" \ | jq '.' > "target_workspace_pre-recreation.json"
Using the AdminUI - Delete the workspace from the target tenant.
Select the Gear icon in the top-right corner, then click Workspaces.
Select the three dots button in the frame of the workspace that needs to be deleted.
Select Delete, then enter the workspace name to confirm the workspace deletion.
Proceed with the steps for importing a workspace into a tenant where it doesn't exist.
Optional -- Export the configuration of the workspace imported into your target tenant/
curl -s -X GET \ "https://$TGT_TID.$REGION.authz.cloudentity.io/api/hub/$TGT_TID/workspaces/$WID/promote/config?with_credentials=$CREDENTIALS" \ -H "Accept: application/json" \ -H "Authorization: Bearer $TGT_ACCESS_TOKEN" \ | jq '.' > "target_workspace_post-recreation.json"
Optional -- Compare the two workspace export JSON files with a
diff
tool.Determining the value of the differences
The resulting
diff
will contain a decent amount of "noise", and it may be worth delaying adiff
until/if missing or unexpected functionality is reported in that environment.Occurrences of strings that resemble this format
5d581d0703b64f19c40ef2d16b6e3cf0
are the IDs that were changed to match your higher-level environment. The value of these strings may result in the exported elements shifting positions, resulting in sections being highlighted as differences - incorrectly.
Though the steps in this section require more effort and consideration than if you were able to utilize the ideal preparation scenario more immediately, there are ancillary gains from this path, that should not be overlooked.
It's not unreasonable to believe that this effort results in better understanding of your overall environment, your Cloudentity configuration, and how you are now better positioned to implement automated configuration management, just to name a few.
Regardless, your Cloudentity tenants are now ready for workspace configuration promotions!
Option 2 - Mapping the IDs between Tenants
If political or technical constraints prevent you from adopting Option 1, you need to resolve the conflict arising from manually managed tenants/workspaces by mapping the configuration element IDs between environments.
This option is considered less desirable for addressing an imperfect state of Cloudentity tenants, primarily because the effort to map the configuration element IDs becomes an ongoing task. The mapping process should be consistent and repeatable to ensure automation of configuration promotion. It requires the creation and maintenance of a custom id-mapping-tool
to facilitate programmatic mapping.
There are far too many possible combinations of Cloudentity configurations, customer needs, and ID mapping processes to fully encompass every scenario. So, this section feels far less procedural that the previous sections.
Tip
Although this section does not provide specific procedural steps for actively updating your Cloudentity tenants, the prerequisites outlined above are still crucial. Ensure that you have completed everything in the prerequisites section, so that you can effectively apply the information below to your actual configuration data.
Identifying and Correlating IDs in Configuration Exports
The first step in creating a proper ID mapping solution is being able to identify the IDs, in configuration exports, that need to be mapped.
Export the workspace configuration from the source tenant.
curl -s -X GET \ "https://$SRC_TID.$REGION.authz.cloudentity.io/api/hub/$SRC_TID/workspaces/$WID/promote/config?with_credentials=$CREDENTIALS" \ -H "Accept: application/json" \ -H "Authorization: Bearer $SRC_ACCESS_TOKEN" \ | jq '.' > "source_workspace_export.json"
Export the workspace configuration from the target tenant
curl -s -X GET \ "https://$TGT_TID.$REGION.authz.cloudentity.io/api/hub/$TGT_TID/workspaces/$WID/promote/config?with_credentials=$CREDENTIALS" \ -H "Accept: application/json" \ -H "Authorization: Bearer $TGT_ACCESS_TOKEN" \ | jq '.' > "target_workspace_export.json"
Open the
source_workspace_export.json
andtarget_workspace_export.json
files with an editor to examine their contents.In the
source_workspace_export.json
file:If your editor supports RegEx, you can use this query string to locate IDs automatically generated by the Cloudentity AdminUI:
[a-f0-9]{32}
Example:
... "clients": { "34e48fb7d2d4b51f5e3a58ec010ca7be": { "client_name": "test", "description": "", ...
In the example above, the string
34e48fb7d2d4b51f5e3a58ec010ca7be
is matched by the RegEx[a-f0-9]{32}
, because it is a string with exactly32
characters that are onlya-f
or0-9
.The surrounding lines in the example were provided for context. They indicate that this ID represents a Client Application named
test
.Locate a similar client application, generated via the Cloudentity Admin Portal, in your source export file.
In the
targe_workspace_export.json
file:Locate the corresponding client application in your target export file.
Example:
... "clients": { "0cd9doe43ea6f6ebb804fcedccb58d77": { "client_name": "test", "description": "", ...
In the example above, we have now located the workspace's client application in both Cloudentity tenants.
The correlation between the ID
34e48fb7d2d4b51f5e3a58ec010ca7be
and the ID0cd9doe43ea6f6ebb804fcedccb58d77
needs to be incorporated into the ID mapping procedure.To address the ID mapping between the two Cloudentity tenants, the mapping correlation provided as an example above must be replicated for every ID that differs in the workspace exports.
Including discrepant IDs in other formats
Depending on your initial setup and configuration management to-date, this may include IDs that aren't in the
[a-f0-9]{32}
format.As an example, the following JSON shows two valid IDs for Client Applications that were created with the API, and would also need to be included in the ID mapping correlations.
From the source export:
... "clients": { "dev_client-ID_for_client-app_abc123": { "client_name": "Example Client App", "description": "", ...
From the target export:
... "clients": { "prod_client-ID_for_client-app_abc123": { "client_name": "Example Client App", "description": "", ...
The utilization of
diff
tools can be valuable in detecting non-conforming IDs that lack a readily identifiable pattern.
ID Mapping Procedure
Once you have identified and established correlations for all the discrepant IDs in your exports, you require an ID mapping procedure. This procedure can take various forms, even a manual process involving diff
and find/replace for each ID mapping correlation, if desired. Relying solely on diff
tools and implementing a manual ID mapping procedure is not recommended as a sustainable long-term solution.
It is crucial to note that when opting for the ID mapping approach, you must execute the ID mapping procedures prior to every configuration promotion. It is advisable to develop a repeatable, reliable, and efficient ID mapping procedure, ideally automated with the assistance of a dedicated tool.
The ID mapping procedure takes an export of your workspace from your source Cloudentity tenant as input and provides a modified version of that export as output. The output can then be used in the workspace configuration promotion procedures.
Expected Result of the ID Mapping Procedure
The desired outcome of the ID mapping procedure is a JSON file that represents the export from the source Cloudentity tenant workspace, where all the IDs have been replaced with the corresponding IDs from the target Cloudentity tenant workspace.
Performing Workspace Configuration Promotions
Once your Cloudentity tenants have been prepared for workspace configuration promotion, you can begin performing configuration promotions for your workspace.
The steps provided in this section serve as examples and for informational purposes. In all scenarios, it is highly recommended to automate the configuration promotion procedures, even with a basic level of automation. While sporadic manual execution may be manageable in low-level environments with infrequent changes, it can be challenging to maintain vigilance and adhere to best practices.
By embracing automation, you can ensure consistent and reliable configuration promotion, minimize human errors, and significantly enhance the efficiency of your configuration management.
Manually performing a Workspace Configuration Promotion
These steps assume that the Cloudentity tenants you are using have been prepared for workspace configuration promotion and that the prerequisites steps have recently been performed in your current terminal.
Additional Prerequisite
These steps utilize the Python JSON Merge Patch Library to generate JSON Merge Patches, in accordance with RFC 7396.
Please follow the instructions on the Python JSON Merge Patch Library README to install it or have an alternative tool, that creates JSON Merge Patch Documents - in accordance with the RFC 7396, readily available.
Ensure that there have been changes to the workspace in your source tenant.
If you are following these steps for their intended purpose, there is a high likelihood that the workspace configuration on your source tenant has not been changed.
For this example, we will create a very simple change in the source tenant's workspace configuration, to ensure that there is at least one change that needs to be promoted:
In the Admin Portal, navigate to the Demo Portal Client Application: Applications > Clients > Demo Portal
Add the following Description to the Client Application's Configuration:
This is a change worth promoting!
Save the change to the Demo Portal Client Application
Export the workspace configuration from your source tenant.
curl -s -X GET \ "https://$SRC_TID.$REGION.authz.cloudentity.io/api/hub/$SRC_TID/workspaces/$WID/promote/config?with_credentials=$CREDENTIALS" \ -H "Accept: application/json" \ -H "Authorization: Bearer $SRC_ACCESS_TOKEN" \ | jq '.' > "source_workspace_export.json"
Export the workspace configuration from your target tenant.
curl -s -X GET \ "https://$TGT_TID.$REGION.authz.cloudentity.io/api/hub/$TGT_TID/workspaces/$WID/promote/config?with_credentials=$CREDENTIALS" \ -H "Accept: application/json" \ -H "Authorization: Bearer $TGT_ACCESS_TOKEN" \ | jq '.' > "target_workspace_export.json"
Create a JSON Merge Patch Document, using the two export files.
Additional Step Required for ID Mapping
If the current Cloudentity tenants require an ID mapping procedure, please ensure to apply it to the
source_workspace_export.json
file before proceeding.json-merge-patch create-patch target_workspace_export.json source_workspace_export.json -o target_workspace_patch.json
Open the
target_workspace_patch.json
in an editor and observe the output.Ensure that the example change we made exists in this JSON Merge Document. Example:
"test-workspace1-demo": { "description": "This is a change worth promoting!", "redirect_uris": [ "https://source-tenant.us.authz.cloudentity.io/source-tenant/test-workspace1/demo" ], "updated_at": "2023-07-12T07:57:10.0734Z" }
Cleanup the
target_workspace_patch.json
, removing unnecessary elements like"redirect_uris"
,"updated_at"
time-stamps,"custom_audience"
, etc.If our test change was the only thing that was actually changed in your source Cloudentity tenant, we should expect to see a JSON Patch Document that only contains 7 lines with the following content:
{ "clients": { "g3-business-apps-demo": { "description": "This is a change worth promoting!" } } }
After reviewing the example from the previous step, it is evident that there are extraneous elements included in the JSON Patch Document. Despite the fact that it should only contain the 7 elements shown above, the actual document generated from the
json-merge-patch
for this example workspace exceeded 150 lines.While most of these extra elements do not pose any risk of being included in the
PATCH
request, it is important to note that items containing the source Cloudentity tenant ID carry a very minor risk and should be removed before making thePATCH
request.Avoid the "Cleanup" Step
The manual cleanup step requires minimal effort yet further emphasizes the benefits of a continuous, automated deployment model.
By regularly exporting the workspace from the source Cloudentity tenant and utilizing a
merge-patch-tool
to compare the previous and latest exports, the resulting patch document will contain only the actual changes made to the source Cloudentity tenant.Running the
merge-patch-tool
again with the workspace export from the target Cloudentity tenant and the created patch document will generate a final JSON Patch document that does not include any extraneous elements, requiring no additional cleanup (as shown the 7 line example above).Apply the Patch to the target tenant
curl -v -X PATCH \ "https://$TGT_TID.$REGION.authz.cloudentity.io/api/hub/$TGT_TID/workspaces/$WID/promote/config-rfc7396?mode=$INSERT_MODE" \ -H "Accept: application/json" \ -H "Authorization: Bearer $TGT_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d @"target_workspace_patch.json"
That's it! The configuration change made in the source Cloudentity tenant has now been successfully applied to the target Cloudentity tenant. The manual procedures were quick, simple, and easily repeatable, although they may seem cumbersome and inconvenient when compared to an automated version of these procedures.