Set up external identities

Enterprises typically manage identities (users and user groups) using an identity provider (IDP). The IDP acts as the source of truth for identities in an organization, is responsible for provisioning new identities, and enforces authentication.

When using third-party SaaS solutions, enterprises often connect these solutions to their IDP so that all employees can use their single corporate credentials to sign in and access company resources.

However, some SaaS applications allow customers to create new user groups that are defined locally within that application, instead of being defined and managed in the IDP. This is also common for custom applications that an enterprise has built in-house. These application-specific user groups or secondary user IDs are referred to as external identities.

For example, if user groups are defined in Jira, then the IDP and other SaaS applications don't have visibility into those external identities. Similarly, the IDP doesn't have visibility into RBAC roles that are defined in Sharepoint.

Why set up identity mapping?

To make sure that Google can enforce access control correctly, map your IDP identities to any external identities from SaaS applications that you plan to use with Google Agentspace Enterprise.

To apply access control to app results, Google uses the IDP as the source of truth to determine which data your users have access to. Enterprises often connect their IDP to other SaaS solutions so that an employee can use a single set of corporate credentials to sign into and access all company resources.

If you have external identities defined through applications that you plan to connect to your app such as third-party applications or custom applications, then your IDP isn't the only source of truth for access control.

For example, say that "JaneDoe" exists within Example Organization, with domain "example.com". The ID in the IDP is defined as "JaneDoe@example.com". The same user has a separate ID within a third-party application as "JDoe". The IDP might not be aware of this ID. Because of this, Google Agentspace Enterprise does not receive information about the third-party application IDs through the IDP.

In Google Agentspace Enterprise, identity mappings are stored in an identity mapping store that you create and import the mappings into. If you plan to use a custom connector, you can then bind the identity mapping store to the custom connector data store. Then update your data store's ACL metadata with information about your external identities.

Before you begin

Before setting up identity mapping, do the following:

  1. Reach out to your Google contact to add your project to the allowlist for the identity mapping API.
  2. Connect your identity provider in your Google Cloud project.

Prepare identity mapping entries

Prepare the identity mapping entries for import. Identity mappings should be formatted as in the following example:

{
  "identity_mapping_entries":
  { "external_identity": "u1", "user_id": "user1@example.com" },
  "identity_mapping_entries":
  { "external_identity": "u2", "user_id": "user2@example.com" },
  "identity_mapping_entries":
  { "external_identity": "gABC", "group_id": "groupABC@example.com" }
}

For example, the following chart represents an example user-group membership, where Ext represents external groups. This chart shows an example relationship between external groups to IDP users and groups.

External identity relationship to IDP users and groups.

This user-group membership graph would have following mapping:

{
  "identity_mapping_entries":
  {"external_identity": "Ext1", "user_id": "IDPUser1@example.com"},
  "identity_mapping_entries":
  {"external_identity": "Ext2", "user_id": "IDPUser1@example.com"},
  "identity_mapping_entries":
  {"external_identity": "Ext2", "user_id": "IDPUser2@example.com"},
  "identity_mapping_entries":
  {"external_identity": "Ext3", "user_id": "IDPUser2@example.com"},
  "identity_mapping_entries":
  {"external_identity": "Ext3", "group_id": "IDPGroup1@example.com"},
  "identity_mapping_entries":
  {"external_identity": "Ext3", "group_id": "IDPGroup2@example.com"}
}

Nested identity memberships, where external identities have child identities, must be flattened.

Google assumes that the connector sends a primary ID for an external identity. For example, import the group ID instead of the group name, because the name could be changed over the lifetime of the group within the third-party application.

Set up identity mapping

Use the following procedures to set up identity mapping in Google Agentspace Enterprise between your IDP and your external identities. In the following steps, you will create an identity mapping store, import the identity mappings that you prepared. If you plan to use a custom connector, you will also create a new data store that is bound to the identity mapping store.

Create an identity mapping store

