This document explains how to configure managed workload identities for Google Kubernetes Engine (GKE) in your GKE fleets-managed clusters. It also explains how to deploy a workload and verify the workload's identity and certificate.
Setting up and using managed workload identities for GKE involves the following steps:
Configure Certificate Authority Service to issue certificates for managed workload identities.
Authorize managed workload identities to request certificates from the CA pool.
Google-managed workload identity pool
When you add your clusters to GKE fleets, fleets automatically creates a Google-managed workload identity pool that serves as the root of your trust domain. The Google-managed workload identity pool has the following constraints:
Google fully manages the pool, so you cannot create any sub-resources, like namespaces, identities, or identity providers.
The pool can only be used for GKE workloads. You cannot add other types of workloads, like Compute Engine VMs, to the pool.
All clusters in the pool are subject to the standard Kubernetes namespace sameness model. This means that all clusters in the pool are equivalently privileged. Workloads that run on any of the clusters in the pool can use any identity that is in the pool.
Multi-project configuration
Google Cloud resources that you use in this document, such as
GKE clusters, the root CA, and subordinate CAs, can exist
in separate projects. When referring to these resources, use the --project
flag to specify the correct project for each resource.
Before you begin
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
Understand managed workload identities.
Ensure that you have created a GKE cluster.
Add your clusters to GKE fleets. If your cluster is an Autopilot cluster, omit
--enable-workload-identity
. Fleets automatically creates a Google-managed workload identity pool that serves as a trust domain.Enable GKE fleets by running the following command:
gcloud container clusters update CLUSTER_NAME \ --enable-workload-identity \ --enable-fleet \ --fleet-project=PROJECT_ID
Replace the following:
CLUSTER_NAME
: the name of the GKE cluster that you want to register with the GKE fleetPROJECT_ID
: the GKE fleet host project ID
Enable the IAM and Certificate Authority Service APIs:
gcloud services enable cloudresourcemanager.googleapis.com
iam.googleapis.com privateca.googleapis.com Configure the Google Cloud CLI to use the billing and quota project.
gcloud config set billing/quota_project PROJECT_ID
Replace PROJECT_ID with the ID of the fleet project.
Required roles
To get the permissions that you need to create managed workload identities and provision managed workload identity certificates, ask your administrator to grant you the following IAM roles on the project:
-
To create and configure managed workload identities:
IAM Workload Identity Pool Admin (
roles/iam.workloadIdentityPoolAdmin
) -
To create and configure CA pools:
CA Service Admin (
roles/privateca.admin
)
For more information about granting roles, see Manage access to projects, folders, and organizations.
You might also be able to get the required permissions through custom roles or other predefined roles.
Configure CA Service to issue certificates for managed workload identities
To configure managed workload identities for GKE, you first need to configure a certificate authority (CA) and one or more subordinate CAs. This configuration is known as a CA hierarchy.
You can use CA Service pools to set up this hierarchy. With this hierarchy, the subordinate CA pool issues the X.509 workload identity certificates to your workloads.
Configure your root CA pool
To create the root CA pool, do the following:
Create the root CA pool in the Enterprise tier using gcloud privateca pools create
.
This tier is meant for long-lived, low-volume certificate issuance.
gcloud privateca pools create ROOT_CA_POOL_ID \ --location=REGION \ --project=CA_PROJECT_ID \ --tier=enterprise
Replace the following:
ROOT_CA_POOL_ID
: a unique ID for the root CA pool. The ID can be up to 64 characters in length and must contain only lower and uppercase alphanumeric characters, underscores, or hyphens. The pool ID must be unique within the region.REGION
: the region where the root CA pool is located.CA_PROJECT_ID
: the project ID that you want to create the root CA in.
To learn more about CA pools, tiers, and regions, see Creating CA pools.
Configure your root CA
Create a root CA in the root CA pool using gcloud privateca roots create
.
You might be prompted to enable the root CA
if this is the only CA in the root CA Pool.
To create a root CA, run the following command:
gcloud privateca roots create ROOT_CA_ID \ --pool=ROOT_CA_POOL_ID \ --subject="CN=ROOT_CA_CN, O=ROOT_CA_ORGANIZATION" \ --key-algorithm="KEY_ALGORITHM" \ --max-chain-length=1 \ --location=REGION \ --project=CA_PROJECT_ID \ --auto-enable
Replace the following:
ROOT_CA_ID
: a unique name for the root CA. The CA name can be up to 64 characters in length and must contain only lower and uppercase alphanumeric characters, underscores, or hyphens. The CA name must be unique within the region.ROOT_CA_POOL_ID
: the ID of the root CA pool.ROOT_CA_CN
: the common name of the root CA.ROOT_CA_ORGANIZATION
: the organization of the root CA.KEY_ALGORITHM
: the key algorithm—for example,ec-p256-sha256
REGION
: the region where the root CA pool is located.CA_PROJECT_ID
: the project ID that you created the root CA in.
For more information about the subject
fields for the CA, see Subject.
Optionally, you create additional root CAs in your root CA pool. Doing so can be useful for root CA rotation.
Configure subordinate CAs
Optionally, you can configure subordinate CAs. Configuring subordinate CAs can help with the following:
Multiple certificate issuance scenarios: If you have multiple certificate issuance scenarios, then you can create a subordinate CA for each scenario.
Better load balancing: Adding multiple subordinate CAs in a CA pool helps you achieve better load balancing of certificate requests.
To create a subordinate CA pool and subordinate CA, do the following:
Create the subordinate CA pool in the DevOps tier, which is meant for high volume, short-lived certificate issuance.
gcloud privateca pools create SUBORDINATE_CA_POOL_ID \ --location=REGION \ --project=CA_PROJECT_ID \ --tier=devops
Replace the following:
SUBORDINATE_CA_POOL_ID
: a unique ID for the subordinate CA pool. The ID can be up to 64 characters in length and must contain only lowercase and uppercase alphanumeric characters, underscores, or hyphens. The pool ID must be unique within the region.REGION
: the region in which to create the subordinate CA pool.CA_PROJECT_ID
: the ID of the project that you created the subordinate CA in.
For more information, see Creating CA pools.
Create a subordinate CA in the subordinate CA pool. Don't change the default config-based issuance mode.
gcloud privateca subordinates create SUBORDINATE_CA_ID \ --pool=SUBORDINATE_CA_POOL_ID \ --location=REGION \ --issuer-pool=ROOT_CA_POOL_ID \ --issuer-location=REGION \ --subject="CN=SUBORDINATE_CA_CN, O=SUBORDINATE_CA_ORGANIZATION" \ --key-algorithm="KEY_ALGORITHM" \ --use-preset-profile=subordinate_mtls_pathlen_0 \ --project=CA_PROJECT_ID \ --auto-enable
Replace the following:
SUBORDINATE_CA_ID
: a unique name for the subordinate CA. The name can be up to 64 characters in length and must contain only lowercase and uppercase alphanumeric characters, underscores, or hyphens. The pool name must be unique within the region.SUBORDINATE_CA_POOL_ID
: the name of the subordinate CA pool.REGION
: the region where the subordinate CA pool is located.ROOT_CA_POOL_ID
: the ID of the root CA pool.REGION
: the region of the root CA pool.SUBORDINATE_CA_CN
: the common name of the subordinate CA.SUBORDINATE_CA_ORGANIZATION
: the name of the subordinate CA issuing organization.KEY_ALGORITHM
: the key algorithm—for example,ec-p256-sha256
CA_PROJECT_ID
: the ID of the project that you created the subordinate CA in.
For more information about the
subject
fields for the CA, see Subject.
Create a certificate issuance configuration file
To bind CAs to workload identity pools, they need to have a certificate issuance config. Optionally, if you need your workloads to authenticate across multiple trust domains, you can also update the pool with trust configuration configs.
To configure the certificate issuance config, you create a certificate issuance config file. The format of the file is similar to the following:
{ "inlineCertificateIssuanceConfig": { "caPools": { "REGION1": "projects/CA_PROJECT_NUMBER1/locations/REGION1/caPools/SUBORDINATE_CA_POOL_ID1", "REGION2": "projects/CA_PROJECT_NUMBER2/locations/REGION2/caPools/SUBORDINATE_CA_POOL_ID2" }, "lifetime": "DURATION", "rotationWindowPercentage": ROTATION_WINDOW_PERCENTAGE, "keyAlgorithm": "ALGORITHM" } }
Replace the following:
REGION
: The regions whether the CAs are located.CA_PROJECT_NUMBER
: The project number of the project that in which you created the subordinate CA pool. To get the project number from CA_PROJECT_ID project, run the following command:gcloud projects describe CA_PROJECT_ID --format="value(projectNumber)"
SUBORDINATE_CA_POOL_ID
: The name of the subordinate CA pool.ALGORITHM
: Optional. The encryption algorithm used to generate the private key. Valid values areECDSA_P256
(default),ECDSA_P384
,RSA_2048
,RSA_3072
,RSA_4096
.DURATION
: Optional. The leaf certificate validity duration, in seconds. The value must be between 86400 (1 day) and 2592000 (30 days). If not specified, the default value of 86400 (1 day) is used. The actually validity of the issued certificate also depends on the issuing CA, because it can restrict the lifetime of the issued certificate.ROTATION_WINDOW_PERCENTAGE
: Optional: The percentage of the certificate's lifetime at which a renewal triggers. The value must be between 50 and 80. The default is 50.
Create the trust configuration file
By default, your workloads within the same trust domain can mutually
authenticate using managed workload identities. If you want workloads that
are in different trust domains to mutually authenticate, then you need
to explicitly declare the trust relationship in the workload identity pool.
You do this by creating a trust config file
that contains an inlineTrustConfig
that provides certificates for each domain.
The trust config file contains a set of trust anchors that managed workload identity uses to validate peer certificates. The trust config file maps the SPIFFE trust domain to CA certificates.
To create the trust config file, do the following:
-
Download the certificates.
gcloud privateca pools get-ca-certs ROOT_CA_POOL_ID \ --output-file=CERTIFICATE_PATH \ --location=REGION
Replace the following:
-
ROOT_CA_POOL_ID
: the ID of the root CA pool -
CERTIFICATE_PATH
: the path to which to output the PEM-encoded certificate -
REGION
: the region of the root CA pool
-
-
Create a file called that contains your inline trust configuration, with PEM-formatted certificates. The file looks similar to the following:
{ "inlineTrustConfig": { "additionalTrustBundles": { "TRUST_DOMAIN_NAME1": { "trustAnchors": [ { "pemCertificate": "-----BEGIN CERTIFICATE-----\nCERTIFICATE_MATERIAL1\n-----END CERTIFICATE-----" }, { "pemCertificate": "-----BEGIN CERTIFICATE-----\nCERTIFICATE_MATERIAL2\n-----END CERTIFICATE-----" } ] }, "TRUSTED_DOMAIN_NAME2": { "trustAnchors": [ { "pemCertificate": "-----BEGIN CERTIFICATE-----\nCERTIFICATE_MATERIAL3\n-----END CERTIFICATE-----" }, { "pemCertificate": "-----BEGIN CERTIFICATE-----\nCERTIFICATE_MATERIAL4\n-----END CERTIFICATE-----" } ] } } } }
Replace the following:
-
TRUST_DOMAIN_NAME
: The trust domain name, formatted as follows:PROJECT_ID.svc.id.goog
-
CERTIFICATE_MATERIAL
: A set of PEM-formatted CA certificates trusted to issue certificates in the trust domain.
-
Bind the CAs to the workload identity pool
After you create your CA hierarchy and create certificate issuance configs for each CA, you bind the CAs to the workload identity pool. To bind a CA to the workload identity pool, you update the workload identity pool with the CA's certificate issuance config. Then, you can verify that the pool was updated.
Update the workload identity pool
To update the pool, run the following command:
gcloud iam workload-identity-pools update TRUST_DOMAIN_NAME \ --location="global" \ --inline-certificate-issuance-config-file=CIC_JSON_FILE_PATH \ --inline-trust-config-file=TC_JSON_FILE_PATH \ --project=PROJECT_ID
Replace the following:
TRUST_DOMAIN_NAME
: The name of the trust domain, formatted as follows:PROJECT_ID.svc.id.goog
CIC_JSON_FILE_PATH
: The path to the JSON-formatted certificate issuance config file (cic.json
) that you created earlier.TC_JSON_FILE_PATH
: Optional. The path to the JSON-formatted trust config file (tc.json
) that you created earlier. If your workloads authenticate across different trust domains, you must specify this file. Otherwise you can omit--inline-trust-config
.
Verify that the workload identity pool was updated
To verify that your workload identity pool was updated along with the certificate issuance config and trust config, run the following command:
gcloud iam workload-identity-pools describe TRUST_DOMAIN_NAME \ --location="global" \ --project=PROJECT_ID
Replace TRUST_DOMAIN_NAME
with the trust domain name
that you used to update the workload identity pool earlier
in this document.
The command output looks similar to the following:
inlineCertificateIssuanceConfig: caPools: REGION1: projects/PROJECT_NUMBER1/locations/REGION1/caPools/SUBORDINATE_CA_POOL_ID1, REGION2: projects/PROJECT_NUMBER2/locations/REGION2/caPools/SUBORDINATE_CA_POOL_ID2 keyAlgorithm: ALGORITHM lifetime: DURATION rotationWindowPercentage: ROTATION_WINDOW_PERCENTAGE inlineTrustConfig: additionalTrustBundles: example.com: trustAnchors: - pemCertificate: |- -----BEGIN CERTIFICATE----- CERTIFICATE_MATERIAL1 -----END CERTIFICATE----- - pemCertificate: |- -----BEGIN CERTIFICATE----- CERTIFICATE_MATERIAL2 -----END CERTIFICATE----- myorg.com: trustAnchors: - pemCertificate: |- -----BEGIN CERTIFICATE----- CERTIFICATE_MATERIAL3 -----END CERTIFICATE----- - pemCertificate: |- -----BEGIN CERTIFICATE----- CERTIFICATE_MATERIAL4 -----END CERTIFICATE----- name: PROJECT_ID.svc.id.goog state: ACTIVE
If inlineCertificateIssuanceConfig
or inlineTrustConfig
isn't present in the command output, verify that you've correctly configured
your gcloud CLI to use the correct project for billing and quota.
You might need to update to a newer version of the gcloud CLI.
Authorize managed workload identities to request certificates from the CA pool
After you bind the CAs to the workload identity pool, you need to authorize managed workload identities to request certificates from the CA pool. To authorize these identities, do the following:
Grant the CA Service Workload Certificate Requester (
roles/privateca.workloadCertificateRequester
) IAM role on each subordinate CA pool to the trust domain. The followinggcloud privateca pools add-iam-policy-binding
command authorizes the trust domain to request certificates from the CA Service certificate chains.gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_ID \ --location=REGION \ --role=roles/privateca.workloadCertificateRequester \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/name/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog" \ --project=CA_PROJECT_ID
Replace the following:
SUBORDINATE_CA_POOL_ID
: the ID for the subordinate CA pool.REGION
: the region of the subordinate CA pool.PROJECT_NUMBER
: the project number of the project that contains the GKE workload identity pool.To get
PROJECT_NUMBER
fromPROJECT_ID
, run the following command:gcloud projects describe PROJECT_ID --format="value(projectNumber)"
PROJECT_ID
: The project ID of the GKE fleet host project.CA_PROJECT_ID
: the ID of the project that you created the subordinate CA in.
Grant the CA Service Pool Reader (
roles/privateca.poolReader
) role on the subordinate CA pools to the managed workload identity. Doing so authorizes the managed workload identity to get the signed X.509 certificates from the CA's certificate chains.gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_ID \ --location=REGION \ --role=roles/privateca.poolReader \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/name/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog" \ --project=CA_PROJECT_ID
Replace the following:
SUBORDINATE_CA_POOL_ID
: the ID of the subordinate CA pool.REGION
: the region of the subordinate CA pool.PROJECT_NUMBER
: the project number of the project that contains the GKE workload identity pool.PROJECT_ID
: The project ID of the GKE fleet host project.CA_PROJECT_ID
: the ID of the project that you created the subordinate CA in.
Deploy workloads with managed workload identities
After you configure your CA pools to issue certificates for managed workload identities, you can deploy workloads that have managed workload identities.
This section shows you how to deploy a test workload that has a managed workload identity. To do this, you deploy a Pod, check that credentials were generated, and view the certificate and the SPIFFE ID.
Deploy a Pod
To deploy a test Pod in your cluster, do the following:
Get the cluster credentials.
gcloud container clusters get-credentials CLUSTER_NAME \ --location=CLUSTER_ZONE \ --project=CLUSTER_PROJECT_ID
Create the Kubernetes namespace.
kubectl create namespace KUBERNETES_NAMESPACE
Deploy a test PodSpec.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: namespace: KUBERNETES_NAMESPACE name: example-pod spec: containers: - name: main image: debian command: ['sleep', 'infinity'] volumeMounts: - name: fleet-spiffe-credentials mountPath: /var/run/secrets/workload-spiffe-credentials readOnly: true nodeSelector: iam.gke.io/gke-metadata-server-enabled: "true" volumes: - name: fleet-spiffe-credentials csi: driver: podcertificate.gke.io volumeAttributes: signerName: spiffe.gke.io/fleet-svid trustDomain: fleet-project/svc.id.goog EOF
List the workload credentials
To list the workload credentials, run the following command. It can take a few minutes to create the credentials.
kubectl exec -it example-pod -n KUBERNETES_NAMESPACE -- ls /var/run/secrets/workload-spiffe-credentials
You should see the following output:
ca_certificates.pem
certificates.pem
private_key.pem
trust_bundles.json
View the certificate
To view the certificate, do the following:
Export the certificate to a certificate file.
kubectl exec -it example-pod --namespace=KUBERNETES_NAMESPACE -- cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -noout -text > certfile
View the certificate file.
cat certfile
In the certificate, in the
X509v3 Subject Alternative Name
attribute, you see the SPIFFE ID, with the following format:spiffe://PROJECT_ID.svc.id.goog/ns/KUBERNETES_NAMESPACE/sa/default
default
refers to the default Kubernetes ServiceAccount.
Test workload-to-workload authentication
To test workload-to-workload authentication, see Test mTLS authentication using Go.
The sample code in the repository creates client and server workloads. You can test mutual authentication between the workloads using the certificates that you generated earlier in this document.
What's next
- Troubleshoot managed workload identity for GKE.
- Learn more about creating CA pools.
Try it for yourself
If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
Get started for free