Custom domains


Custom domains overview

PingOne supports the mapping of customer-owned and controlled domain names that are used to access user interfaces and services. Customers have the ability to route their own domain name alias to PingOne hosts, removing all references to “pingone” in the URLs. With a custom domain, the application sign-on URL, https://apps.pingone.com/signon, is seen by end users as https://{CustomDomainName}/signon.

For example, if your company domain is acme.com and you want to use auth.acme.com for your custom domain, you can create a custom domain resource, passing in auth.acme.com. When the custom domain resource is created, the status value is set to VERIFICATION_REQUIRED and the response returns a canonicalName property value that looks similar to this: 1234-abcd-5678-efgh.pingone.com. However, before you can verify the domain, you must first create a record with the Domain Name System (DNS) to describe how traffic is routed for the domain. The DNS record identifies the domain, and it requires a CNAME record value, which is a name/value pair consisting of your domain name pointing to the PingOne canonicalName property value returned by the create request. In this example, the CNAME record resolves auth.acme.com to the canonical name, 1234-abcd-5678-efgh.pingone.com.

After defining the CNAME record in the Domain Name System, you can verify the domain using the POST /environments/{environmentId}/customDomains/{customDomainId} request with the application/vnd.pingidentity.domainName.verify+json custom media type (and an empty request body). Be aware that after entering the CNAME record, it can take some time to propagate to the DNS servers, which can result in a request failure during this period. When successful, the response returns a status of SSL_CERTIFICATE_REQUIRED, which requires an SSL certificate import action.

To import the certificate, you can run the POST /environments/{environmentId}/customDomains/{customDomainId} request again using the application/vnd.pingidentity.certificate.import+json custom media type in the request header. The body for this request must specify the certificate, the certificate chain, and the private key. If successful, the response returns a status of ACTIVE to indicate that the custom domain has been verified and is active. Again, be aware that it can take some time before the custom domain is operational.

The examples that follow show common actions to find and manage custom domain entities. You need the Environment Admin role to perform operations on resources entities.

Resources API operations

The custom domains endpoints support the following operations:

For hands-on experience with the custom domains API endpoints, click the Run in Postman button below to download a Postman collection that you can import and open in your local Postman application.

Custom domains data model

Property Description
certificate An object that specifies information about the SSL certificate used by this custom domain. If this property is not present, it indicates that an SSL certificate has not been setup for this custom domain.
canonicalName A string that specifies the domain name that should be used as the value of the CNAME record in the customer’s DNS.
certificate.expiresAt The time when the certificate expires.
domainName A string that specifies the resource name, which must be provided and must be unique within an environment (for example, auth.shopco.com). This is a required property.
environment.id A string that specifies the environment resource’s unique identifier associated with the resource.
id A string that specifies the resource’s unique identifier.
status A string that specifies the status of the custom domain. Options are ACTIVE, VERIFICATION_REQUIRED, and SSL_CERTIFICATE_REQUIRED.

SSL certificate import request data model

Property Description
certificate A string that specifies the PEM-encoded certificate to import. This is a required property. The following validation is performed on the certificate:
  • It must not be expired.
  • It MUST not be self signed.
  • The custom domain name MUST match one of the subject alternative name (SAN) values on the certificate.
intermediateCertificates A string that specifies the PEM-encoded certificate chain.
privateKey A string that specifies the PEM-encoded, unencrypted private key that matches the certificate’s public key. This is a required property.

Response codes

Code Message
200 Successful operation.
201 Successfully created.
204 Successfully removed. No content.
400 The request could not be completed.
401 You do not have access to this resource.
404 The requested resource was not found.

Endpoint examples

Get custom domains

The GET /environments/{environmentId}/customDomains endpoint returns a list of all custom domain resources associated with the specified environment resource.

curl -X "GET" "https://api.pingone.com/v1/environments/{environmentId}/customDomains" \
-H 'Authorization: Bearer jwtToken'

The response data looks like this:

{
  "_links": {
    "self": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/customDomains"
    }
  },
  "_embedded": {
    "customDomains": [
      {
        "_links": {
          "self": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/customDomains/4490de20-a93d-4369-82a5-b04f935c522a"
          },
          "environment": {
            "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
          }
        },
        "id": "4490de20-a93d-4369-82a5-b04f935c522a",
        "environment": {
          "id": "9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
        },
        "domainName": "custom-domain.example.com",
        "status": "ACTIVE"
      }
    ]
  },
  "count": 1,
  "size": 1
}

Get one custom domain