The first step is to set up an identity mapping store. This is the parent resource in which all identity mappings are stored.

When you create the identity mapping store, it automatically fetches the IDP configuration from the IDP that you connected to your Agentspace Enterprise project.

  1. To create an identity mapping store, run the following command using the identityMappingStores.create method:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: PROJECT_ID" \
    "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/identityMappingStores?identityMappingStoreId=IDENTITY_MAPPING_STORE_ID" \
    -d '{
      "name": "projects/PROJECT_ID/locations/global/identityMappingStores/IDENTITY_MAPPING_STORE_ID"
    
    }'
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • IDENTITY_MAPPING_STORE_ID: the unique ID for the identity mapping store. For example, test-id-mapping-store.

Import identity mappings

After creating the identity mapping store, import the identity mappings entries that you prepared.

  1. To import your identity mappings, run the following command using the importIdentityMappings method:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" -H "x-goog-user-project: PROJECT_ID" \
    "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/identityMappingStores/IDENTITY_MAPPING_STORE_ID:importIdentityMappings" \
    -d '{"inline_source" : IDENTITY_MAPPINGS_JSON}'
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • IDENTITY_MAPPING_STORE_ID: the unique ID of the identity mapping store.
    • IDENTITY_MAPPINGS_JSON: the prepared identity mappings in JSON format.
  2. Next, if you plan to build a custom connector and use external identities, go to Bind custom data stores to the identity mapping store. Otherwise, skip to Update ACL metadata.

Bind custom data stores to the identity mapping store

This procedure is only necessary if you build a custom connector. If you are not building a custom connector, skip this step.

For custom connectors, the identity mapping store needs to be bound to the data store before an external identity can be associated with its documents. Setting this field is allowed only during data store creation.

  1. To bind a data store to the identity mapping store, specify identity_mapping_store during data store creation using the Datastores.create method.

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json"  \
    -H "X-Goog-User-Project: PROJECT_ID" \
    "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/collections/default_collection/dataStores?dataStoreId=DATA_STORE_ID \
    -d '{
        ...
        "identity_mapping_store": IDENTITY_MAPPING_STORE_NAME"
    }'
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • DATA_STORE_ID: the ID of the data store that you want to create. This ID can contain only lowercase letters, digits, underscores, and hyphens.
    • IDENTITY_MAPPING_STORE_NAME: the full resource name of the identity mapping store. For example, projects/exampleproject/locations/global/identityMappingStores/test-id-mapping-store. After creating a data store, this name can't be updated.

Add ACL metadata

Include ACL metadata in the AclInfo object for your documents.

When a user sends a search request and documents whose ACL metadata include external identities are fetched, then those external identities are evaluated. If the user's identity (groupID or userID) is mapped to an external identity (externalEntityId) that is associated with a document, then the user gets access to that document.

For example, say that you have created a custom connector for Jira. A given Jira issue is accessible by certain IDP users, certain IDP groups, and an administrator role. To allow that issue to be accessible by those people in search results, you can create an identity mapping store and map IDP users and groups to Jira-specific external identities. Bind the identity mapping store to your Jira data store. Then, create documents in your Jira data stores with aclInfo configured with the IDP users, IDP groups, and external identities who should have access to those documents.

To update your ACL metadata with information about your external identities, use the following format to specify the external identities and associated user and group IDs.

{
  "aclInfo": {
    "readers": [
      {
        "principals": [
          {
            "groupId": "group_1"
          },
          {
            "userId": "user_1"
          },
          {
            "externalEntityId": "external_id1"
          }

        ]
      }
    ]
  }
}

For more information about updating ACL metadata, see Configure a data source with access control.

Manage identity mappings

You can list identity mappings in an identity store, or you can purge an identity store by defining them through an inline source or by using a filter condition.

Management tasks available for identity mapping are:

