Onboarding a New Multi-Tenant (MT) Tenant: Agent Credentials and Installer Configuration

Create the tenant-specific credentials and the installerConfig.json file that the Agent installer uses to connect to a new multi-tenant (MT) tenant.

Summary

When you complete this procedure, you have an installerConfig.json file that lets the Agent installer connect to the tenant without further configuration. All intermediate values, such as tokens and the new tenant client, are created only to produce this file.

You can complete the procedure in either of the following ways:
  1. Option A: Run each step manually by using curl and AdminTools.
  2. Option B: Run the provided PowerShell script, which performs all steps automatically.
Both options produce the same result:
  • A tenant-scoped client ID and client secret for the Agent.
  • An installerConfig.json file that is ready to deliver to the customer.

Before you start either option, collect the values listed in Onboarding Parameters and retrieve the Tenant UUID as described in Retrieving the Tenant UUID.

Onboarding Parameters

The following values are used throughout the onboarding procedure. The table also shows where to obtain each one.

Parameter Description Source
Tenant ID (tenant slug)

Placeholder: <TENANT_ID>

A DNS-safe tenant identifier, for example fp002dev. It is used in the manifest URL path and replaces {{tenant}} in the issuer value of the manifest. Assigned when the tenant is provisioned on the platform.
Tenant UUID

Placeholder: <TENANT_UUID>

The platform-wide tenant identifier, for example 86ebc2d5-f10d-46b9-89fb-32ff4b416015. It is passed as the tenantID parameter when you request a tenant bearer token, and appears with the "global" hint in the ext.tenantId field of a token introspection response.
Important:

The Tenant UUID is not the same as the Tenant ID (slug).

Retrieved from a tenant user's access token. See Retrieving the Tenant UUID.
Cluster host

Placeholder: <CLUSTER_HOST>

The host name of the cluster that serves the tenant's AgentEdge service and configuration manifest, for example fp002dev.gvdevelopment.app.forcepoint.com. Provided by the platform team when the tenant's cluster is provisioned.
Issuer

Placeholder: <ISSUER>

The Forcepoint ONE (F|ONE) OpenID Connect (OIDC) issuer URL for the tenant, for example https://fp002dev.qa.forcepointone.com. Read from the issuer field of the DSPM cluster configuration manifest. Do not set this value manually.
Global client ID and secret

Placeholders: <GLOBAL_CLIENT_ID>, <GLOBAL_CLIENT_SECRET>

A platform-provisioned client with the client:post admin:* scopes. It is shared across all tenants and is used only to obtain a tenant bearer token.
Attention:

Never share the global client credentials with a customer.

Provisioned once by the platform team and reused for every onboarding.
Tenant client ID and secret

Placeholders: <NEW_CLIENT_ID>, <NEW_CLIENT_SECRET>

The new, tenant-scoped client_credentials pair that you create during onboarding. These are the credentials that the customer's Agent uses. Created for each tenant during this procedure.

Retrieving the Tenant UUID

Retrieve the Tenant UUID from the access token of a user who is signed in to the target tenant. You need this value for both Option A and Option B.

Before you begin:
  • A user account that belongs to the target tenant.
  • The <CLUSTER_HOST>, <TENANT_ID>, <GLOBAL_CLIENT_ID>, and <GLOBAL_CLIENT_SECRET> values. See Onboarding Parameters.
Important:

No self-service API is currently available for retrieving the Tenant UUID. Use the following interim procedure.

  1. Sign in to the F|ONE or DSPM user interface as any user that belongs to the target tenant.
  2. Copy the user's access token.
    1. Open the browser developer tools and select the Network tab.
    2. Select any API request that the user interface sends, and view its Authorization request header. The header value has the format Bearer eyJhbGc....
    3. Copy only the token that follows the word Bearer. This value is <USER_ACCESS_TOKEN>.
  3. Fetch the DSPM cluster configuration manifest to obtain the issuer URL.
    curl -s "https://<CLUSTER_HOST>/.well-known/dspm-cluster-configuration/tenants/<TENANT_ID>"
    Note:

    This is the same command as step 1 of Option A. You run it here because the issuer URL is required to retrieve the Tenant UUID.

    Record the value of the issuer field in the response, for example https://fp002dev.qa.forcepointone.com. This value is <ISSUER>.

  4. Introspect the user access token by sending a POST request to the /oidc/introspect endpoint of the issuer.
    curl -s -X POST "<ISSUER>/oidc/introspect" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "token=<USER_ACCESS_TOKEN>" \
      -d "client_id=<GLOBAL_CLIENT_ID>" \
      -d "client_secret=<GLOBAL_CLIENT_SECRET>"

    Pass the global client credentials as client_id and client_secret parameters in the request body. F|ONE does not accept Basic authentication on this endpoint.

    Alternatively, if you have the IntrospectToken helper script, you can use it instead of curl.

  5. In the response, locate the ext.tenantId array and find the entry with "hint": "global".
    "ext": {
      "tenantId": [
        { "hint": "global", "id": "86ebc2d5-f10d-46b9-89fb-32ff4b416015" },
        { "hint": "DSPM", "id": "fp002dev" }
      ]
    }

    The id value of this entry is the Tenant UUID, <TENANT_UUID>.

Result: You have the Tenant UUID. The access token of a signed-in tenant user already contains the Tenant UUID that the platform assigned, so this procedure only reads the existing value; it does not create a new one.

Option A: Onboarding a Tenant Manually

Create the tenant-scoped Agent client and generate the installerConfig.json file manually by using curl, grpcurl, and AdminTools.

Before you begin:

