# Create a subordinate CA from an external CA

This page describes how to create a subordinate certificate authority (CA) that
chains up to an external root CA.

If you have an existing public key infrastructure (PKI) hierarchy containing a
root CA and subordinate CAs, you can maintain the same root CA and create a
subordinate CA in CA Service that chains up to your external root
CA. The external root CA's key and operations remain outside of Google Cloud.
You can only use the external root CA to issue the subordinate CA certificate to
Google Cloud. The subordinate CA is immediately trusted by any workload that
trusts the external root CA. You can then use the subordinate CA to issue
certificates without needing to reach back to the external root CA at runtime.

## Before you begin

- Make sure you have the CA Service Operation Manager (`roles/privateca.caManager`) or the CA Service Admin (`roles/privateca.admin`) IAM role. For information, see [Configure IAM
  policies](https://docs.cloud.google.com/certificate-authority-service/docs/configuring-iam).
- Identify the external root CA.
- Define the name, subject, validity period, and key size for the subordinate CA. For information, see [Determine CA
  Settings](https://docs.cloud.google.com/certificate-authority-service/docs/certificate-authority-settings).

## Create a subordinate CA from an external CA

Creating a subordinate CA from an external CA involves the following steps:

1. **Generate the subordinate CA Certificate Signing Request (CSR)**: The first
   step is to generate a CSR for the subordinate CA and then download the CSR.

2. **Get the subordinate CA certificate signed by the external root CA**: The
   second step is to submit the CSR to the external root CA for signing. Ensure
   that you follow the external root CA's specific instructions for submitting
   CSRs and obtaining signed certificates.

3. **Import the signed subordinate CA certificate into
   CA Service**: The final step is to upload the signed PEM
   certificate chain using either the Google Cloud CLI or the Google Cloud console.

> [!NOTE]
> **Note:** When creating a subordinate CA that chains up to an external CA, the properties included in the CSR generated by CA Service must be preserved in the CA certificate signed by the external CA. The external CA can add additional extensions as long as it preserves the properties in the CSR. For example, if the CSR contains a path length restriction, the signed subordinate CA certificate must also include the same path length restriction.

The following section shows you how to create a subordinate CA from an external
root CA.

### Create a CSR

### Console

1. In Google Cloud console, go to the **Certificate Authority Service** page.

   [Go to Certificate Authority Service](https://console.cloud.google.com/security/cas)
2. Click the **CA manager** tab.

3. Click **Create CA**.

**Select CA type**:

1. Click **Subordinate CA**.
2. In the **Valid for** field, enter the duration that you want the certificates issued by the subordinate CA to be valid for.
3. Click **Root CA is external**.
4. Select one of the available options for the CA **Tier** . For more information, see [Select the operation
   tiers](https://docs.cloud.google.com/certificate-authority-service/docs/tiers).
5. Under **Regionalization** , select a **CA location** from the list.
6. Click **Next**.

**Configure CA subject name**

1. Optional: In the **Organization (O)** field, enter the name of your company.
2. Optional: In the **Organization unit (OU)** field, enter the company subdivision or business unit.
3. Optional: In the **Country name (C)** field, enter a two letter country code.
4. Optional: In the **State or province name** field, enter the name of your state.
5. Optional: In the **Locality name** field, enter the name of your city.
6. In the **CA common name (CN)** field, enter the CA name.
7. Click **Continue**.

**Configure CA key size and algorithm**

1. Choose the key algorithm that best meets your needs. For more details on signing key options, see [Configure CA signing keys](https://docs.cloud.google.com/certificate-authority-service/docs/choosing-key-algorithm).
2. To use a customer-managed signing key, select **Customer-managed key** and provide the Cloud Key Management Service crypto key version.
3. Click **Continue**.

**Configure CA artifacts**

1. Choose whether you want to use a Google-managed or a customer-managed Cloud Storage bucket.
   1. For a Google-managed Cloud Storage bucket, CA Service creates a Google-managed bucket in the same location as the CA.
   2. For a customer-managed Cloud Storage bucket, click Browse and select one of the existing Cloud Storage buckets.
2. Click **Continue**.

**Add labels**


The following steps are optional.


If you want to add labels to the CA, do the following:

1. Click **Add item**.
2. In the **Key 1** field, enter the label key.
3. In the **Value 1** field, enter the label value.
4. If you want to add another label, click **Add item**. Then, add the label key and value as mentioned in steps 2 and 3.
5. Click **Continue**.

**Review the settings**


Carefully review all the settings, then click **Done** to create the CA.

> [!NOTE]
> **Note:** The CA is created in the `AWAITING_USER_ACTIVATION` state. If you don't activate the subordinate CA within 30 days of creation, CA Service deletes the CA.

**Download the CSR**

1. On the **Certificate authority** page, select the CA you want to activate.
2. Click **Activate**.
3. In the dialog that opens, click
   **Download CSR**.

   ![](https://docs.cloud.google.com/static/certificate-authority-service/images/download-ca-csr.png)
   ![Download the CSR of the CA.](https://docs.cloud.google.com/static/certificate-authority-service/images/download-ca-csr.png)

### gcloud

1. To create a CA pool for the subordinate CA, run the following command.
   For more information, see [Create a CA
   pool](https://docs.cloud.google.com/certificate-authority-service/docs/creating-ca-pool).

       gcloud privateca pools create SUBORDINATE_POOL_ID --location=LOCATION

   Replace the following:
   - <var translate="no">SUBORDINATE_POOL_ID</var>: the name of the CA pool
   - <var translate="no">LOCATION</var>: the location of the CA pool
2. To create a subordinate CA in the created CA pool, run the following
   `gcloud` command. The `gcloud` command also creates a CSR and saves it
   to the <var translate="no">FILE_NAME</var> file.

         gcloud privateca subordinates create SUBORDINATE_CA_ID \
             --pool=SUBORDINATE_POOL_ID \
             --location=LOCATION \
             --create-csr --csr-output-file=FILE_NAME \
             --key-algorithm="ec-p256-sha256" \
             --subject="CN=Example Server TLS CA, O=Example LLC"

   Replace the following:
   - <var translate="no">SUBORDINATE_CA_ID</var>: the unique identifier of the subordinate CA
   - <var translate="no">SUBORDINATE_POOL_ID</var>: the name of the CA pool
   - <var translate="no">LOCATION</var>: the location of the CA pool
   - <var translate="no">FILE_NAME</var>: the name of the file where the PEM-encoded CSR is written

   The `--key-algorithm` flag specifies the cryptographic algorithm that you want to
   use for creating a managed Cloud HSM key for the CA.

   The `--subject` flag specifies the X.501 name of the certificate subject.

   For more information about the `gcloud privateca subordinates create`
   command, see [gcloud privateca subordinates
   create](https://docs.cloud.google.com/sdk/gcloud/reference/privateca/subordinates/create).

   To create a subordinate CA using a customer-managed signing key, run the following command:

         gcloud privateca subordinates create SUBORDINATE_CA_ID \
             --pool=SUBORDINATE_POOL_ID \
             --location=LOCATION \
             --create-csr --csr-output-file=FILE_NAME \
             --kms-key-version=KMS_KEY_VERSION \
             --subject="CN=Example Server TLS CA, O=Example LLC"

   Replace the following:
   - <var translate="no">SUBORDINATE_CA_ID</var>: the unique identifier of the subordinate CA
   - <var translate="no">SUBORDINATE_POOL_ID</var>: the name of the CA pool
   - <var translate="no">LOCATION</var>: the location of the CA pool
   - <var translate="no">FILE_NAME</var>: the name of the file where the PEM-encoded CSR is written
   - <var translate="no">KMS_KEY_VERSION</var>: the full resource ID of a customer-managed Cloud KMS crypto key version to use as the signing key

   For more details on signing key options and preparing a customer-managed signing key, see [Configure CA signing keys](https://docs.cloud.google.com/certificate-authority-service/docs/choosing-key-algorithm).

The following statement is returned when the CSR is created:

```
Created Certificate Authority [projects/my-project-pki/locations/us-west1/caPools/SUBORDINATE_POOL_ID/certificateAuthorities/SUBORDINATE_CA_ID] and saved CSR to FILE_NAME.
```

To see the exhaustive list of available settings, run the following command:

    gcloud privateca subordinates create --help

If you lose the CSR, you can download it again using the following
command:

    gcloud privateca subordinates get-csr SUBORDINATE_CA_ID \
        --pool=SUBORDINATE_POOL_ID \
        --location=LOCATION

### Terraform

1. To create a CA pool and a subordinate CA in that CA pool, use the
   following configuration file:

       resource "google_privateca_ca_pool" "default" {
         name     = "test-ca-pool"
         location = "us-central1"
         tier     = "ENTERPRISE"
       }

       resource "google_privateca_certificate_authority" "sub-ca" {
         pool = google_privateca_ca_pool.default.name
         certificate_authority_id = "my-certificate-authority-sub"
         location = "us-central1"
         config {
           subject_config {
             subject {
               organization = "HashiCorp"
               common_name = "my-subordinate-authority"
             }
             subject_alt_name {
               dns_names = ["hashicorp.com"]
             }
           }
           x509_config {
             ca_options {
               is_ca = true
               # Force the sub CA to only issue leaf certs
               max_issuer_path_length = 0
             }
             key_usage {
               base_key_usage {
                 cert_sign = true
                 crl_sign = true
               }
               extended_key_usage {
               }
            }
          }
         }
         lifetime = "86400s"
         key_spec {
           algorithm = "RSA_PKCS1_4096_SHA256"
         }
         type = "SUBORDINATE"
       }

2. To fetch the CSR, append the following configuration.

       data "google_privateca_certificate_authority" "sub-ca-csr" {
         location = "us-central1"
         pool = google_privateca_ca_pool.default.name
         certificate_authority_id = google_privateca_certificate_authority.sub-ca.certificate_authority_id
       }

       output "csr" {
         value = data.google_privateca_certificate_authority.sub-ca-csr.pem_csr
       }

3. Run `terraform apply`.

> [!CAUTION]
> **Caution:** New subordinate CAs are created in the `AWAITING_USER_ACTIVATION` state until they are activated with the signed PEM certificate issued by their parent CA. If you don't activate subordinate CAs within 30 days of creation, the subordinate CAs are deleted. To activate a subordinate CA, see [Upload the
> signed certificate](https://docs.cloud.google.com/certificate-authority-service/docs/create-sub-ca-from-external-ca#upload-signed-certificate).   
> For information about CA states, see [CA
> states](https://docs.cloud.google.com/certificate-authority-service/docs/certificate-authority-states).

### Sign the CSR

Pass the generated CSR file to the member of your organization responsible for
certificate issuance, and request that they sign it. The specific steps depend
on your organization's setup.

You can experiment with a simple root CA using the following `openssl` commands:

### Shell

Configure settings for the new root CA.

    cat > root.conf <<- EOM
    [ req ]
    distinguished_name = req_distinguished_name
    x509_extensions    = v3_ca
    prompt             = no
    [ req_distinguished_name ]
    commonName = Sample Root
    [ v3_ca ]
    subjectKeyIdentifier=hash
    basicConstraints=critical, CA:true
    EOM

Create the new root CA.

    openssl req -x509 -new -nodes -config root.conf -keyout rootCA.key \
      -days 3000 -out rootCA.crt -batch

Configure the extensions that must be added to the new subordinate CA
certificate.

    cat > extensions.conf <<- EOM
    basicConstraints=critical,CA:TRUE,pathlen:0
    keyUsage=critical,keyCertSign,cRLSign
    extendedKeyUsage=critical,serverAuth
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid
    EOM

Sign the subordinate CA's CSR with this root.

    openssl x509 -req -in FILE_NAME -CA rootCA.crt -CAkey rootCA.key \
      -CAcreateserial -out subordinate.crt -days 1095 -sha256 -extfile extensions.conf

Concatenate the entire certificate chain into a single file.

    cat subordinate.crt > chain.crt
    cat rootCA.crt >> chain.crt

> [!NOTE]
> **Note:** By default, [openssl](https://www.openssl.org/docs/man1.1.1/man1/x509.html#BUGS) does not include extensions from the CSR in the signed certificate. `extensions.conf` is required to add extensions to a signed certificate, even though CSRs issued by CA Service include extensions.

### Upload the signed certificate

To activate a subordinate CA using a signed certificate, do the following:

### Console

1. Go to the **Certificate Authority Service** page in the
   Google Cloud console.

   [Go to Certificate Authority Service](https://console.cloud.google.com/security/cas)
2. Click the **CA manager** tab.

3. Under **Certificate authorities**, choose the subordinate CA that you
   created.

4. Click **Activate**.

5. In the dialog that opens, click **Download CSR** to download the
   PEM-encoded CSR file that the issuing CA can sign.

6. Click **Next**.

7. In the **Upload Certificate Chain** field, click **Browse**.

8. Upload the signed certificate file with `.crt` extension.

9. Click **Activate**.

### gcloud

    gcloud privateca subordinates activate SUBORDINATE_CA_ID \
        --pool=SUBORDINATE_POOL_ID \
        --location=LOCATION \
        --pem-chain ./chain.crt

Replace the following:

- <var translate="no">SUBORDINATE_CA_ID</var>: the unique identifier of the subordinate CA that you want to activate
- <var translate="no">SUBORDINATE_POOL_ID</var>: the name of the CA pool that contains the subordinate CA
- <var translate="no">LOCATION</var>: the location of the CA pool. For the complete list of locations, see [Locations](https://docs.cloud.google.com/certificate-authority-service/docs/locations).

The `--pem-chain` flag is required. This flag specifies a file that contains the list of PEM-encoded certificates. The list of certificates starts with the current CA certificate and ends with the root CA certificate.

For more information about the `gcloud privateca subordinates activate` command, see [gcloud privateca subordinates activate](https://docs.cloud.google.com/sdk/gcloud/reference/privateca/subordinates/activate).

The following statement is returned when the signed certificate is uploaded:

```
Activated certificate authority [SUBORDINATE_CA_ID].
```

### Terraform

1. Save the signed CA certificate locally as `subordinate.crt`.
2. Save the signer CA certificates locally as `rootCA.crt`.
3. Remove the configuration for fetching CSR mentioned in the first step as it tries to fetch CSR which is not allowed after CA activation.
4. Update the subordinate CA configuration with the following fields and run
   `terraform apply`.

       pem_ca_certificate     = file("subordinate.crt")
       subordinate_config {
         pem_issuer_chain {
             pem_certificates = [file("rootCA.crt")]
         }
       }

If the issuer chain includes more than one CA, specify the value as
`[file("intermediateCA.cert"), file("rootCA.crt")]`.

> [!NOTE]
> **Note:** Subordinate CAs are set to the `STAGED` state after user activation. Once it has been verified that the CA works as expected, it can be enabled to start issuing load-balanced certificates for the CA pool. To enable a CA, see [Enable
> a subordinate
> CA](https://docs.cloud.google.com/certificate-authority-service/docs/create-subordinate-ca#enable-subordinate-ca). For information about CA states, see [CA
> states](https://docs.cloud.google.com/certificate-authority-service/docs/certificate-authority-states).

## What's next

- Learn how to [request
  certificates](https://docs.cloud.google.com/certificate-authority-service/docs/requesting-certificates).
- Learn about [templates and issuance
  policies](https://docs.cloud.google.com/certificate-authority-service/docs/certificate-template).