Transferring applications and associated access policies from one account to another with Secure Private Access API

This topic provides instructions on how a user can transfer applications and the associated access policies by extracting them from one Citrix Cloud customer and importing them to another Citrix Cloud customer.

Prerequisites

  • Citrix-CustomerId for both the Citrix Cloud Customer that owns the applications/access policies that must be extracted and the Citrix Cloud customer for whom the applications/policies are to be imported.
  • Bearer token for each customer that is required when running the relevant requests for each of them. For details, see Getting started with Secure Private Access API.

Extracting applications using the API

The entire list of applications can be extracted by a GET request to the following endpoint, with the headers as described and without any other query parameters.

GET https://api.cloud.com/accessSecurity/applications

Request headers

Accept: application/json
Citrix-CustomerId: \{\{customerId1\}\}
Authorization: CWSAuth Bearer=\{\{bearerToken1\}\}
Citrix-TransactionId: \{\{Citrix-TransactionId\}\}
<!--NeedCopy-->

The Citrix-TransactionId header can be omitted.

Response sample

A 200 OK response contains a JSON body like the following:

{
    "items": [
        {
            "state": "complete",
            "usingTemplate": false,
            "templateName": "",
            "name": "Test Application 1",
            "type": "saas",
            "description": "Test Application 1",
            "category": null,
            "keywords": null,
            "locations": null,
            "url": "https://www.testapplication1.com/",
            "policies": null,
            "sbsOnlyLaunch": false,
            "mobileSecurity": false,
            "customerDomainFields": null,
            "hidden": false,
            "agentlessAccess": false,
            "destination": null,
            "policyCount": "3",
            "createdTime": "2023-02-03T13:12:42Z",
            "relatedURLs": [
                "*.testapplication1.com"
            ],
            "icon": null,
            "iconURL": null,
            "sso": "nosso",
            "id": "b1030399-2312-4374-85a4-da6910da253e"
        },
        {
            "state": "complete",
            "usingTemplate": false,
            "templateName": "",
            "name": "Test Application 2",
            "type": "saas",
            "description": "Test Application 2",
            "category": null,
            "keywords": null,
            "locations": null,
            "url": "https://www.testapplication2.com/",
            "policies": null,
            "sbsOnlyLaunch": false,
            "mobileSecurity": false,
            "customerDomainFields": null,
            "hidden": false,
            "agentlessAccess": false,
            "destination": null,
            "policyCount": "3",
            "createdTime": "2022-11-10T12:26:11Z",
            "relatedURLs": [
                "*.testapplication2.com"
            ],
            "icon": null,
            "iconURL": null,
            "sso": "nosso",
            "id": "1a1d2dce-f567-4369-8997-d4834fc64464"
        },
        {
            "state": "complete",
            "usingTemplate": true,
            "templateName": "b_name",
            "name": "Test Application 3",
            "type": "saas",
            "description": "Test Application 3",
            "category": "category",
            "keywords": null,
            "locations": null,
            "url": "https://www.testapplication3.com/",
            "policies": null,
            "sbsOnlyLaunch": false,
            "mobileSecurity": false,
            "customerDomainFields": null,
            "hidden": false,
            "agentlessAccess": true,
            "destination": null,
            "policyCount": "0",
            "createdTime": "2023-02-02T09:19:04Z",
            "relatedURLs": [
                "*.testapplication3.com"
            ],
            "icon": null,
            "iconURL": null,
            "sso": "nosso",
            "id": "48289849-123c-4acf-8c2f-a23a596ea604"
        }
    ],
    "totalNum": 3
}
<!--NeedCopy-->

The JSON object contains an items array that contains the list of application objects. The JSON object also has a totalNum property that contains the total number of application objects returned.

For more details regarding the GET requests to this endpoint and the schema of the response, see Handling Applications with Secure Private Access API.

Extracting policies using the API

The entire list of policies can then be extracted by a GET request to the following endpoint, with the headers as described and without any other query parameters.

GET https://api.cloud.com/accesssecurity/accessPolicy

Request headers

