Choosing and Implementing a Search Authentication Method

Any search interface that relies on the Coveo Cloud platform must regularly perform authenticated HTTP requests against the Search API and Coveo Usage Analytics (Coveo UA) Write API. The most commonly used authentication methods are API key authentication and search token authentication.

Each authentication method offers its own set of benefits and drawbacks. This article provides an overview of each method along with diagrams illustrating some of the most typical authentication scenarios to help you choose and implement the authentication method that best fits your needs.

Method Benefits Drawbacks
Public API Key
  • Simple implementation
  • Public API key can be used outside of intended client
  • External use of API key can result in misleading usage analytics data
  • All users are considered anonymous
Private API Key
  • Private API key cannot be used outside of intended client
  • Complex implementation
  • All users are considered anonymous
Search Token
  • Complex implementation

Authentication Scheme

The Search API and Usage Analytics Write API both rely on the bearer HTTP authentication scheme. All HTTP requests made to these services must include an Authorization header with a valid access token (e.g., API key or search token):

Authorization: Bearer <token>

The above information is only useful if your search interface does not rely on the Coveo JavaScript Search Framework, which handles all HTTP requests to the Search API and Usage Analytics Write API on its own, assuming that:

API Key Authentication

An API key is a non-expiring access token which carries a certain set of privileges in a Coveo Cloud organization.

To implement API key authentication, create an API key with the Search - Execute queries and Analytics - Analytics data - Edit privileges in the target Coveo Cloud organization, and ensure that this API key authenticates all Search API and Usage Analytics Write API requests that originate from a specific search interface.

All queries authenticated with this API key will be performed as an anonymous user, so you should only use this method when working with public sources or items that do not have varying levels of security.

API key authentication can be implemented in two ways:

Public API Key Authentication Scenario

The fastest and simplest way to implement API key authentication is to expose a public API key with Search - Execute queries and Analytics - Analytics data - Edit privileges directly in the client. However, there is no way to ensure that all of the Search API and Usage Analytics Write API requests that are authenticated with this key originate from its intended search interface. This can result in the logging of invalid or incorrect usage analytics data, among other issues.

Typical Public API Key Authentication Scenario

In a typical public API key authentication scenario:

  1. The client requests the search interface from the server.

  2. The server generates the search interface code, configures it with a public API key that has the Search - Execute queries and Analytics - Analytics data - Edit privileges, and delivers it to the client.

  3. When a query is triggered, the client calls the Search API through the search interface to execute the query, using its public API key to authenticate the HTTP request.

  4. The Search API executes the query against the index and returns only public items to the client.

  5. The client calls the Usage Analytics Write API through the search interface to log a search event, using its public API key to authenticate the HTTP request.

  6. The Usage Analytics Write API logs a search event for an anonymous user.

Private API Key Authentication Scenario

This is more complicated to implement than search token authentication, and it provides fewer benefits. It is recommended that you use search token authentication instead.

A more complex but more robust way to implement API key authentication is to store an API key with the Search - Execute queries and Analytics - Analytics data - Edit privileges on the server, so that the search interface makes its requests against the server, which in turn makes requests to the appropriate Coveo Cloud services.

With this implementation, the end user cannot see the API key, so it can never be used outside of its intended search interface. Furthermore, you can implement your own throttling mechanism, allowing you to better manage network traffic and avoid potential threats and issues.

You cannot implement private API key authentication in a search interface that relies on the Coveo JavaScript Search Framework.

Typical Private API Key Authentication Scenario

In a typical private API key authentication scenario:

  1. The client requests the search interface from the server.

  2. The server generates the search interface code and delivers the code to the client. The returned search interface is not configured with an API key.

  3. When a query is triggered, the client forwards the query parameters to the server.

  4. The server, acting as a proxy, calls the Search API to execute the query against the index. The server uses a stored, private API key that has the Search - Execute queries and Analytics - Analytics data - Edit privileges to authenticate the HTTP request.

  5. The Search API executes the query against the index and returns only public items to the server, which then returns them to the client.

  6. The server, acting as a proxy, calls the Usage Analytics Write API to log a search event. The server uses the same private API key used in step 4 to authenticate the HTTP request.

  7. The Usage Analytics Write API logs a search event for an anonymous user.

