Create a root certificate authority

This page describes the steps to create a root certificate authority (CA) in Google Distributed Cloud (GDC) air-gapped.

A root CA, which sits atop the public key infrastructure (PKI) hierarchy, establishes the trust anchor for the PKI. To use certificates within a PKI, devices, software, and components must trust the root CA. This configuration ensures trust in all certificates issued by the root CA, thereby enabling trust in the PKI itself.

Before you begin

To get the permissions you need to create a root certificate authority, ask your Organization IAM Admin to grant you the Certificate Authority Service Admin (certificate-authority-service-admin) role. For more information on roles, see Role definitions.

Get the kubeconfig file

To run commands against the Management API server, ensure you have the following resources:

  1. Sign in and generate the kubeconfig file for the Management API server if you don't have one.

  2. Use the path to the kubeconfig file of the Management API server to replace MANAGEMENT_API_SERVER_KUBECONFIG in these instructions.

Create a root certificate authority

To create a root CA, apply a custom resource to your Distributed Cloud air-gapped instance.

  1. Create a CertificateAuthority resource and save it as a YAML file called root-ca.yaml:

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateAuthority
    metadata:
      Name: ROOT_CA_NAME
      namespace: USER_PROJECT_NAMESPACE
    spec:
      caProfile:
        commonName: COMMON_NAME
        duration: DURATION
        renewBefore: RENEW_BEFORE
        organizations:
        - ORGANIZATION
        organizationalUnits:
        - ORGANIZATIONAL_UNITS
        countries:
        - COUNTRIES
        localities:
        - LOCALTIES
        provinces:
        - PROVINCES
        streetAddresses:
        - STREET_ADDRESSES
        postalCodes:
        - POSTAL_CODES
      caCertificate:
        selfSignedCA: {}
      certificateProfile:
        keyUsage:
          - digitalSignature
          - keyCertSign
          - crlSign
        extendedKeyUsage:
          - EXTENDED_KEY_USAGE
      secretConfig:
        secretName: SECRET_NAME
        privateKeyConfig:
          algorithm: KEY_ALGORITHM
          size: KEY_SIZE
      acme:
        enabled: ACME_ENABLED
    

    Replace the following variables:

    Variable Description
    ROOT_CA_NAME The name of the root CA.
    USER_PROJECT_NAMESPACE The name of the namespace where the user project resides.
    COMMON_NAME The common name of the CA certificate.
    DURATION The requested lifetime of the CA certificate.
    SECRET_NAME The name of the Kubernetes Secret that holds the private key and signed CA certificate.

    The following variables are optional values:

    Variable Description
    RENEW_BEFORE The rotation time before the CA certificate expires.
    ORGANIZATION Organization to be used on the certificate.
    ORGANIZATIONAL_UNITS Organizational units to be used on the certificate.
    COUNTRIES Countries to be used on the certificate.
    LOCALITIES Cities to be used on the certificate.
    PROVINCES State or Provinces to be used on the certificate.
    STREET_ADDRESSES Street addresses to be used on the certificate.
    POSTAL_CODES Postal codes to be used on the certificate.
    EXTENDED_KEY_USAGE The extended key usage for the certificate. If provided, the allowed values are serverAuth and clientAuth.
    KEY_ALGORITHYM The private key algorithm used for this certificate. Allowed values are RSA, Ed25519, or ECDSA. If the size is not provided, it defaults to 256 for ECDSA and 2048 for RSA. Key size is ignored for Ed25519.
    KEY_SIZE The size, in bits, of the private key for this certificate depends on the algorithm. RSA allows 2048, 3072, 4096, or 8192 (default 2048). ECDSA allows 256, 384, or 521 (default 256). Ed25519 ignores size.
    ACME_ENABLED If set to true, CA runs in ACME mode and outputs the ACME server URL. You can then use the ACME client and protocol to manage certificates.

  2. Apply the custom resource to your Distributed Cloud instance:

    kubectl apply -f root-ca.yaml –kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG
    

    Replace MANAGEMENT_API_SERVER_KUBECONFIG with the path to the kubeconfig file of the Management API server.

  3. Verify the readiness of the root CA. It normally takes around 40 minutes for the CA to become ready:

    kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificateauthority.pki.security.gdc.goog/ROOT_CA_NAME -ojson | jq -r ' 
    .status.conditions[] | select( .type as $id | "Ready" | index($id))
    

    The output looks similar to the following:

    {
      "lastTransitionTime": "2025-01-24T17:09:19Z",
      "message": "CA reconciled",
      "observedGeneration": 2,
      "reason": "Ready",
      "status": "True",
      "type": "Ready"
    }
    

List CAs

To list all of the Certificate Authority Service resources in your Distributed Cloud air-gapped instance, do the following:

Use the certificateauthorities parameter to list all CertificateAuthority resources:

   kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificateauthorities

The output looks similar to the following:

   NAMESPACE    NAME              READY   REASON   AGE
   foo          root-ca           True    Ready    7h24m
   foo          sub-ca            True    Ready    7h24m