List identity mappings

  1. To list identity mappings, run the following command using the listIdentityMappings method:

    curl -X GET \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H  "Content-Type: application/json" \
    -H "x-goog-user-project: PROJECT_ID" \
    https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/identityMappingStores/IDENTITY_MAPPING_STORE_ID:listIdentityMappings?page_size=PAGE_SIZE&page_token=PAGE_TOKEN
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • PAGE_SIZE: maximum number of identity mapping stores to return. If unspecified, defaults to 100. The maximum allowed value is 1000. Values higher than 1000 will be coerced to 1000.
    • PAGE_TOKEN: a page token, received from a previous ListIdentityMappingStores call. Provide this to retrieve the subsequent page.

Purge using inline source

You can purge specified entries from an identity mapping store by providing a JSON file of which identities to purge.

  1. To purge identity mappings using inline source, run the following command using the purgeIdentityMappings method:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -H "x-goog-user-project: PROJECT_ID" \
    "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/identityMappingStores/IDENTITY_MAPPING_STORE_ID:purgeIdentityMappings" \
    -d '{"inline_source" : IDENTITY_MAPPINGS_JSON}'
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • IDENTITY_MAPPING_STORE_ID: the unique ID of the identity mapping store.
    • IDENTITY_MAPPING_STORE_NAME: the identity mapping store name.
    • IDENTITY_MAPPINGS_JSON: the identity mappings to be purged.

Purge using a filter condition

You can purge specified entries from an identity mapping store by filtering for entries by update time, external identity, or all entries.

  1. To purge identity mappings using a filter condition, run the following command using the purgeIdentityMappings method:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -H "x-goog-user-project: PROJECT_ID" \
    "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/identityMappingStores/IDENTITY_MAPPING_STORE_ID:purgeIdentityMappings" \
    -d '{"identity_mapping_store":"IDENTITY_MAPPING_STORE_NAME", "filter": "FILTER_CONDITION"}'
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • IDENTITY_MAPPING_STORE_ID: the unique ID of the identity mapping store.
    • IDENTITY_MAPPING_STORE_NAME: the identity mapping store name.
    • FILTER_CONDITION: one of the following filter types:
      • Update time. For example, update_time > "2012-04-23T18:25:43.511Z" AND update_time < "2012-04-23T18:30:43.511Z">
      • External Identity. For example, external_id = "id1"
      • All identity mappings. For example, *

Manage identity mapping stores

You can get, delete, list, and purge identity mapping stores.

Get identity mapping store

  1. To get an identity mapping store, run the following command using the identityMappingStores.get method:

    curl -X GET \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: PROJECT_ID" \
    "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/identityMappingStores/IDENTITY_MAPPING_STORE_ID"
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • IDENTITY_MAPPING_STORE_ID: the unique ID of the identity mapping store.
    • IDENTITY_MAPPING_STORE_NAME: the identity mapping store name.

List identity mapping stores

  1. To list identity mapping stores, run the following command using the identityMappingStores.list method:

    curl -X GET \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H  "Content-Type: application/json" \
    -H "x-goog-user-project: PROJECT_ID" \
    "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/identityMappingStores?page_size=PAGE_SIZE&page_token=PAGE_TOKEN"
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • PAGE_SIZE: maximum number of identity mapping stores to return. If unspecified, defaults to 100. The maximum allowed value is 1000. Values higher than 1000 will be coerced to 1000.
    • PAGE_TOKEN: a page token, received from a previous ListIdentityMappingStores call. Provide this to retrieve the subsequent page.

Delete identity mapping stores

To delete an identity mapping store, it must not be bound to a data store, and no identity mappings can be present in the identity mapping store.

  1. To delete an identity mapping store, run the following command using the identityMappingStores.delete method:

    curl -X DELETE \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: PROJECT_ID" \
    "https://discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/global/identityMappingStores/IDENTITY_MAPPING_STORE_ID"
    

    Replace the following:

    • PROJECT_ID: the ID of your project.
    • IDENTITY_MAPPING_STORE_ID: the unique ID of the identity mapping store.
    • IDENTITY_MAPPING_STORE_NAME: the identity mapping store name.