Request a certificate

This page describes the steps to request a certificate using the Certificate Authority Service.

To establish trust and secure communication within your Google Distributed Cloud (GDC) air-gapped, request an ACME-enabled or disabled certificate from the Certificate Authority Service.

Before you begin

To get the permissions you need to request a certificate, ask your Organization IAM Admin to grant you the Certificate Authority Service Admin (certificate-authority-service-admin) role.

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.

Request a certificate using CA with ACME mode enabled

If the certificate authority is hosted in ACME mode, it outputs the ACME server URL in its status after it becomes ready.

Gather the CA ACME server URL from your Distributed Cloud environment:

kubectl get certificateauthorities CA_NAME -n USER_PROJECT_NAMESPACE -ojson | jq -r '.status.acme.uri'

Replace the following:

  • CA_NAME: The name of the CA, which can be a root or sub CA.
  • USER_PROJECT_NAMESPACE: The name of the namespace where the user project resides.

Request a certificate using CA with ACME mode disabled

To create a certificate request with ACME mode disabled, you must create and apply a CertificateRequest resource to your Distributed Cloud air-gapped instance. There are two ways to do this:

  • Create a CertifateResource and include a CSR in the resource.
  • Create a CertificateResource using a GDC auto-generated private key and provide the certificate configurations as custom values.

Request a certificate using a CSR

  1. Create a CertificateRequest resource and save it as a YAML file called cert-request.yaml. Use your private key to create a Certificate Signing Request (CSR) and add it to your resource:

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateRequest
    metadata:
      name: CERT_REQ_NAME
      namespace: USER_PROJECT_NAMESPACE
    spec:
      certificateAuthorityRef:
        name: CA_NAME
        namespace: USER_PROJECT_NAMESPACE
      csr: CSR
      signedCertificateSecret: SECRET_NAME
    

    Replace the following variables:

    Variable Description
    CERT_REQ_NAME The name of the certificate.
    USER_PROJECT_NAMESPACE The name of the namespace where the user project resides.
    CA_NAME The name of the CA, which can be a root or sub CA.
    CSR The Certificate Signing Request to sign using CA.
    SECRET_NAME The name of the Kubernetes Secret that holds the private key and signed CA certificate.
  2. Apply the custom resource to your Distributed Cloud instance:

    kubectl apply -f cert-request.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 certificate request:

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

    The output is similar to the following:

    {
      "lastTransitionTime": "2025-01-27T12:22:59Z",
      "message": "Certificate is issued",
      "observedGeneration": 1,
      "reason": "Issued",
      "status": "True",
      "type": "Ready"
    }
    
  4. Get the certificate secret name:

    kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificaterequest.pki.security.gdc.goog/CERT_REQ_NAME -ojson | jq -r '.spec.signedCertificateSecret'
    

    The output shows the SECRET_NAME containing the signed certificate:

    test-jwk-1
    

Request a certificate using an auto-generated key

  1. Create a CertificateRequest resource and save it as a YAML file called cert-request.yaml. Populate the chosen values for the certificate:

    apiVersion: pki.security.gdc.goog/v1
    kind: CertificateRequest
    metadata:
      name: CERT_REQ_NAME
      namespace: USER_PROJECT_NAMESPACE
    spec:
      certificateAuthorityRef:
        name: CA_NAME
        namespace: USER_PROJECT_NAMESPACE
      certificateConfig:
        subjectConfig:
          commonName: COMMON_NAME
          organization: ORGANIZATION
          locality: LOCALITY
          state: STATE
          country: COUNTRY
          dnsNames: 
          - DNS_NAMES
          ipAddresses:
          - IP_ADDRESSES
          rfc822Names:
          - RFC822NAMES
          uris:
          - URIS
      signedCertificateSecret: SECRET_NAME
    

    Replace COMMON_NAME with the common name of the certificate.

    Replace the following optional variables. You must include at least one of these values in the CertificateRequest resource:

    Variable Description
    ORGANIZATION Organization to be used on the certificate.
    LOCALITY The locality of the certificate.
    STATE State or Province to be used on the certificate.
    COUNTRY The country of the certificate.
    DNS_NAMES DNSNames is a list of dNSName subjectAltNames to be set on the certificate.
    IP_ADDRESS A list of ipAddress subjectAltNames to be set on the certificate.
    RFC822_NAMES A list of rfc822Name subjectAltNames to be set on the certificate.
    URIS A list of uniformResourceIdentifier subjectAltNames to be set on the certificate.
  2. Apply the custom resource to your Distributed Cloud instance:

    kubectl apply -f cert-request.yaml --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG
    
  3. Verify the readiness of the certificate request:

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

    The output is similar to the following:

    {
      "lastTransitionTime": "2025-01-27T12:22:59Z",
      "message": "Certificate is issued",
      "observedGeneration": 1,
      "reason": "Issued",
      "status": "True",
      "type": "Ready"
    }
    
  4. Get the certificate secret name:

    kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificaterequest.pki.security.gdc.goog/CERT_REQ_NAME -ojson | jq -r '.spec.signedCertificateSecret'
    

    The output shows the SECRET_NAME containing the signed certificate:

    test-jwk-1
    

List certificate requests

Use the certificaterequests parameter to list all CertificateRequest resources:

   kubectl --kubeconfig MANAGEMENT_API_SERVER_KUBECONFIG -n USER_PROJECT_NAMESPACE get certificaterequests

The output looks similar to the following:

   NAMESPACE    NAME               READY   AGE
   foo          cert-req           True    30s