Use these steps to produce a copy of an already existing integration, whether it is a pre-existing Okta Integration Network (OIN) app or a custom application.
- Custom App - OIDC/SAML/Bookmark/SWA
- Okta Integration Network (OIN)
- Clone App with Okta API - Apps API
This operation can only be done through an API call. Depending on the app type (SAML, OIDC, SWA, etc.), not all settings related to the original application will be copied (provisioning details, group/person assignments, resource sets, app logo, etc.).
- Run a GET app call with the below Request Header:
GET https://{{OktaDomainName}}/api/v1/apps/{{AppID}}
The Atlassian Cloud - SAML SSO-enabled application is used for this example. The GET call response should be completed with 200 OK and the below sample response body:
{
"id": "<app id>",
"name": "atlassian",
"label": "Atlassian Cloud",
"status": "ACTIVE",
"lastUpdated": "2023-08-08T14:07:33.000Z",
"created": "2023-08-08T14:07:32.000Z",
"accessibility": {
"selfService": false,
"errorRedirectUrl": null,
"loginRedirectUrl": null
},
"visibility": {
"autoLaunch": false,
"autoSubmitToolbar": true,
"hide": {
"iOS": false,
"web": false
},
"appLinks": {
"trello": false,
"confluence": true,
"statuspage": true,
"compass": false,
"bitbucket": false,
"jira_service_management": true,
"jira": true
}
},
"features": [],
"signOnMode": "SAML_2_0",
"credentials": {
"userNameTemplate": {
"template": "substringBefore(user.email, \"@\")+\"@test.com\"",
"type": "CUSTOM",
"pushStatus": "PUSH"
},
"signing": {
"kid": "<kid>"
}
},
"settings": {
"app": {
"compassUrl": "https://www.<name>.test.com"",
"jiraServiceManagementUrl": "https://www.<name>.test.com"",
"jiraUrl": "https://www.jira.test.com"",
"statusPageUrl": "https://www.statuspage.test.com"",
"opsgenieUrl": null,
"confluenceUrl": "https://www.confluence.test.com"",
"trelloUrl": "https://www.trello.test.com"",
"uniqueID": null,
"bitbucketUrl": "https://www.bitbucket.test.com"",
"strideUrl": "https://app.stride.com""
},
"notifications": {
"vpn": {
"network": {
"connection": "DISABLED"
},
"message": null,
"helpUrl": null
}
},
"manualProvisioning": false,
"implicitAssignment": false,
"notes": {
"admin": "",
"enduser": ""
},
"signOn": {
"defaultRelayState": null,
"ssoAcsUrlOverride": null,
"audienceOverride": null,
"recipientOverride": null,
"destinationOverride": null,
"attributeStatements": []
}
},
"_links": {
"help": {
"href": "https://<name>-admin.okta.com/app/atlassian/<app id>/setup/help/SAML_2_0/external-doc"",
"type": "text/html"
},
"metadata": {
"href": "https://<name>.net/api/v1/apps/<app id>/sso/saml/metadata"",
"type": "application/xml"
},
"uploadLogo": {
"href": "https://<name>.net/api/v1/apps/<app id>/logo"",
"hints": {
"allow": [
"POST"
]
}
},
"appLinks": [
{
"name": "jira",
"href": "https://<name>.net/home/atlassian/<app id>/<id>"",
"type": "text/html"
},
{
"name": "statuspage",
"href": "https://<name>.net/home/atlassian/<app id>/<id>"",
"type": "text/html"
},
{
"name": "confluence",
"href": "https://<name>.net/home/atlassian/<app id>/<id>"",
"type": "text/html"
},
{
"name": "jira_service_management",
"href": "https://<name>.net/home/atlassian/<app id>/<id>"",
"type": "text/html"
}
],
"groups": {
"href": "https://<name>.net/api/v1/apps/<app id>/groups""
},
"logo": [
{
"name": "medium",
"href": "https://ok14static.oktacdn.com/fs/bcg/4/<id>"",
"type": "image/png"
}
],
"users": {
"href": "https://<name>.net/api/v1/apps/<app id>/users""
},
"deactivate": {
"href": "https://<name>.net/api/v1/apps/<app id>/lifecycle/deactivate""
}
}
}
- Fully copy the entire GET response body from step 1 and run the below POST /apps API call to create a new application:
POST https://{{OktaDomainName}}/api/v1/apps
When constructing a POST call request body, there are a couple of things to note:
- For any app type, please change the value of the
labelparameter. This will be the application name. - Then,
- If this is a custom SAML app, remove the "name", "id" and "kid" lines.
- If this is an OIDC app, remove the "client_id" line.
- If this is a custom SAML app, remove the "name", "id" and "kid" lines.
- If this is a custom SWA app, remove the "name" and "id" and change the "signOnMode" from "BROWSER_PLUGIN" to "AUTO_LOGIN".
- If this is an OIN app, remove the entire 'signing' block containing the 'kid' value. Also, remove the comma from the last block to avoid invalid request formatting error:
- For example:
- from:
- For example:
"features": [],
"signOnMode": "SAML_2_0",
"credentials": {
"userNameTemplate": {
"template": "substringBefore(user.email, \"@\")+\"@test.com\"",
"type": "CUSTOM",
"pushStatus": "PUSH"
},
"signing": {
"kid": "<kid>"
}
},
-
-
-
- to:
-
-
"features": [],
"signOnMode": "SAML_2_0",
"credentials": {
"userNameTemplate": {
"template": "substringBefore(user.email, \"@\")+\"@test.com\"",
"type": "CUSTOM",
"pushStatus": "PUSH"
}
},
The POST request body would look similar to the below:
{
"id": "<app id>",
"name": "atlassian",
"label": "Atlassian Cloud - NEW CLONED APP LABEL",
"status": "ACTIVE",
"lastUpdated": "2023-08-08T14:07:33.000Z",
"created": "2023-08-08T14:07:32.000Z",
"accessibility": {
"selfService": false,
"errorRedirectUrl": null,
"loginRedirectUrl": null
},
"visibility": {
"autoLaunch": false,
"autoSubmitToolbar": true,
"hide": {
"iOS": false,
"web": false
},
"appLinks": {
"trello": false,
"confluence": true,
"statuspage": true,
"compass": false,
"bitbucket": false,
"jira_service_management": true,
"jira": true
}
},
"features": [],
"signOnMode": "SAML_2_0",
"credentials": {
"userNameTemplate": {
"template": "substringBefore(user.email, \"@\")+\"@test.com\"",
"type": "CUSTOM",
"pushStatus": "PUSH"
},
"signing": {
"kid": "<kid>"
}
},
"settings": {
"app": {
"compassUrl": "https://www.<name>.test.com"",
"jiraServiceManagementUrl": "https://www.<name>.test.com"",
"jiraUrl": "https://www.jira.test.com"",
"statusPageUrl": "https://www.statuspage.test.com"",
"opsgenieUrl": null,
"confluenceUrl": "https://www.confluence.test.com"",
"trelloUrl": "https://www.trello.test.com"",
"uniqueID": null,
"bitbucketUrl": "https://www.bitbucket.test.com"",
"strideUrl": "https://app.stride.com""
},
"notifications": {
"vpn": {
"network": {
"connection": "DISABLED"
},
"message": null,
"helpUrl": null
}
},
"manualProvisioning": false,
"implicitAssignment": false,
"notes": {
"admin": "",
"enduser": ""
},
"signOn": {
"defaultRelayState": null,
"ssoAcsUrlOverride": null,
"audienceOverride": null,
"recipientOverride": null,
"destinationOverride": null,
"attributeStatements": []
}
},
"_links": {
"help": {
"href": "https://test.okta.com/app/atlassian/<app id>/setup/help/SAML_2_0/external-doc"",
"type": "text/html"
},
"metadata": {
"href": "https://test.okta.com/api/v1/apps/<app id>/sso/saml/metadata"",
"type": "application/xml"
},
"uploadLogo": {
"href": "https://test.okta.com/api/v1/apps/<app id>/logo"",
"hints": {
"allow": [
"POST"
]
}
},
"appLinks": [
{
"name": "jira",
"href": "https://test.okta.com/home/atlassian/<app id>/<id>"",
"type": "text/html"
},
{
"name": "statuspage",
"href": "https://test.okta.com/home/atlassian/<app id>/<id>"",
"type": "text/html"
},
{
"name": "confluence",
"href": "https://test.okta.com/home/atlassian/<app id>/<id>"",
"type": "text/html"
},
{
"name": "jira_service_management",
"href": "https://test.okta.com/home/atlassian/<app id>/<id>"",
"type": "text/html"
}
],
"groups": {
"href": "https://test.okta.com/api/v1/apps/<id>/groups""
},
"logo": [
{
"name": "medium",
"href": "https://ok14static.oktacdn.com/fs/bcg/4/<id>"",
"type": "image/png"
}
],
"users": {
"href": "https://test.okta.com/api/v1/apps/<app id>/users""
},
"deactivate": {
"href": "https://test.okta.com/api/v1/apps/<app id>/lifecycle/deactivate""
}
}
}
NOTE: A new and unique signing kid will be created upon a successful POST /apps call.
