# Code Samples for the Chrome Management Certificate Provisioning API

Visit [Cert Provisioning API](https://developers.google.com/chrome/management/guides/certprovisioning_api)
for an overview of API features.

All the requests on this page use the following variables:

- `$TOKEN` - OAuth2 token or self-signed JWT
- `$CUSTOMER` - ID of the customer or literal `my_customer`
- `$CERT_PROVISIONING_PROCESS` - ID of the certificate provisioning process that was transmitted to the Certificate Provisioning Adapter in the initial Pub/Sub message
- `$OPERATION` - ID of the long-running operation

## Get a Certificate Provisioning Process

Get a
[CertificateProvisioningProcess](https://developers.google.com/chrome/management/reference/rest/Shared.Types/CertificateProvisioningProcess)
resource. Depending on the state of the certificate provisioning process, not
all fields of the `CertificateProvisioningProcess` resource are populated in the
response.

#### Request

    curl -H "Authorization: Bearer $TOKEN" \
    https://chromemanagement.googleapis.com/v1/customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS

#### Response

The following response is generated before the client is requested to sign data.

    {
      "name": "customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS",
      "provisioningProfileId": "43b413f9-5ecd-4bf6-b431-f2df56ce852e",
      "subjectPublicKeyInfo": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqtbosvGe1JzJJYBPsPzFY33xD9fSJhQLZh21ELD2vEZ5OSzxXzQOhlXZ2Mv4C3m4zn8mjuYykprBxaMggryd8kyhycm2DDsL2/KUkdQNPnv6mBQ8iionF84iabh+FWph1CU63j2vCPnw0VYSv7cz+bHsxs3tXFB7PqqQZr7WcWAAxFaIqoTkJrTGMzDFs8GHUA6mFhMj0WsPzp3aicj24uW0AAJjVFmiZ+pz1lOOL4coNsVrujrX2E6lU8AHjmoQT6ThRVnuo1jFXoASB4A1It6dtu/P8L3zhsVWYRtOZjLLVvGryzT8z0A8iW5k+apkb465jgLd2vuxFPekAgPRDwIDAQAB",
      "chromeOsDevice": {
        "deviceDirectoryApiId": "abcdefgh-ijkl-mnop-qrst-uvwxyz0123456",
        "serialNumber": "0123456789"
      },
      "startTime": "2025-03-07T13:38:54.930621Z",
      "genericCaConnection": {
        "caConnectionAdapterConfigReference": "default_ca_config"
      },
      "genericProfile": {
        "profileAdapterConfigReference": "device_profile"
      }
    }

## Claim a Certificate Provisioning Process

A Certificate Provisioning Adapter claims a certificate provisioning process.
If multiple Adapter instances are running in parallel, this ensures that the
certificate provisioning process is handled by the same Adapter instance. This
step is also necessary if there is only a single Adapter instance.

#### Request

    curl -H "Authorization: Bearer $TOKEN" \
    --json '{"callerInstanceId": "adapter_instance_1"}' \
    https://chromemanagement.googleapis.com/v1/customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS:claim

#### Response

If the certificate provisioning process has not been claimed before, an empty
response is returned.

    {}

If the certificate provisioning process has already been claimed by another
Adapter instance, the `claim` request will fail with a 400 Bad Request error.

## Request a Proof of Possession Signature

Request the client requesting a certificate to sign some data using the
specified [SignatureAlgorithm](https://developers.google.com/chrome/management/reference/rest/Shared.Types/SignatureAlgorithm)
with the private key corresponding to the public key in the certificate
provisioning process. The `$DATA_TO_SIGN` represents the Base64-encoded data to
be signed by the client.

#### Request

    curl -H "Authorization: Bearer $TOKEN" \
    --json '{"signData": "$DATA_TO_SIGN","signatureAlgorithm":"SIGNATURE_ALGORITHM_RSA_PKCS1_V1_5_SHA256"}'\
    https://chromemanagement.googleapis.com/v1/customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS:signData

#### Response

The response contains an [Operation](https://developers.google.com/chrome/management/reference/rest/v1/customers.certificateProvisioningProcesses.operations)
with the metadata field being populated with a [SignDataMetadata](https://developers.google.com/chrome/management/reference/rest/Shared.Types/SignDataMetadata)
proto message.

    {
      "name": "customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS/operations/$OPERATION",
      "metadata": {
        "@type": "type.googleapis.com/google.chrome.management.versions.v1.SignDataMetadata",
        "startTime": "2025-03-07T14:44:06.156385Z"
      }
    }

## Get long-running Operation

Get the latest state of a long-running operation returned from the `SignData`
request.

#### Request

    curl -H "Authorization: Bearer $TOKEN" \
    https://chromemanagement.googleapis.com/v1/customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS/operations/$OPERATION

#### Response

The `metadata` field of an
[Operation](https://developers.google.com/chrome/management/reference/rest/v1/customers.certificateProvisioningProcesses.operations)
is populated with a
[SignDataMetadata](https://developers.google.com/chrome/management/reference/rest/Shared.Types/SignDataMetadata)
proto message. If present, the `response` of an Operation is populated with a
[SignDataResponse](https://developers.google.com/chrome/management/reference/rest/Shared.Types/SignDataResponse)
proto message.

In case the long-running operation is still ongoing:

    {
      "name": "customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS/operations/$OPERATION",
      "metadata": {
        "@type": "type.googleapis.com/google.chrome.management.versions.v1.SignDataMetadata",
        "startTime": "2025-03-07T14:44:06.156385Z"
      }
    }

In case the long-running operation has completed successfully:

    {
      "name": "customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS/operations/$OPERATION",
      "metadata": {
        "@type": "type.googleapis.com/google.chrome.management.versions.v1.SignDataMetadata",
        "startTime": "2025-03-07T14:44:06.156385Z"
      },
      "done": true,
      "response": {
        "@type": "type.googleapis.com/google.chrome.management.versions.v1.SignDataResponse",
        "certificateProvisioningProcess": {
          "name": "customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS",
          "provisioningProfileId": "43b413f9-5ecd-4bf6-b431-f2df56ce852e",
          "subjectPublicKeyInfo": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqtbosvGe1JzJJYBPsPzFY33xD9fSJhQLZh21ELD2vEZ5OSzxXzQOhlXZ2Mv4C3m4zn8mjuYykprBxaMggryd8kyhycm2DDsL2/KUkdQNPnv6mBQ8iionF84iabh+FWph1CU63j2vCPnw0VYSv7cz+bHsxs3tXFB7PqqQZr7WcWAAxFaIqoTkJrTGMzDFs8GHUA6mFhMj0WsPzp3aicj24uW0AAJjVFmiZ+pz1lOOL4coNsVrujrX2E6lU8AHjmoQT6ThRVnuo1jFXoASB4A1It6dtu/P8L3zhsVWYRtOZjLLVvGryzT8z0A8iW5k+apkb465jgLd2vuxFPekAgPRDwIDAQAB",
          "chromeOsDevice": {
            "deviceDirectoryApiId": "abcdefgh-ijkl-mnop-qrst-uvwxyz0123456",
            "serialNumber": "0123456789"
          },
          "startTime": "2025-03-07T13:38:54.930621Z",
          "signData": "ZGF0YSB0byBzaWduCg==",
          "signatureAlgorithm": "SIGNATURE_ALGORITHM_RSA_PKCS1_V1_5_SHA256",
          "signature": "mPfL8v/DR+ZqbtJ6X5cJCTrzfOO3wPHCY8nV/stbokdNZnkRJ8U0PBzgm6pWy08pMmOfrs9ZMBXcQ0i05Oe6AwgHYYN5RHuwdnhAklJYriDT4fXdzewD6KuA6x7ZX1d2xYnh0p2XczcdNOJsrz2T/p+89PLcB6I1PIg1Cwz4I1YCAS2OMAQF5DxS+SvMpPbkdzkNG4SCCL/hJNayxRMr98SbQ0aQE77AtxzpXGof5cBEBOcbQ+T+kBIgArQ87D6bQVHVB3di+TvYepK6hwxiLbhCEDGHgi2DfMp8kEWnAVPVzi6xht5jPNhVqILALRbQQ1nUjlP8UO+/y+WR4M36Yg==",
          "genericCaConnection": {
            "caConnectionAdapterConfigReference": "default_ca_config"
          },
          "genericProfile": {
            "profileAdapterConfigReference": "device_profile"
          }
        }
      }
    }

In case the long-running operation has failed:

    {
      "name": "customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS/operations/$OPERATION",
      "metadata": {
        "@type": "type.googleapis.com/google.chrome.management.versions.v1.SignDataMetadata",
        "startTime": "2025-03-07T14:44:06.156385Z"
      },
      "done": true,
      "error": {
        "code": 3,
        "message": "The requested SignData LRO failed because the corresponding certificate provisioning process is in failure state CERTIFICATE_PROVISIONING_RESULT_ERROR_INVALID_SIGNATURE with the following error message: The proof of possession signature is invalid. [operationId=$OPERATION, cppId=$CERT_PROVISIONING_PROCESS, customerId=$CUSTOMER]"
      }
    }

## Upload a Certificate

Upload X.509 certificate in PEM format. In the sample request the PEM-encoded
certificate is denoted by the `$CERTIFICATE_IN_PEM_FORMAT` variable.

#### Request

    curl -H "Authorization: Bearer $TOKEN" \
    --json '{"certificatePem": "$CERTIFICATE_IN_PEM_FORMAT"}' \
    https://chromemanagement.googleapis.com/v1/customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS:uploadCertificate

#### Response

    {}

## Report a failure for a Certificate Provisioning Process

Mark a certificate provisioning process as failing and set an appropriate error
message. The error message is propagated to the ChromeOS client that initiated
the certificate provisioning process.

#### Request

    curl -H "Authorization: Bearer $TOKEN" \
    --json '{"errorMessage": "The CA could not issue the certificate."}' \
    https://chromemanagement.googleapis.com/v1/customers/$CUSTOMER/certificateProvisioningProcesses/$CERT_PROVISIONING_PROCESS:setFailure

#### Response

    {}