Skip to main content

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

  1. Familiarization with Cloudentity REST APIs and what is required to properly access them.

  2. A general understanding of the new import, export, and patch configuration APIs, their intended use-cases, and known limitations.

  3. 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.

  4. A valid access token from your source and target Cloudentity tenants, by calling each client application's token endpoint.

  5. 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 and TGT_ACCESS_TOKEN are obtained from the source and target tenants respectively, in the previous step.

  6. 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 standard curl -o flag can be used, but all subsequent curl samples include a pipe to jq.

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.

  1. 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.

  2. 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 have jq "pretty-print" the JSON Output from the export API call.

  3. 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               
  4. 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.

  1. Ensure that you have completed everything in the prerequisites section for your source and target tenant.

  2. 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"                  
  3. 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"                  
  4. 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.

  5. Proceed with the steps for importing a workspace into a tenant where it doesn't exist.

  6. 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"                  
  7. 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 a diff 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 and target_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 exactly 32 characters that are only a-f or 0-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 ID 0cd9doe43ea6f6ebb804fcedccb58d77 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.

  1. 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

  2. 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"                  
  3. 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"                  
  4. 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                  
  5. 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"
    }                  
  6. 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 the PATCH 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).

  7. 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.