Accept: application/json
Citrix-CustomerId: \{\{customerId1\}\}
Authorization: CWSAuth Bearer=\{\{bearerToken1\}\}
Citrix-TransactionId: \{\{Citrix-TransactionId\}\}
<!--NeedCopy-->

The Citrix-TransactionId header can be omitted but it is encouraged to use the Citrix-TransactionId returned by the first GET request so that this particular stream of requests can be traced, in case support is needed.

Response sample

A 200 OK response contains a JSON body like the following:

{
    "items": [
        {
            "id": "1f738e0a-7342-4f65-aa6c-af50c56dbfc7",
            "modified": "2022-10-27T09:05:58Z",
            "apps": [
                "1a1d2dce-f567-4369-8997-d4834fc64464"
            ],
            "name": "TestPolicy 1",
            "description": "TestPolicy Description",
            "priority": 73945,
            "active": false,
            "accessRules": [...]
        },
        {
            "id": "7a738d4d-c6fb-46bf-8cdd-ba19097d25e6",
            "modified": "2022-12-06T12:41:55Z",
            "apps": [
                "b1030399-2312-4374-85a4-da6910da253e"
            ],
            "name": "TestPolicy 2",
            "description": "TestPolicy Description",
            "priority": 22920,
            "active": true,
            "accessRules": [...]
        },
        {
            "id": "e04f4bcb-807e-4743-8d4d-6a19e805f0c5",
            "modified": "2023-01-31T08:37:31Z",
            "apps": [
                "b1030399-2312-4374-85a4-da6910da253e"
            ],
            "name": "TestPolicy 3",
            "description": "TestPolicy Description",
            "priority": 12604,
            "active": false,
            "accessRules": [...]
        },
        {
            "id": "f75a4eab-5c5c-46cf-9155-42ee0e067902",
            "modified": "2023-02-03T13:13:23Z",
            "apps": [
                "b1030399-2312-4374-85a4-da6910da253e"
            ],
            "name": "TestPolicy 4",
            "description": "TestPolicy Description",
            "priority": 12202,
            "active": true,
            "accessRules": [...]
        }
    ],
    "totalNum": 4
}
<!--NeedCopy-->

The JSON object can be parsed and the policies retrieved from the items array. The totalNum property also contains the total number of policy objects returned.

For more details regarding the GET requests to this endpoint and the schema of the response please see Handling Policies with Secure Private Access API.

All policies contain an app list that contains the application ids corresponding to the application from the previous response. The user can use these IDs to connect the application with the policies.

Importing applications using the API

Next, the user needs to do a POST request for each application that came from the first GET request to create the applications for the second customer:

POST https://api.cloud.com/accessSecurity/applications

Request headers

Accept: application/json
Content-Type: application/json; charset=utf-8
Citrix-CustomerId: \{\{customerId2\}\}
Authorization: CWSAuth Bearer=\{\{bearerToken2\}\}
Citrix-TransactionId: \{\{Citrix-TransactionId\}\}
<!--NeedCopy-->

The Citrix-TransactionId header can be omitted but it is encouraged to use the Citrix-TransactionId returned by the previous requests so that this particular stream of requests can be traced, in case support is needed.

Request body example

{
    "usingTemplate": false,
    "templateName": "",
    "name": "Test Application 1",
    "type": "saas",
    "description": "Test Application 1",
    "category": null,
    "keywords": null,
    "locations": null,
    "url": "https://www.testapplication1.com/",
    "policies": null,
    "sbsOnlyLaunch": false,
    "mobileSecurity": false,
    "customerDomainFields": null,
    "hidden": false,
    "agentlessAccess": false,
    "destination": null,
    "policyCount": "3",
    "createdTime": {},
    "relatedURLs": [
        "*.testapplication1.com"
    ],
    "icon": null,
    "iconURL": null,
    "sso": "nosso"
}
<!--NeedCopy-->

This request body must not contain an id field, as that is generated with the response, nor a status field.

Response Body Example

