# Custom Identity Provider

Use this template to model authorization metadata for custom identity providers using the [Open Authorization API](/4yItIzMvkpAvMVFAamTf/developers/api/oaa.md).

This document includes an example template and notes for designing and [publishing](#creating-and-updating-a-custom-identity-provider) a model of your IdP.

* [`domain`](#idp-domain)
* [`users`](#idp-users)
* [`groups`](#idp-groups)
* [`apps`](#idp-apps)
* [`identity_mapping_configuration`](#identity-mapping-configuration)

A [custom property definition](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) can define additional properties, used to add supplemental metadata to entities in the payload.

Veza will handle federated identities just as those in supported IdPs such as Okta or Entra ID, enabling search and access review for OAA entities alongside the rest of your data catalog.

## Sample Template and Features

The metadata payload describes the Identity Provider domain, users, and groups to add to the Veza Access Graph:

<details>

<summary>Simple Custom Identity Provider</summary>

```json
{
  "name": "My IdP",
  "idp_type": "custom_idp",
  "domains": [
    {
      "name": "example.com",
      "tags": [],
    }
  ],
  "users": [
    {
      "name": "m_richardson",
      "email": "mrichardson@example.com",
      "identity": "m_richardson",
      "full_name": "Michelle Richardson",
      "department": null,
      "is_active": true,
      "is_guest": false,
      "groups": [
        {
          "identity": "everyone"
        },
        {
          "identity": "developers"
        }
      ],
      "assumed_role_arns": [
        {
          "identity": "arn:aws:iam::123456789012:role/role001"
        },
        {
          "identity": "arn:aws:iam::123456789012:role/role002"
        }
      ],
      "tags": [],
    },
    {
      "name": "evargas",
      "email": "evargas@example.com",
      "identity": "evargas",
      "full_name": "Elizabeth Vargas",
      "department": null,
      "is_active": true,
      "is_guest": false,
      "groups": [
        {
          "identity": "everyone"
        },
        {
          "identity": "developers"
        },
        {
          "identity": "sec-ops"
        }
      ],
      "assumed_role_arns": [],
      "tags": [],
    },
    {
      "name": "willis",
      "email": "willis@example.com",
      "identity": "c_williams",
      "full_name": null,
      "department": null,
      "is_active": true,
      "is_guest": false,
      "groups": [
        {
          "identity": "everyone"
        }
      ],
      "assumed_role_arns": [],
      "tags": []
    }
  ],
  "groups": [
    {
      "name": "developers",
      "identity": "developers",
      "full_name": null,
      "is_security_group": null,
      "tags": []
    },
    {
      "name": "sec-ops",
      "identity": "sec-ops",
      "full_name": null,
      "is_security_group": null,
      "tags": []
    },
    {
      "name": "everyone",
      "identity": "everyone",
      "full_name": "All Company Employees",
      "is_security_group": null,
      "tags": []
    }
  ],
  "identity_mapping_configuration": {
    "mappings": [
      {
        "destination_datasource_type": "GITHUB_USERS",
        "property_matchers": [
          {
            "source_property": "EMAIL",
            "destination_property": "UNIQUE_ID"
          }
        ]
      },
      {
        "destination_datasource_type": "SQL_SERVER",
        "property_matchers": [
          {
            "source_property": "EMAIL",
            "destination_property": "EMAIL"
          }
        ],
        "transformations": [
          "IGNORE_DOMAIN"
        ]
      }
    ]
  }
}
```

</details>

### Modeling Assumable Amazon Web Services Roles

For cases where federated IdP entities are granted AWS permissions via IAM roles, the template supports defining assumable roles per-user. Binding a custom IdP user or group to an AWS role or group ARN enables Veza to parse and display the resource-level actions permitted within AWS.

```json
{
      "name": "Custom User",
      "assumed_role_arns": {
        "identity": [
          "arn:aws:iam::123456789012:role/S3Access"
          ]
        },
    }
```

Custom IdP users and groups can be assigned permissions in other OAA applications by setting the principal `type` to `idp` in `identity_to_permissions` in the [custom application](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/templates/custom-application-template.md) payload.

### Source Identity Assignments

For use cases where a custom IdP is federated with another identity provider user identities can be linked between the two. Authorizations granted to the user will also be granted the source identity. The link is created by providing the unique identity ID and provider type as part of the user entry.

```json
{
  "name": "Custom User",
  "identity": "00001",
  "source_identity": {
    "identity": "user0001@corp.example.com",
    "provider_type": "okta"
  }
}
```

For `provider_type` the following values are accepted:

| Provider         | `provider_type` string |
| ---------------- | ---------------------- |
| Active Directory | `active_directory`     |
| Any              | `any`                  |
| AzureAD          | `azure_ad`             |
| OAA              | `custom`               |
| Google Workspace | `google_workspace`     |
| Okta             | `okta`                 |
| One Login        | `one_login`            |

### Resource Manager Assignments

> New in Veza release `2022.2.1`

To assign an IdP user or group as the manager of any resource Veza has discovered, list the node type and node id in the `entities_owned` field, for example:

```json
{
  "name": "Custom User",
  "identity": "000011",
  "entities_owned": [
    {
      "node_type": "S3Bucket",
      "id": "arn:aws:s3:::amazon-connect-53f87966654d"
    }
  ]
}
```

When parsing the payload, resources in the data catalog will be updated with a `SYSTEM_resource_managers` tag to enable entitlement reviews. The owner(s) will be suggested as reviewers for Veza Workflows that target an individual named resource with the correct tag.

### Manager Assignments

Users and groups can be mapped to the `identity` of another user they report to. When configured, the manager will be suggested as a review for Workflow certifications where the assigned reporter is the single query target "named entity."

```json
{
  "name": "Custom User",
  "identity": "000013",
  "manager_id": "000011"
}
```

### Custom Properties and Tags

[Custom Properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) are the recommended method for adding additional metadata to custom identities and resources.

The `custom_property_definition` object supports separate property namespaces for each entity type:

| Field                       | Description                                              |
| --------------------------- | -------------------------------------------------------- |
| `domain_properties`         | Custom property definitions for IdP domain entities.     |
| `user_properties`           | Custom property definitions for IdP user entities.       |
| `group_properties`          | Custom property definitions for IdP group entities.      |
| `app_properties`            | Custom property definitions for IdP app entities.        |
| `app_assignment_properties` | Custom property definitions for app assignment entities. |

Additionally, [Veza tags](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-tags.md) can be applied to the IdP domain, users, and groups:

```json
"tags": [
  {
    "key": "Tag1key",
    "value": "optional_Tag1Val"
  }
]
```

*Use incremental updates to remove tags*: Resubmitting a payload with different tags will apply any new tags, but not remove existing ones. To remove a tag already applied to an entity, you will need to use the [incremental update](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/incremental-updates.md) `remove_tag` operation.

### Incremental Updates

After the initial metadata push (which must contain the full payload), you can modify, add, or remove the domain, users, and groups without resubmitting other entities. An [incremental update](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/incremental-updates.md) is enabled by setting `"incremental_change": true` in the `json_data` push payload, and specifying the update `operation` for each entity to change.

## `Custom Identity Provider` definition

The identity provider object models one instance of the custom IdP:

| Field                            | Type                                                                                                           | Description                                                                                                                                      |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`                           | string                                                                                                         | Name to associate with the provider in Veza.                                                                                                     |
| `custom_property_definition`     | [Custom Property Definition](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) | Defines the key and types for properties that can be applied to other objects in the push payload                                                |
| `idp_type`                       | string                                                                                                         | Type descriptor for IdP, can be unique or share across multiple IdP (for example `ldap`, `IPA`)                                                  |
| `idp_description`                | string                                                                                                         | Any notes to add as entity details (optional)                                                                                                    |
| `domains`                        | [IdP Domain](#idp-domain)                                                                                      | Domain model                                                                                                                                     |
| `users`                          | [IdP Users](#idp-users)                                                                                        | Dictionary of CustomIdPUser class instances                                                                                                      |
| `groups`                         | [IdP Group](#idp-groups)                                                                                       | Dictionary of CustomIdPGroup class instances                                                                                                     |
| `incremental_change`             | boolean                                                                                                        | When `true`, enables [incremental update](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/incremental-updates.md) operations (optional). |
| `identity_mapping_configuration` | [Identity Mapping Configuration](#identity-mapping-configuration)                                              | Configuration for mapping identities between IdP User and other User types from external data sources                                            |

### **`IdP Domain`**

One domain is supported for each custom IdP. Users and groups are mapped to the IdP domain, and connected in Veza Search:

| Field                | Type                                                                                                  | Description                                                                                                                                                               |
| -------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`               | string                                                                                                | IdP Domain name                                                                                                                                                           |
| `custom_properties`  | [Custom Properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) | Each element of the push payload can have `property_values`, validated against the `custom_property_definition`.                                                          |
| `dynamic_properties` | Dynamic Properties                                                                                    | Up to 5 attributes to apply to the domain (deprecated, use [custom properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) instead) |
| `tags`               | [Veza Tags](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-tags.md) list                 | Any tags to create and apply to the domain.                                                                                                                               |
| `operation`          | enum                                                                                                  | For [incremental updates](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/incremental-updates.md), the operation to use.                                          |

### **`IdP Users`**

Each IdP user object contains the display name, login email, and identity, along with other identity-related properties:

```json
{
      "name": "willis",
      "email": "willis@example.com",
      "identity": "000001",
      "full_name": "Charles Willis",
      "department": "Sales",
      "is_active": true,
      "is_guest": false,
      "groups": [
        {
          "identity": "everyone"
        }
      ],
      "assumed_role_arns": {
        "identity": [
          "arn:aws:iam::123456789012:role/S3Access"
          ]
      },
      "source_identity": {
        "identity": "user0001@corp.example.com",
        "provider_type": "okta"
      },
      "tags": [],
      "custom_properties": {},
      "manager_id": "string",
      "entities_owned": {
        "node_type": "S3Bucket",
        "id": "arn:aws:s3:::amazon-connect-53f87966654d"
        }
    }
```

| Field                | Type                                                                                                  | Description                                                                                                                                                                                                                                          |
| -------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`               | string                                                                                                | Primary ID for user                                                                                                                                                                                                                                  |
| `email`              | string                                                                                                | Optional email for user                                                                                                                                                                                                                              |
| `identity`           | string                                                                                                | Optional unique identifier for user                                                                                                                                                                                                                  |
| `groups`             | string list                                                                                           | Assign groups memberships by group `identity` (optional)                                                                                                                                                                                             |
| `full_name`          | string                                                                                                | Full name to display in Veza                                                                                                                                                                                                                         |
| `department`         | string                                                                                                | Department to apply as a searchable property (optional).                                                                                                                                                                                             |
| `is_active`          | boolean                                                                                               | If available, will be applied to the entity as a searchable property (optional).                                                                                                                                                                     |
| `is_guest`           | boolean                                                                                               | If available, will be applied to the entity as a searchable property (optional).                                                                                                                                                                     |
| `assumed_role_arns`  | array                                                                                                 | AWS IAM roles that can be assumed by the IdP user, in the format `{"identity": ["arn:aws:iam::123456789012:role/S3Access"]}` (optional).                                                                                                             |
| `tags`               | [Veza Tags](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-tags.md) list                 | Any tags to create and apply to the user.                                                                                                                                                                                                            |
| `dynamic_properties` | Dynamic Properties                                                                                    | Up to 5 attributes to apply to the user (deprecated, use [custom properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) instead)                                                                              |
| `custom_properties`  | [Custom Properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) | Each element of the push payload can have `property_values`, validated against the `custom_property_definition`.                                                                                                                                     |
| `manager_id`         | string                                                                                                | If the same as another user's `identity`, that user will be recommended for [access](/4yItIzMvkpAvMVFAamTf/features/access-reviews.md) reviews. Entity details for the user will be updated on push to include the manager as a searchable property. |
| `entities_owned`     | [Entities Owned](#resource-manager-assignments) array                                                 | If another resource is specified by entity type and entity id, a Veza tag will be created on the resource to indicate the owner.                                                                                                                     |
| `operation`          | enum                                                                                                  | For [incremental updates](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/incremental-updates.md), the operation to use (optional).                                                                                                          |
| `source_identity`    | [Source Identity](#source-identity-assignments)                                                       | Optionally link IdP user to user from another IdP for federation use cases.                                                                                                                                                                          |

### **`IdP Groups`**

Add a group by `name` in the `groups` section of the template to enable mapping IdP `users` to those groups:

```json
"groups": [
  {
    "name": "developers",
    "identity": "developers",
    "full_name": null,
    "is_security_group": null,
    "assumed_role_arns": {
      "identity": ["arn:aws:iam::123456789012:role/S3Access"]
    },
    "tags": [],
    "groups": [
      { "group_1_identity": "parent" },
      { "group_2_identity": "parent" }
    ],
    "custom_properties": {}
  }
]
```

| Field                | Type                                                                                                  | Description                                                                                                                                                                |
| -------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`               | string                                                                                                | IdP group name.                                                                                                                                                            |
| `identity`           | string                                                                                                | Unique ID used for user-group assignments.                                                                                                                                 |
| `full_name`          | string                                                                                                | Optional display name for group                                                                                                                                            |
| `groups`             | string list                                                                                           | other custom IdP groups this group is a member of                                                                                                                          |
| `is_security_group`  | boolean                                                                                               | Sets the `is security group` searchable property for the entity in Veza (optional).                                                                                        |
| `tags`               | Veza Tags list                                                                                        | Any [tags](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-tags.md) to create and apply to the group.                                                          |
| `custom_properties`  | [Custom Properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) | Each element of the push payload can have `property_values`, validated against the `custom_property_definition`.                                                           |
| `dynamic_properties` | Dynamic Properties                                                                                    | Up to 5 attributes to apply to the domain. (deprecated, use [custom properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) instead) |
| `operation`          | enum                                                                                                  | For [incremental updates](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/incremental-updates.md), the operation to use (optional).                                |
| `assumed_role_arns`  | array                                                                                                 | AWS IAM roles the group can assume, in the format `{"identity": ["arn:aws:iam::123456789012:role/S3Access"]}` (optional).                                                  |
| `source_identity`    | [Source Identity](#source-identity-assignments)                                                       | Optionally link the IdP group to a group from another IdP for federation use cases (optional).                                                                             |
| `entities_owned`     | [Entities Owned](#resource-manager-assignments) array                                                 | Resources to assign this group as manager of (optional).                                                                                                                   |
| `app_assignments`    | array                                                                                                 | App assignments for this group (optional). See [IdP Apps](#idp-apps).                                                                                                      |

> IdP entities can be granted permissions on custom applications in the `identity_to_permissions` section of the [custom app metadata payload](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/templates/custom-application-template.md).

### **`IdP Apps`**

Use the `apps` section to define any applications used to manage access within the identity provider. Apps can be associated with users and groups to model application assignments across your organization.

```json
  "apps": [
    {
      "id": "app1",
      "name": "Application 1",
      "description": "This is a sample application",
      "assumed_role_arns": [
        {
          "identity": "arn:aws:iam::1234567890:role/DevAppRole"
        }
      ],
      "custom_properties": {
        "owner_org": "engineering"
      },
      "tags": []
    }
  ]
```

| Field               | Type                                                                                                  | Description                                                                                                                                 |
| ------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                | string                                                                                                | App unique identifier.                                                                                                                      |
| `name`              | string                                                                                                | IdP app name.                                                                                                                               |
| `description`       | string                                                                                                | Description for the App (optional).                                                                                                         |
| `assumed_role_arns` | array                                                                                                 | AWS IAM roles the app can assume, in the format `{"identity": ["arn:aws:iam::123456789012:role/S3Access"]}` (optional).                     |
| `custom_properties` | [Custom Properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) | Each element of the payload can have `property_values`, validated against the `custom_property_definition`.                                 |
| `tags`              | Veza Tags list                                                                                        | Any [tags](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-tags.md) to create and apply to the group.                           |
| `operation`         | enum                                                                                                  | For [incremental updates](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/incremental-updates.md), the operation to use (optional). |

The `apps` payload does not accept an `owners` field. To assign owners to `CustomIDPApp` entities, see [Supported entity types for owner assignment](/4yItIzMvkpAvMVFAamTf/features/access-reviews/configuration/managers-and-resource-owners.md#supported-entity-types).

Users and Groups can be assigned to an application by setting the `app_assignments` in the user or group.

```json
    {
      "name": "willis",
      "email": "willis@example.com",
      "identity": "cwilliams",
      "groups": [
        {
          "identity": "everyone"
        }
      ],
      "custom_properties": {
        "region": "NorthAmerica",
        "is_contractor": true
      },
      "app_assignments": [
        {
          "id": "assignment1",
          "name": "Assignment",
          "app_id": "app1",
          "custom_properties": {
            "assigned_on": "2024-12-05T12:42:25+00:00"
          }
        }
      ]
    }
```

| Field               | Type                                                                                                  | Description                                                                                                 |
| ------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `id`                | string                                                                                                | Assignment unique identifier.                                                                               |
| `name`              | string                                                                                                | Display name for the assignment.                                                                            |
| `app_id`            | string                                                                                                | Unique ID of the App to assign the identity to.                                                             |
| `custom_properties` | [Custom Properties](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/oaa-custom-properties.md) | Each element of the payload can have `property_values`, validated against the `custom_property_definition`. |

## Creating and Updating a Custom Identity Provider

The steps to add a custom IdP are the same as for any other OAA provider: you will need to register the new provider and data source, and then push the domain, user, and group descriptions in a JSON payload.

### Register a custom identity provider

To create a new custom provider using the `identity_provider` template, POST the name and template type to /providers/custom:

```bash
curl -X POST 'https://<veza_url>/api/v1/providers/custom' \
-H 'authorization: Bearer '<access_token> \
--data-binary '{"name":"SimpleIdP","custom_template":"identity_provider"}'
```

The response will return the custom IdP ID, which you will need when pushing the metadata payload:

```json
{
  "value": {
    "id": "532f6fe3-189f-4576-afdf-8913088961e4",
    "name": "Simple IdP",
    "custom_template": "identity_provider",
    "state": "ENABLED",
    "application_types": [],
    "resource_types": [],
    "idp_types": []
  }
}
```

### Push a data source for the custom identity provider

```bash
curl -X POST 'https://<veza_url>/api/v1/providers/custom/532f6fe3-189f-4576-afdf-8913088961e4/datasources' \
-H 'authorization: Bearer '<access_token> \
--data-binary '{"id":"532f6fe3-189f-4576-afdf-8913088961e4", "name":"SimpleDataSource"}'
```

Note that the provider id is required in both the path and body of the request. The response will include the new data source ID.

```bash
{"value":{"id":"b6a32af6-b854-47e1-8325-e5984f78bb4d","name":"SimpleDataSource"}}
```

### Push metadata for the data source

```bash
curl -X POST 'https://<veza_url>/api/v1/providers/custom/532f6fe3-189f-4576-afdf-8913088961e4/datasources/b6a32af6-b854-47e1-8325-e5984f78bb4d:push' \
-H 'authorization: Bearer '<access_token> \
--compressed --data-binary @payload.json
```

The payload file must contain the provider and data source ID, and the authorization metadata as a single string, for example:

{% code title="payload.json" %}

```json
{
  "id": "532f6fe3-189f-4576-afdf-8913088961e4",
  "data_source_id": "b6a32af6-b854-47e1-8325-e5984f78bb4d",
  "json_data": "{\n\"name\":\"CustomIdentityProvider\",\n\"idp_type\": ... "
}
```

{% endcode %}

### **`Identity Mapping Configuration`**

The `identity_mapping_configuration` parameter defines rules for connecting users in a custom IdP to users from other data sources in the Veza graph.

This is useful when:

* The connected data source does not natively support returning information about external identities
* A correlation between IdP identities and local users can be assumed based on values like `username`, `email`, or another property value.

The `identity_mapping_configuration` is a top-level property of the Custom IDP submission, and is optional. The mapping configuration can include multiple mappings to connect IDP users to users from different data source types,\
each based on its own mappings.

```json
{
  "identity_mapping_configuration": {
    "mappings": [
      {
        "destination_datasource_type": "OKTA",
        "property_matchers": [
          {
            "source_property": "EMAIL",
            "destination_property": "EMAIL"
          }
        ],
        "transformations": [
          "IGNORE_SPECIAL"
        ]
      },
      {
        "destination_datasource_type": "AZURE_AD",
        "property_matchers": [
          {
            "source_property": "EMAIL",
            "destination_property": "EMAIL"
          }
        ],
        "transformations": [
          "IGNORE_DOMAIN"
        ]
      },
      {
        "destination_datasource_type": "GITHUB_USERS",
        "property_matchers": [
          {
            "source_property": "EMAIL",
            "destination_property": "UNIQUE_ID"
          }
        ]
      }
    ]
  }
}
```

#### Incremental Identity Mapping Updates

You can update just the identity mappings without resubmitting the entire provider payload by using an incremental update. This is useful when you need to modify only the mapping configuration while leaving other provider data unchanged.

<details>

<summary>Example: Incremental Identity Mapping Update</summary>

Set `"incremental_change": true` and use `"operation": "modify"` in the identity\_mapping\_configuration to update mapping rules without affecting other aspects of the provider.

```json
{
  "incremental_change": true,
  "identity_mapping_configuration": {
    "operation": "modify",
    "mappings": [
      {
        "destination_datasource_type": "GITHUB_USERS",
        "property_matchers": [
          {
            "source_property": "EMAIL",
            "destination_property": "UNIQUE_ID"
          }
        ]
      },
      {
        "destination_datasource_type": "SQL_SERVER",
        "property_matchers": [
          {
            "source_property": "EMAIL",
            "destination_property": "EMAIL"
          }
        ],
        "transformations": [
          "IGNORE_DOMAIN"
        ]
      }
    ]
  }
}
```

</details>

Example curl command to apply the incremental identity mapping update:

```bash
curl --location 'https://<veza_url>/api/v1/providers/custom/816d6e51-6d6a-4279-ba41-2e7c732be880/datasources/716026b5-4b84-4b2f-a805-b41a6ec69cf3:push' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <API_KEY>' \
--data '{
    "id": "816d6e51-6d6a-4279-ba41-2e7c732be880",
    "data_source_id": "716026b5-4b84-4b2f-a805-b41a6ec69cf3",
    "json_data": "{\"incremental_change\":true,\"identity_mapping_configuration\":{\"operation\":\"modify\",\"mappings\":[{\"destination_datasource_type\":\"GITHUB_USERS\",\"property_matchers\":[{\"source_property\":\"EMAIL\",\"destination_property\":\"UNIQUE_ID\"}]},{\"destination_datasource_type\":\"SQL_SERVER\",\"property_matchers\":[{\"source_property\":\"EMAIL\",\"destination_property\":\"EMAIL\"}],\"transformations\":[\"IGNORE_DOMAIN\"]}]}}"
}'
```

#### Identity Mapping Configuration

| Field       | Type                        | Description                                                                                                                      |
| ----------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `mappings`  | `IdentityMappingSubmission` | List of mappings to create between IDP Users and external data sources                                                           |
| `operation` | enum                        | For [incremental updates](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/incremental-updates.md), the operation to use. |

#### Identity Mapping Submission

| Field                                 | Type                                        | Description                                                                                                     |
| ------------------------------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `destination_datasource_type`         | string                                      | Veza Type for the destination data source, `GITHUB_USERS`, `SQL_SERVER`, `CUSTOM_APPLICATION`                   |
| `destination_datasource_oaa_app_type` | string                                      | Optional specifically for mapping to OAA Custom Application to provide a specific App Type                      |
| `property_matchers`                   | `IdentityMappingPropertyMatchersSubmission` | List of properties to match on                                                                                  |
| `transformations`                     | list enum                                   | Optional transformations to perform on the property values, available values: `ignore_special`, `ignore_domain` |

Supported transformations:

* `IGNORE_SPECIAL`: Ignore special characters (`_`, `-`, `.`) when matching identities
* `IGNORE_DOMAIN`: Match identities after removing domain portions (e.g., "@example.com")

#### IdentityMappingPropertyMatchersSubmission

| Field                         | Type   | Description                                                                                  |
| ----------------------------- | ------ | -------------------------------------------------------------------------------------------- |
| `source_property`             | enum   | IDP User property to match on, `unique_id`, `email`, `property` or `custom_property`         |
| `destination_property`        | enum   | Destination User property to match on, `unique_id`, `email`, `property` or `custom_property` |
| `custom_source_property`      | string | When using `property` or `custom_propert` the property name to match on                      |
| `custom_destination_property` | string | When using `property` or `custom_propert` the property name to match on                      |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.veza.com/4yItIzMvkpAvMVFAamTf/developers/api/oaa/templates/custom-identity-provider-template.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