To get data for a single resource entity, the GET /environments/{environmentId}/customDomains/{customDomainId} operation returns data for the custom domain resource with the specified ID.

curl -X GET "https://api.pingone.com//v1/environments/{environmentId}/customDomains/{customDomainId}" \
-H "Authorization: Bearer jwtToken"

The response data looks like this:

{
  "_links": {
    "self": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/customDomains/4490de20-a93d-4369-82a5-b04f935c522a"
    },
    "environment": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
    }
  },
  "id": "4490de20-a93d-4369-82a5-b04f935c522a",
  "environment": {
    "id": "9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
  },
  "domainName": "custom-domain.example.com",
  "status": "ACTIVE"
}

Create custom domains

The POST /environments/{environmentId}/customDomains operation adds a new resource entity to the specified environment resource.

curl -X "POST" "https://api.pingone.com/v1/environments/{environmentId}/customDomains" \
-H 'Content-type: application/json' \
-H 'Authorization: Bearer jwtToken' \
-d '{
    "domainName": "custom-domain.example.com"
}'

The request body must specify a value for the resource entity’s domainName property, and there cannot be an existing custom domain resource associated with the specified environment. If a custom domain resource already exists for this environment, the response returns a UNIQUENESS_VIOLATION error.

The response data looks like this:

{
  "_links": {
    "self": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/customDomains/93838ab0-0238-40fa-ae4e-6b890882d323"
    },
    "environment": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
    }
  },
  "id": "93838ab0-0238-40fa-ae4e-6b890882d323",
  "environment": {
    "id": "9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
  },
  "domainName": "custom-domain.example.com",
  "status": "VERIFICATION_REQUIRED",
  "canonicalName": "5849925b-5d87-42d4-88fb-12a24bb3a7d6.edge1.pingone.com"
}

Validate custom domains

The POST /environments/{environmentId}/customDomains/{customDomainId} operation is used to validate a custom domain resource when the status property value is set to VERIFICATION_REQURIED. This operation uses the application/vnd.pingidentity.domainName.verify+json custom media type as the content type in the request header.

curl -X "POST" "https://api.pingone.com/v1/environments/{environmentId}/customDomains/{customDomainId}" \
-H 'Content-type: application/vnd.pingidentity.domainName.verify+json' \
-H 'Authorization: Bearer jwtToken'

If successful, the response returns a 200 OK message. If no CNAME record was found with the expected domain alias value, the response returns a REQUEST_FAILED/VERFICATION_FAILED error.

The response data looks like this:

{
  "_links": {
    "self": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/customDomains/4490de20-a93d-4369-82a5-b04f935c522a"
    },
    "environment": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
    }
  },
  "id": "93838ab0-0238-40fa-ae4e-6b890882d323",
  "domainName": "custom-domain.example.com",
  "status": "SSL_CERTIFICATE_REQUIRED",
}

Import the custom domain SSL certificate

The POST /environments/{environmentId}/customDomains/{customDomainId} operation imports the SSL certificate used by the custom domain resource. The request is valid when the status property value is set to SSL_CERTIFICATE_REQUIRED or ACTIVE. This operation uses the application/vnd.pingidentity.certificate.import+json custom media type as the content type in the request header.

curl -X "POST" "https://api.pingone.com/v1/environments/{environmentId}/customDomains/{customDomainId}" \
-H 'Content-type: application/vnd.pingidentity.certificate.import+json' \
-H 'Authorization: Bearer jwtToken' \
-d '{
  "certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
  "intermediateCertificates": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
  "privateKey": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
}'

If any of the certificates and keys are invalid, the response returns an INVALID_VALUE error. If the request is successful, the response returns a 200 OK message.

The response data looks like this:

{
  "_links": {
    "self": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7/customDomains/4490de20-a93d-4369-82a5-b04f935c522a"
    },
    "environment": {
      "href": "https://api.pingone.com/v1/environments/9ad15e9e-3ac6-43f7-a053-d46b87d6c4a7"
    }
  },
  "id": "93838ab0-0238-40fa-ae4e-6b890882d323",
  "domainName": "custom-domain.example.com",
  "status": "ACTIVE",
  "certificate": {
    "expiresAt": "2022-06-04T21:52:34.866Z"
  }
}

Delete custom domains

The following sample shows the DELETE /environments/{environmentId}/customDomains/{customDomainId} operation to delete the resource entity specified by its ID in the request URL.

curl -X DELETE "https://api.pingone.com/v1/environments/{environmentId}/customDomains/{customDomainId}" \
-H "Authorization: Bearer jwtToken"

When successful, the DELETE request returns a code 204 No Content message.