{
    "state": "incomplete",
    "usingTemplate": false,
    "templateName": "",
    "name": "Test Application 1",
    "type": "saas",
    "description": "Test Application 1",
    "category": null,
    "keywords": null,
    "locations": null,
    "url": "https://www.testapplication1.com/",
    "policies": null,
    "sbsOnlyLaunch": false,
    "mobileSecurity": false,
    "customerDomainFields": null,
    "hidden": false,
    "agentlessAccess": false,
    "destination": null,
    "policyCount": "3",
    "createdTime": "2023-02-03T13:12:42Z",
    "relatedURLs": [
        "*.testapplication1.com"
    ],
    "icon": null,
    "iconURL": null,
    "sso": "nosso",
    "id": "0382f5a4-4b9a-4322-ab60-f5eb08d1c093"
}
<!--NeedCopy-->

In the 201 Created response, the user must note the new application ID and keep an association between the old application ID and the new, so that it can be used when creating the new access policies later.

For more details regarding the POST requests to this endpoint and the schema of the request and response please see Handling Applications with Secure Private Access API.

Completing application creation

To complete the application creation for the second customer, the user must make a PUT request for each one of the newly created applications. The application’s UUID is appended to the request URL:

PUT https://api.cloud.com/accessSecurity/applications/{{applicationUUID}}?action=complete

Request header sample

Accept: application/json
Content-Type: application/json; charset=utf-8
Citrix-CustomerId: \{\{customerId2\}\}
Authorization: CWSAuth Bearer=\{\{bearerToken2\}\}
Citrix-TransactionId: \{\{Citrix-TransactionId\}\}
<!--NeedCopy-->

The Citrix-TransactionId header can be omitted but it is encouraged to use the Citrix-TransactionId returned by the previous requests so that this particular stream of requests can be traced, in case support is needed.

Request body example

The request body is an empty JSON object.

{}
<!--NeedCopy-->

Successful response example

A 204 NO CONTENT response with an empty body is returned.

Creating the access policies

For each access policy that was retrieved from the second GET request, the user must do a POST request to create it for the second customer.

POST https://api.cloud.com/accessSecurity/accessPolicy

Request headers

Accept: application/json
Content-Type: application/json; charset=utf-8
Citrix-CustomerId: \{\{customerId2\}\}
Authorization: CWSAuth Bearer=\{\{bearerToken2\}\}
Citrix-TransactionId: \{\{Citrix-TransactionId\}\}
<!--NeedCopy-->

The Citrix-TransactionId header can be omitted but it is encouraged to use the Citrix-TransactionId returned by the previous requests so that this particular stream of requests can be traced, in case support is needed.

Request body sample

{
    "apps": [ "0382f5a4-4b9a-4322-ab60-f5eb08d1c093" ],
    "name": "TestPolicy",
    "description": "TestPolicy Description",
    "priority": 3848354,
    "active": false,
    "accessRules": [
        {
            "name": "Test Policy | browserV1 ",
            "id": "1c052a01-dafa-45ff-8c8e-340974e1b1c4",
            "priority": 1,
            "active": true,
            "access": "ACCESS_ALLOW",
            "restrictions": {
                "enhancedSecuritySettings": {
                    "browserV1": "embeddedBrowser",
                    "watermarkV1": "disabled"
                }
            },
            "rules": [
                {
                    "type": "TYPE_USERGROUP",
                    "operator": "OPERATOR_IN",
                    "tagSource": "ITM",
                    "tagKey": "",
                    "values": [
                        "SID:/03fc0b3d-7441-4236-8e39-a4d5da073edb/",
                        "OID:/9df11d6a-8488-42ca-a3ed-6c4b3d1a5f43"
                    ],
                    "metadata": {
                        "ak2": "SID:/03fc0b3d-7441-4236-8e39-a4d5da073edb/,OID:/9df11d6a-8584-42ca-a3ed-6c4b3d1a5f43"
                    }
                }
            ]
        }
    ]
}
<!--NeedCopy-->

The request needs to have the new application ids for the second customer instead of the old application IDs from the first customer. Apart from that, the request body must be a copy of the old access policy. A successful request returns an empty 201 Created response.

Resources
Access Security OpenAPI Specification
Copy Download
Transferring applications and associated access policies from one account to another with Secure Private Access API