---
title: Unmanaged apps
description: Register and govern disconnected applications in PingOne Identity Governance without a connector, using the Unmanaged Apps API.
component: pingoneaic
page_id: pingoneaic:identity-governance:administration/unmanaged-apps
canonical_url: https://docs.pingidentity.com/pingoneaic/identity-governance/administration/unmanaged-apps.html
llms_txt: https://docs.pingidentity.com/pingoneaic/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
keywords: ["unmanaged apps", "disconnected application", "IGA", "application onboarding", "entitlement data", "account data"]
section_ids:
  core-concepts: Core concepts
  important-tips: Important tips
  prerequisites: Prerequisites
  workflow: Workflow
  onboarding_an_unmanaged_app: Onboarding an unmanaged app
  offboarding_an_unmanaged_app: Offboarding an unmanaged app
  step-1-get-an-access-token: "Step 1: Get an access token"
  step-2-create-the-application: "Step 2: Create the application"
  step-3-verify-the-application-was-created: "Step 3: Verify the application was created"
  step-4-add-object-types: "Step 4: Add object types"
  step-4a-account-object-type: 4a. Add account object type
  step-4b-resource-object-type: 4b. Add resource object type
  step-5-verify-the-schema: "Step 5: Verify the schema"
  step-6-upload-poll-and-verify-resource-data: "Step 6: Upload, poll, and verify resource (entitlement) data"
  step-7-upload-account-data-and-poll-status: "Step 7: Upload account data and poll status"
  step-8-link-an-account-to-a-user: "Step 8 (optional): Link an account to an Advanced Identity Cloud user"
  offboarding-and-delete-an-application: Offboard and delete an application
  step-1-run-delete-detection: "Step 1: Run delete detection"
  step-2-delete-the-application: "Step 2: Delete the application"
  api-quick-reference: API quick reference
---

# Unmanaged apps

An unmanaged app, also called a disconnected application, is any application that doesn't use a live connector to Advanced Identity Cloud. Instead, governance data such as accounts and entitlements is brought into Advanced Identity Cloud through manual imports using APIs or .csv file uploads, while fulfillment happens through an IT Service Management (ITSM) workflow rather than through automated provisioning. For example, a manager creates a request for a new laptop, the request ticket is created through a ticketing system, such as ServiceNow or another system, the ticket is routed to the right IT team, approvals happen, and IT fulfills the request using a standard workflow.

With Identity Governance, application owners and administrators can onboard and govern unmanaged apps themselves, without requiring the governance team to connect to each application, obtain service credentials, and secure environment access from application owners as is typically done with live connector applications.

This page covers how to register an unmanaged app, upload resource and account data, verify the results in the entitlement catalog, and offboard the application when it's no longer needed.

## Core concepts

| Term                 | Meaning                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Application          | An unmanaged app registered in Identity Governance, owned by one or more identities.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| Account object type  | Represents the account object structure for the app (for example, a Salesforce user account).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| Resource object type | Represents any non-account object: an entitlement (group, role, permission set) or an application resource (service principal, API key, cloud resource).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| Roles attribute      | A multi-valued account attribute holding the entitlements granted to that account, referencing a `Resource` object type.&#xA;&#xA;This page refers to the roles account attribute as "roles" in the text, but you can call it anything you want as long as it points to the id of the resource object. For example, the reference property refers to the id of the resource object type. Learn more in 4b. Add resource object type for the full object type.&#xA;&#xA;"entitlement\_grants": {&#xA;    "items": {&#xA;        "type": "string"&#xA;    },&#xA;    "required": false,&#xA;    "type": "array",&#xA;    "userSpecific": true,&#xA;    "order": 2,&#xA;    "displayName": "Roles",&#xA;    "isEntitlement": true,&#xA;    "reference": {&#xA;        "objectType": "Roles"&#xA;    } |
| Delete detection     | The process of identifying records to remove by comparing a new upload against existing data. Any record absent from the new upload is marked for removal.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| Relationship         | The link between an account and the Advanced Identity Cloud user identity who owns it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |

## Important tips

* **Required attributes**: Every object (account or resource) must define `id` and `displayName` attributes.

  |   |                                                                                                                                                               |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | Ping Identity plans to remove the `id` and `displayName` attribute requirements on all objects and the admin access token requirement in an upcoming release. |

* **Multi-valued attribute notation**: Multi-valued attributes (for example, `entitlement_grants`) must be represented as a JSON array encoded as a string: `["value1","value2"]`. In a .csv file, this appears as a quoted cell, for example, `["0PS000000000001","0PS000000000007"]`.