Search Token Authentication

A search token is a temporary, Search API-generated JSON web token which can be used to authenticate certain Search API and Usage Analytics Write API requests as a specific user.

Search tokens can contain information about end users, such as their display names and user groups, which may be used in query pipeline conditions. They can also be used to enforce specific search hubs, query pipelines, and/or filters on the queries they authenticate.

When a search token is used to authenticate a query, the index only returns items that the user for whom the token was generated is allowed to see. You should use this method when working with secure sources or items that have varying levels of security.

Search tokens can be generated for anonymous or non-anonymous (authenticated) users.

Typical Anonymous Search Token Authentication Scenario

In a typical anonymous search token authentication scenario:

  1. The client requests the search interface for an anonymous user from the server.

  2. The server calls the Search API to request a search token for an anonymous user. The server uses a stored, private API key that has the privilege to impersonate (i.e., the Allowed access level on the Impersonate domain) to authenticate the HTTP request (see Privilege Management).

  3. The Search API returns a search token for an anonymous user to the server.

  4. The server delivers a search interface which is configured with the search token returned in step 3.

  5. When a query is triggered, the client calls the Search API through the search interface to execute the query against the index. The client uses the search token returned in step 3 to authenticate the HTTP request.

  6. The Search API executes the query against the index and returns to the client only the query result items that anonymous users are allowed to see (i.e., public items).

  7. The client calls the Usage Analytics Write API through the search interface to log a search event. The client uses the search token returned in step 3 to authenticate the HTTP request.

  8. The Usage Analytics Write API logs a search event for an anonymous user.

Typical Non-Anonymous Search Token Authentication Scenario

In a typical non-anonymous search token authentication scenario:

  1. The client requests the search interface for an authenticated user from the server.

  2. The server validates the user’s credentials and then calls the Search API to request a search token for that authenticated user. The server uses a stored, private API key that has the privilege to impersonate (i.e., the Allowed access level on the Impersonate domain) to authenticate the HTTP request (see Privilege Management).

  3. The Search API returns a search token containing information regarding the authenticated user to the server.

  4. The server delivers a search interface which is configured with the search token returned in step 3.

  5. When a query is triggered, the client calls the Search API through the search interface to execute the query against the index. The client uses the search token returned in step 3 to authenticate the HTTP request.

  6. The Search API executes the query against the index and returns to the client only the query result items that the authenticated user is allowed to see.

  7. The client calls the Usage Analytics Write API through the search interface to log a search event. The client uses the search token returned in step 3 to authenticate the HTTP request.

  8. The Usage Analytics Write API logs a search event for the authenticated user.

In both search token authentication scenarios, you should implement a mechanism to ensure that the end user can get a new search token when their current one expires.

Requesting a Search Token

Make a POST request to https://platform.cloud.coveo.com/rest/search/token (or https://cloudplatform.coveo.com/rest/search/token on Coveo Cloud V1) to request a search token. Use an API key that has the privilege to impersonate (i.e., the Allowed access level on the Impersonate domain) in the target Coveo Cloud organization to authenticate the HTTP request (see Privilege Management).

If an API key has the privilege to impersonate, it should never be exposed in client-side code because this could allow users to impersonate other users and see search results that would otherwise be restricted.

A search token creation call in which you only specify the required values.

POST https://platform.cloud.coveo.com/rest/search/token HTTP/1.1
 
Content-Type: application/json
Authorization: Bearer **********-****-****-****-************

Payload

{
  "userIds": [
    {
      "name": "john_doe@some-domain.com",
      "provider": "Email Security Provider"
    }
  ]
}

A successful request produces a JSON response containing the search token.

{
    "token": "fzKjcHdjPJKJVaJ2OjK0fzK2CI6dHJ1ZSwiZXhwIjoxNDY4Njk2NzEwLCJpYXQiOjE0lQGN..."
}

