Create a root CA

This page describes how to create a root certificate authority (CA) in a CA pool.

A root CA is at the top of a public key infrastructure (PKI) hierarchy and is responsible for forming the trust anchor of the PKI. To properly participate and use certificates in a PKI, a device, software, or component needs to trust the PKI. This is accomplished by configuring the device, software, or component to trust the root CA. As a result, all the certificates issued by the root CA are trusted.

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.
  • If you use an existing Cloud Key Management Service key to sign certificates that the CA issues, you must grant the necessary IAM roles to the CA Service Agent on that Cloud Key Management Service key. For more information about the specific roles required and instructions, see Using the CA Service Agent.

  • Create a CA pool.

  • Determine your CA settings.

Create a root CA

A root CA has a self-signed certificate that you must distribute to the trust stores of your clients. The root CA's certificate is at the top of the certificate chain. No other CA can revoke the CA certificate. The CRL of the root CA applies only to the other certificates the root CA issued, but not to itself.

You can create a root CA either in an existing CA pool or a new CA pool. The following instructions use an existing pool.

Console

To create a root CA in an existing CA pool, do the following:

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

    Go to Certificate Authority Service

  2. Click the CA manager tab.

  3. Click the Create CA expander arrow, and then select Create CA in an existing CA pool.

Select CA pool

Select an existing CA pool from the list and click Continue.

Select CA type

  1. Under Type, select Root CA.
  2. In the Valid for field, enter the duration that you want the certificates issued by the root CA to be valid for.
  3. Under Initialized state, select the operational state to create the CA in.
  4. Click Continue.
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.
  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.

gcloud

  1. To create a new root CA in an existing CA pool, run the following command:

    gcloud privateca roots create ROOT_CA_ID \
        --location=LOCATION \
        --pool=POOL_ID \
        --key-algorithm=KEY_ALGORITHM \
        --subject="CN=my-ca, O=Test LLC"
    

    Replace the following:

    • ROOT_CA_ID: the name of the CA
    • LOCATION: the location of the CA pool
    • POOL_ID: the name of the CA pool
    • KEY_ALGORITHM: the algorithm to use for creating a Cloud KMS key. This flag is optional. If you don't include this flag, the key algorithm defaults to rsa-pkcs1-4096-sha256. For more information, see --key-algorithm flag.

    By default, the CA is created in the STAGED state. To enable a CA by default, include the --auto-enable flag.

    If you want to use a customer-managed Cloud Storage bucket for publishing CA certificates and CRLs, add --bucket bucket-name to the command. Replace bucket-name with the name of the Cloud Storage bucket.

    To specify custom Authority Information Access (AIA) and CRL Distribution Point (CDP) access URLs, use the --custom-aia-urls and --custom-cdp-urls flags. If specified, these URLs are included in all certificates issued by the CA and supersede the default Cloud Storage bucket access URLs.

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

    gcloud privateca roots create ROOT_CA_ID \
        --location=LOCATION \
        --pool=POOL_ID \
        --kms-key-version=KMS_KEY_VERSION \
        --subject="CN=my-ca, O=Test LLC"
    

    Replace the following:

    • ROOT_CA_ID: the unique identifier of the root CA
    • LOCATION: the location of the CA pool
    • POOL_ID: the name of the CA pool
    • KMS_KEY_VERSION: 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.

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

    gcloud privateca roots create --help
    

Terraform

To create a root CA using a Google-owned and Google-managed encryption key, use the following sample configuration:

resource "google_privateca_certificate_authority" "root_ca" {
  // This example assumes this pool already exists.
  // Pools cannot be deleted in normal test circumstances, so we depend on static pools
  pool                                   = "my-pool"
  certificate_authority_id               = "my-certificate-authority-root"
  location                               = "us-central1"
  deletion_protection                    = false # set to true to prevent destruction of the resource
  ignore_active_certificates_on_deletion = true
  config {
    subject_config {
      subject {
        organization = "ACME"
        common_name  = "my-certificate-authority"
      }
    }
    x509_config {
      ca_options {
        # is_ca *MUST* be true for certificate authorities
        is_ca = true
      }
      key_usage {
        base_key_usage {
          # cert_sign and crl_sign *MUST* be true for certificate authorities
          cert_sign = true
          crl_sign  = true
        }
        extended_key_usage {
        }
      }
    }
  }
  key_spec {
    algorithm = "RSA_PKCS1_4096_SHA256"
  }
  // valid for 10 years
  lifetime = "${10 * 365 * 24 * 3600}s"
}

To create a root CA using a self-managed key, use the following sample configuration:

resource "google_project_service_identity" "privateca_sa" {
  provider = google-beta
  service  = "privateca.googleapis.com"
}

resource "google_kms_crypto_key_iam_binding" "privateca_sa_keyuser_signerverifier" {
  crypto_key_id = "projects/keys-project/locations/us-central1/keyRings/key-ring/cryptoKeys/crypto-key"
  role          = "roles/cloudkms.signerVerifier"

  members = [
    "serviceAccount:${google_project_service_identity.privateca_sa.email}",
  ]
}

resource "google_kms_crypto_key_iam_binding" "privateca_sa_keyuser_viewer" {
  crypto_key_id = "projects/keys-project/locations/us-central1/keyRings/key-ring/cryptoKeys/crypto-key"
  role          = "roles/viewer"
  members = [
    "serviceAccount:${google_project_service_identity.privateca_sa.email}",
  ]
}

resource "google_privateca_certificate_authority" "default" {
  // This example assumes this pool already exists.
  // Pools cannot be deleted in normal test circumstances, so we depend on static pools
  pool                     = "ca-pool"
  certificate_authority_id = "my-certificate-authority"
  location                 = "us-central1"
  deletion_protection      = false # set to true to prevent destruction of the resource
  key_spec {
    cloud_kms_key_version = "projects/keys-project/locations/us-central1/keyRings/key-ring/cryptoKeys/crypto-key/cryptoKeyVersions/1"
  }

  config {
    subject_config {
      subject {
        organization = "Example, Org."
        common_name  = "Example Authority"
      }
    }
    x509_config {
      ca_options {
        # is_ca *MUST* be true for certificate authorities
        is_ca                  = true
        max_issuer_path_length = 10
      }
      key_usage {
        base_key_usage {
          # cert_sign and crl_sign *MUST* be true for certificate authorities
          cert_sign = true
          crl_sign  = true
        }
        extended_key_usage {
          server_auth = false
        }
      }
    }
  }

  depends_on = [
    google_kms_crypto_key_iam_binding.privateca_sa_keyuser_signerverifier,
    google_kms_crypto_key_iam_binding.privateca_sa_keyuser_viewer,
  ]
}

Go

To authenticate to CA Service, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.