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:
Sign in and generate the kubeconfig file for the Management API server if you don't have one.
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.
Create a
CertificateAuthority
resource and save it as a YAML file calledroot-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
andclientAuth
.KEY_ALGORITHYM The private key algorithm used for this certificate. Allowed values are RSA
,Ed25519
, orECDSA
. If the size is not provided, it defaults to 256 forECDSA
and 2048 forRSA
. Key size is ignored forEd25519
.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.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.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