Use the following identity to generate search tokens for non-authenticated users:

{
  "name": "anonymous",
  "provider": "Email Security Provider",
}

Request Body Properties

The body of a POST request to https://platform.cloud.coveo.com/rest/search/token (or https://cloudplatform.coveo.com/rest/search/token on Coveo Cloud V1) has the following properties:

userIds (array of RestUserId, required)

The security identities to associate with this search token. The RestUserId model has the following properties:

name (string, required)

The name of the security identity (e.g., ”john_doe@some-domain.com”).

provider (string, required)

The security identity provider of the security identity (e.g., ”Email Security Provider”).

type (string)

The security identity type (e.g., “User”).

The body of a search token creation call in which you specify the type of a userIds entry.

{
  "userIds" : [
    {
      "name" : "john_doe@some-domain.com",
      "provider" : "Email Security Provider",
      "type" : "User"
    }
  ]
}

filter (string)

The query expression filter to add to all queries authenticated with this search token (see Coveo Cloud Query Syntax Reference).

You can set this property to ensure that any query authenticated with this token can only return results from a specific subset of items in the index.

The body of a search token creation call in which you specify a constant query expression.

{
  "filter" : "@objecttype=Case",
  "userIds" : [
    {
      "name" : "john_doe@some-domain.com",
      "provider" : "Email Security Provider"
    }
  ]
}

pipeline (string)

The query pipeline to enforce when authenticating a query with this search token (see Adding and Managing Query Pipelines).

The query pipeline you specify for this property takes precedence over the possible output of all other query pipeline routing mechanisms when authenticating a query using this search token (see Query Pipeline Routing Mechanisms and Rules).

The body of a search token creation call in which you specify an enforced pipeline.

{
  "pipeline" : "Tech Support Query Pipeline",
  "userIds" : [
    {
      "name" : "john_doe@some-domain.com",
      "provider" : "Email Security Provider"
    }
  ]
}

searchHub (string)

The search hub to enforce with this search token.

The search hub is an important parameter for Coveo UA, the Coveo Machine Learning (Coveo ML) service, and query pipelines (see Setting the Search Hub).

The body of a search token creation call in which you specify an enforced searchHub.

{
  "searchHub" : "CommunitySearch",
  "userIds" : [
    {
      "name" : "john_doe@some-domain.com",
      "provider" : "Email Security Provider"
    }
  ]
}

userGroups (array of strings)

The userGroups to pass when authenticating an operation to log a search usage analytics event with this search token. User groups can also be used in query pipeline statements (e.g., when $groups contains \"Employees\").

The body of a search token creation call in which you specify userGroups entries.

{
  "userGroups" : [
    "Tech Support",
    "Employee"
  ],
  "userIds" : [
    {
      "name" : "john_doe@some-domain.com",
      "provider" : "Email Security Provider"
    }
  ]
}

userDisplayName (string)

The display name of the end user with whom you want to associate this search token.

The body of a search token creation call in which you specify the end-user display name.

{
  "userDisplayName" : "John Doe",
  "userIds" : [
    {
      "name" : "john_doe@some-domain.com",
      "provider" : "Email Security Provider"
    }
  ]
}

validFor (integer)

The number of milliseconds for which the search token will remain valid once it has been created.

Minimum value is 900000 (i.e., 15 minutes).

Maximum/default value is 86400000 (i.e., 24 hours).

The body of a search token creation call in which you specify the expiration time.

{
  "validFor" : 1800000,
  "userIds" : [
    {
      "name" : "john_doe@some-domain.com",
      "provider" : "Email Security Provider",
    }
  ]
}

The RestTokenParams model also exposes the salesforceCommunityUrl, salesforceFallbackToAdmin, salesforceUser,scope, and superUserToken attributes, while the RestUserId model exposes the authCookie, infos, and password attributes.

Normally, you should not manually specify values for these attributes. They are either intended for internal use by Coveo or exposed for legacy reasons.