* **When `userId` isn't available at upload time**: If you can't include `userId` in the account .csv file, use the [Link API](#step-8-link-an-account) to associate the account with an Advanced Identity Cloud user afterward.

* **Limitations**: Unmanaged apps can't be used with PingOne Advanced Identity Cloud roles. If role-based provisioning is key to your Identity Governance deployment, consider using the database table, scripted Groovy or other app integrations.

* **Key differences between managed and unmanaged applications**:

  * **Governance**: Unmanaged apps are governed by Identity Governance only, not Advanced Identity Cloud.

  * **Promotions**: Only managed apps require promotions. Unmanaged apps bypass promotion workflows.

  * **Provisioning**: Managed apps use the application catalog and connectors for automated provisioning. Unmanaged apps rely on workflows, ServiceNow, or manual fulfillment. You can't use the application catalog or connectors with unmanaged apps.

## Prerequisites

Before you start, review the following:

* **Identity linkage**: Identities referenced by an account must already exist in Advanced Identity Cloud. Your account .csv file must include a `userId` column mapped to the corresponding Advanced Identity Cloud user ID.

* **Access token**: Unmanaged app onboarding APIs require the tenant [access token](../../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token).

## Workflow

Follow the onboarding steps in order; the offboarding steps are independent.

### Onboarding an unmanaged app

1. [Step 1: Get an access token](#step-1-get-an-access-token).

2. [Step 2: Create the application](#step-2-create-the-application)

3. [Step 3: Verify the application was created](#step-3-verify-the-application-was-created)

4. [Step 4: Add object types](#step-4-add-object-types).

   1. [4a. Add account object type](#step-4a-account-object-type).

   2. [4b. Add resource object type](#step-4b-resource-object-type).

5. [Step 5: Verify the schema](#step-5-verify-the-schema).

6. [Step 6: Upload, poll, and verify resource (entitlement) data](#step-6-upload-poll-and-verify-resource-data)

7. [Step 7: Upload account data and poll status](#step-7-upload-account-data-and-poll-status)

8. [(Optional). Link accounts to Advanced Identity Cloud users individually](#step-8-link-an-account-to-a-user)

### Offboarding an unmanaged app

1. [Step 1: Run delete detection](#step-1-run-delete-detection)

2. [Step 2: Delete the application](#step-2-delete-the-application)

## Step 1: Get an access token

The unmanaged apps APIs require a tenant access token for authorization. Pass this token as a bearer token in the Authorization header of every subsequent API call in this workflow. Learn more in [Authenticate to the REST API with an access token](../../developer-docs/authenticate-to-rest-api-with-access-token.html#get_an_access_token).

## Step 2: Create the application

Register the unmanaged app in Identity Governance. This call creates the application record and returns the `applicationId` you'll use in every subsequent step.

```none
POST {protocol}://{host}:{port}/iga/governance/application?_action=create
```

```json
{
    "applicationId": "<generated-uuid>",
    "name": "Salesforce",
    "isDisconnected": true,
    "datasourceId": "disconnected",
    "description": "This is a disconnected application",
    "ownerIds": [
        "<_id of the managed user>"
    ],
    "icon": "https://example.com/salesforce-logo.png"
}
```

|   |                                                                                                                                                                                                      |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | To find a managed user's ID (`_id`), query the identities API: `GET /openidm/managed/user?_queryFilter=userName+eq+"<username>"`. The `_id` field in the response is the value to use in `ownerIds`. |

## Step 3: Verify the application was created

Confirm the application is created and is flagged as disconnected:

```none
GET {protocol}://{host}:{port}/iga/governance/application?disconnected=true
```

## Step 4: Add object types

Two object types are required: `Account` and `Resource`.

### 4a. Add account object type

Account object types represent the account structure for the application (for example, a Salesforce user account). The `entitlement_grants` property is multi-valued and references the `Resource` object type representing the entitlements granted to that account.

```none
POST {protocol}://{host}:{port}/iga/governance/application/{applicationId}/objectType?_action=create
```

```json
{
    "id": "User",
    "type": "account",
    "properties": {
        "user_name": {
            "type": "string",
            "userSpecific": true,
            "order": 9,
            "displayName": "User Name"
        },
        "entitlement_grants": {
            "items": {
                "type": "string"
            },
            "required": false,
            "type": "array",
            "userSpecific": true,
            "order": 2,
            "displayName": "Roles",
            "isEntitlement": true,
            "reference": {
                "objectType": "Roles"
            }
        },
        "id": {
            "type": "string",
            "userSpecific": true,
            "displayName": "ID",
            "required": true,
            "flags": [
                "NOT_UPDATEABLE"
            ]
        },
        "displayName": {
            "type": "string",
            "order": 10,
            "displayName": "Display Name"
        }
    }
}
```

### 4b. Add resource object type

Resource object types represent the entitlements or resources associated with the application, such as Salesforce permission sets, roles, or API keys. Create one resource object type for each category of entitlement your application provides.

```none
POST {protocol}://{host}:{port}/iga/governance/application/{applicationId}/objectType?_action=create
```

```json
{
    "id": "Roles",
    "type": "resource",
    "properties": {
        "id": {
            "type": "string",
            "required": true,
            "order": 9,
            "displayName": "ID"
        },
        "displayName": {
            "type": "string",
            "order": 25,
            "displayName": "Display Name"
        },
        "applicationId": {
            "type": "string",
            "order": 1,
            "displayName": "Application ID"
        },
        "entitlement_type": {
            "type": "string",
            "order": 1,
            "displayName": "Entitlement Type"
        },
        "criticality": {
            "type": "string",
            "order": 1,
            "displayName": "Criticality"
        },
        "description": {
            "type": "string",
            "order": 1,
            "displayName": "Description"
        }
    }
}
```

|   |                                                                                                                                                                                                |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | The `reference.objectType` value, `Roles`, refers to the `Resource` object type you create in Step 4b. Update this value if you name your `Resource` object type something other than `Roles`. |

## Step 5: Verify the schema

Confirm each object type is created as expected. The response includes the `id`, `type`, and `properties` you defined in [Step 4: Add object types](#step-4-add-object-types). For example, for the `User` object type, verify that `"id": "User"`, `"type": "account"`, and the `entitlement_grants` property with `"isEntitlement": true` are present. If a property is missing or `type` is incorrect, rerun the relevant object type creation call in [Step 4: Add object types](#step-4-add-object-types).

```none
GET {protocol}://{host}:{port}/iga/governance/application/{applicationId}/objectType/{objectTypeId}
```

## Step 6: Upload, poll, and verify resource (entitlement) data

Load entitlements one entitlement type at a time.

```bash
curl --location '{protocol}://{host}:{port}/iga/governance/application/{applicationId}?_action=upload' \
--header 'Authorization: Bearer {accessToken}' \
--form 'file=@"/path/to/file"' \
--form 'objectType="Roles"'
```

The sample .csv file is as follows:

```csv
id,displayName,applicationId,entitlement_type,criticality,description
0PS000000000001,Sales User Basic,d76e8926-078f-4e82-a0ec-8bc4e73d093b,PermissionSet,Low,"Baseline Salesforce access for sales users..."
0PS000000000002,Sales Manager,d76e8926-078f-4e82-a0ec-8bc4e73d093b,PermissionSet,High,"Expanded sales access for managing pipelines..."
```

Response:

```json
{
    "message": "File uploaded started for application d76e8926-078f-4e82-a0ec-8bc4e73d093b",
    "uploads": [
        {
            "extractionId": "fd12a94d-53fb-4426-aaaf-9cadaafc8072",
            "type": "resource"
        }
    ]
}
```

Use the `extractionId` from the response as `{uploadId}` in the following endpoint:

```none
GET {protocol}://{host}:{port}/iga/governance/application/{applicationId}/upload/{uploadId}
```

The response reports `status`, `processed`, `inserted`, and `failed` counts.

Before proceeding, confirm the uploaded entitlements are visible in the entitlement catalog, the central list of all entitlements available for governance. In Advanced Identity Cloud, go to Governance > Entitlements, and search for the entitlement names from your .csv (for example, `Sales User Basic`).

![The entitlements catalog with the \`Sales User Basic\` highlighted.](../_images/disconnected-apps-example.png)

## Step 7: Upload account data and poll status

Upload the account records for your application. If your .csv includes `userId` values, Identity Governance links each account to its Advanced Identity Cloud user at the same time, generating a separate job for those identity relationships.

```bash
curl --location '{protocol}://{host}:{port}/iga/governance/application/{applicationId}?_action=upload' \
--header 'Authorization: Bearer {accessToken}' \
--form 'file=@"/path/to/salesforce_accounts.csv"' \
--form 'objectType="User"'
```

|   |                                                                                                                                                                                                 |
| - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | `objectType` must be the name of the account object type as defined in [4a. Add account object type](#step-4a-account-object-type) (for example, `"User"`), not the literal string `"account"`. |

The sample .csv file is as follows:

```csv
user_name,entitlement_grants,id,displayName,userId
aaron.anderson,"[""0PS000000000001"",""0PS000000000007""]",SF-ACCOUNT-00001,Aaron Anderson Salesforce Account,2d637638-366b-4e64-b05b-97c2c2fb8060
abigail.baker,"[""0PS000000000003"",""0PS000000000013""]",SF-ACCOUNT-00002,Abigail Baker Salesforce Account,8bbc1d1b-080f-4dbf-9c52-811aeaa850fe
```

Because accounts reference both Advanced Identity Cloud identities (`userId`) and entitlements (`entitlement_grants`), Identity Governance can return multiple jobs: one for the accounts themselves, and one for the resulting identity relationships. Each `extractionId` in the response identifies the upload job for that object type.

```json
{
    "message": "File uploaded started for application d76e8926-078f-4e82-a0ec-8bc4e73d093b",
    "uploads": [
        {
            "extractionId": "b74a45b8-8359-41e7-81d1-6f56a6431319",
            "type": "account"
        },
        {
            "extractionId": "009e2f63-8623-463c-92b6-e4c9a508db22",
            "type": "relationship"
        }
    ]
}
```

Poll both extraction IDs using the same upload-status endpoint from [Step 6: Upload, poll, and verify resource (entitlement) data](#step-6-upload-poll-and-verify-resource-data).

If you need to remove the application later, refer to [Offboard and delete an application](#offboarding-and-delete-an-application).

## Step 8 (optional): Link an account to an Advanced Identity Cloud user

If `userId` couldn't be included in the account .csv file, associate the account with its Advanced Identity Cloud user identity individually:

```none
POST {protocol}://{host}:{port}/iga/governance/account/{applicationId}/{objectType}/{accountId}/users?_action=add
```

```json
{
    "applicationId": "{applicationId}",
    "userId": "{AIC user id}"
}
```

Response:

```json
{
    "message": "Successfully provisioned disconnected relationship",
    "relationship": {
        "id": "937fffd0-b6b4-44a5-9216-4f3291bb2ffa",
        "type": "accountGrant",
        "userId": "ae82f3db-6945-4243-a7ee-71e42befa047",
        "applicationId": "d76e8926-078f-4e82-a0ec-8bc4e73d093b",
        "accountId": "d76e8926-078f-4e82-a0ec-8bc4e73d093b/User/SF-ACCOUNT-00001"
    }
}
```

## Offboard and delete an application

Offboarding permanently removes the application record and all associated schema and account data from Identity Governance. Run delete detection first to mark removed records, then delete the application.

### Step 1: Run delete detection

Delete detection identifies records to remove by comparing a new upload against existing data. Resubmit the full current dataset for each object type; any record absent from the new file is marked for removal.

Run the following command once per object type (for example, once for `User`, once for `Roles`):

```bash
curl --location '{protocol}://{host}:{port}/iga/governance/application/{applicationId}?_action=upload&type=delete' \
--header 'Authorization: Bearer {accessToken}' \
--form 'file=@"/path/to/file"' \
--form 'objectType="{objectTypeName}"'
```

### Step 2: Delete the application

```none
DELETE {protocol}://{host}:{port}/iga/governance/application/{applicationId}
```

## API quick reference

| Operation                                    | Method | Endpoint                                                                             |
| -------------------------------------------- | ------ | ------------------------------------------------------------------------------------ |
| Create application                           | POST   | `/iga/governance/application?_action=create`                                         |
| List applications                            | GET    | `/iga/governance/application?disconnected=true`                                      |
| Create object type                           | POST   | `/iga/governance/application/{applicationId}/objectType?_action=create`              |
| Get object type                              | GET    | `/iga/governance/application/{applicationId}/objectType/{objectTypeId}`              |
| Upload data (resource or account)            | POST   | `/iga/governance/application/{applicationId}?_action=upload`                         |
| Get upload status                            | GET    | `/iga/governance/application/{applicationId}/upload/{uploadId}`                      |
| Link account to Advanced Identity Cloud user | POST   | `/iga/governance/account/{applicationId}/{objectType}/{accountId}/users?_action=add` |
| Delete detection (per object type)           | POST   | `/iga/governance/application/{applicationId}?_action=upload&type=delete`             |
| Delete application                           | DELETE | `/iga/governance/application/{applicationId}`                                        |