In the commands in this procedure, replace each placeholder in angle brackets with the actual value. Complete the steps in order, because each step produces a value that a later step requires.

  1. Fetch the DSPM cluster configuration manifest to obtain the issuer URL.
    curl -s "https://<CLUSTER_HOST>/.well-known/dspm-cluster-configuration/tenants/<TENANT_ID>"

    Record the value of the issuer field in the response, for example https://fp002dev.qa.forcepointone.com. This value is <ISSUER>, and it is used in steps 2 through 5.

  2. Run OIDC discovery to confirm the token endpoint.
    curl -s "<ISSUER>/.well-known/openid-configuration"

    Verify that the token_endpoint field in the response is <ISSUER>/oidc/token. You do not need to record this value; the later commands use this endpoint directly.

  3. Request a tenant bearer token by using the global client credentials and the Tenant UUID.
    curl -s -X POST "<ISSUER>/oidc/token" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=client_credentials" \
      -d "client_id=<GLOBAL_CLIENT_ID>" \
      -d "client_secret=<GLOBAL_CLIENT_SECRET>" \
      -d "tenantID=<TENANT_UUID>" \
      -d "scope=client:post admin:*"
    Important:

    You must include the client:post admin:* scope. Without it, the request in the next step is rejected.

    Record the value of the access_token field in the response. This value is <TENANT_BEARER_TOKEN>, and it is used only in the next step.

  4. Create the tenant-specific client.
    curl -s -X POST "<ISSUER>/api/clients" \
      -H "Authorization: Bearer <TENANT_BEARER_TOKEN>" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "agent-<TENANT_ID>",
        "clientType": "confidential",
        "grantTypes": ["client_credentials"],
        "responseTypes": ["code"],
        "redirectUris": [],
        "audiences": [],
        "scopes": [],
        "introspectTokens": true
      }'
    Restriction:

    For tenant-specific clients, scopes must be an empty array ([]). Any other value is rejected.

    The "introspectTokens": true setting allows the new client to introspect its own tokens if required.

    The response contains the complete client object, including grant lifespans and other default values set by the server. Locate the id and secret fields. Note that these fields are named id and secret, not client_id and client_secret.

    {
      ...
      "id": "7acf398c-3ab8-4a55-9c21-6c392ca40e67",
      "secret": "<GENERATED_CLIENT_SECRET>",
      "tenantId": "74e39c7e-7308-4fc6-bbf4-c0092d7019d9",
      ...
    }

    The id value is <NEW_CLIENT_ID>, and the secret value is <NEW_CLIENT_SECRET>.

    CAUTION:

    Save both values immediately and store them securely. The secret is displayed only once. You need both values in step 6, and they are the credentials that the customer's Agent uses.

  5. (Recommended) Verify that the new client credentials work.
    1. Request a new access token by using <NEW_CLIENT_ID> and <NEW_CLIENT_SECRET>.

      The tenantID parameter is not required, because the new client is permanently bound to the tenant.

      curl -s -X POST "<ISSUER>/oidc/token" \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -d "grant_type=client_credentials" \
        -d "client_id=<NEW_CLIENT_ID>" \
        -d "client_secret=<NEW_CLIENT_SECRET>"
      Note:

      Do not use <TENANT_BEARER_TOKEN> from step 3. That token was required only to create the client in step 4.

      Record the value of the access_token field in this response. This value is <NEW_ACCESS_TOKEN>.

    2. Use grpcurl to call the AgentEdge GetConfiguration method with <NEW_ACCESS_TOKEN>.
      grpcurl -H "authorization: Bearer <NEW_ACCESS_TOKEN>" <CLUSTER_HOST>:443 \
        GetVisibility.AgentEdge.Proto.ConfigurationService/GetConfiguration
      Note:

      Use GetConfiguration rather than Ping. The Ping method does not require authentication, so it does not verify the credentials.

      If the response contains the configuration in JSON format, the new credentials are valid.

  6. Generate the installerConfig.json file by using AdminTools.
    1. Run GVClient.Tools.AdminTools.Windows.exe.
    2. From the menu, select Generate installerConfig.json.
    3. Respond to the prompts with the values described in the following table. All required values were collected in the previous steps.
      Prompt Value
      Server Address <CLUSTER_HOST>
      Tenant ID <TENANT_ID>
      Language en
      Visual Style Light
      Keycloak URL Press Enter to accept the default (the server address).
      Keycloak Auth Type ClientCredentials
      Keycloak Client ID <NEW_CLIENT_ID> from step 4.
      Keycloak Realm Press Enter to accept the default (gv).
      Keycloak Client Secret <NEW_CLIENT_SECRET> from step 4. AdminTools encrypts the secret automatically.
      All prompts that begin with Mip Press Enter to skip. These settings are not used in this procedure.

    AdminTools writes the installerConfig.json file to the current directory and displays a msiexec command line that you can use to install the Agent.

Result: The tenant-scoped client is created, and the installerConfig.json file is ready to deliver to the customer.

Option B: Onboarding a Tenant by Using the Script

Run the GenerateTenantOidcClient.ps1 PowerShell script to perform all Option A steps automatically.

Before you begin:
  • The GenerateTenantOidcClient.ps1 script, which is attached to the source Confluence page.
  • Windows PowerShell.
  • The <TENANT_UUID>, <TENANT_ID>, and <CLUSTER_HOST> values, and the global client credentials. See Onboarding Parameters.
  1. In the folder that contains the script, create a file named global-client.json that contains the global client credentials.
    { "ClientId": "<GLOBAL_CLIENT_ID>", "ClientSecret": "<GLOBAL_CLIENT_SECRET>" }

    You need to create this file only once. The script reuses it for every tenant.

    Attention:

    This file contains the global client secret. Restrict access to it, and never share it with a customer.

  2. For each new tenant, run the script with the tenant's values.
    .\GenerateTenantOidcClient.ps1 -TenantUuid "<TENANT_UUID>" -TenantId "<TENANT_ID>" -ClusterHost "<CLUSTER_HOST>"
Result: The script performs all steps of Option A automatically. It:
  • Fetches the manifest and resolves the issuer URL.
  • Requests the tenant bearer token.
  • Creates the tenant-specific client.
  • Verifies the new credentials over gRPC by calling GetConfiguration.
  • Writes the configuration file to .\<TENANT_ID>\installerConfig.json.

You do not need to run AdminTools when you use this option.