Create GCP IAM Resources
This guide explains how to create Workload Identity Federation (WIF) resources for GCP hosted clusters using the hypershift create iam gcp command.
Prerequisites
- The
hypershiftCLI built from the repository gcloudCLI authenticated with IAM permissions in the hosted cluster GCP project- An RSA keypair for OIDC service account token signing
Generate RSA Keypair
The hosted cluster's OIDC provider requires an RSA keypair for signing service account tokens:
# Generate 4096-bit RSA key in PKCS#1 format
openssl genrsa -traditional -out sa-signer.key 4096
openssl rsa -in sa-signer.key -pubout -out sa-signer.pub
Create a JWKS file from the public key:
# Extract modulus and compute key ID
HEX_MODULUS=$(openssl rsa -in sa-signer.key -pubout -outform DER 2>/dev/null | \
openssl rsa -pubin -inform DER -text -noout 2>/dev/null | \
grep -A 100 "^Modulus:" | grep -v "^Modulus:" | grep -v "^Exponent:" | \
tr -d ' \n:' | sed 's/^00//')
MODULUS=$(printf '%b' "$(echo "$HEX_MODULUS" | sed 's/../\\x&/g')" | base64 -w0 | tr '+/' '-_' | tr -d '=')
KID=$(openssl rsa -in sa-signer.key -pubout -outform DER 2>/dev/null | \
openssl dgst -sha256 -binary | base64 -w0 | tr '+/' '-_' | tr -d '=')
cat > jwks.json << EOF
{
"keys": [
{
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"kid": "${KID}",
"n": "${MODULUS}",
"e": "AQAB"
}
]
}
EOF
Create IAM Resources
The hypershift create iam gcp command creates WIF resources in the hosted cluster project:
- Workload Identity Pool — Container for workload identity providers
- OIDC Provider — Links the hosted cluster's Kubernetes OIDC issuer to GCP IAM
- Service Accounts — GCP service accounts for hosted cluster components:
ctrlplane-op— Control Plane Operator (DNS admin, network admin, security admin, compute viewer). Theroles/compute.securityAdminrole lets CPO reconcile the worker firewall rule (<infra-id>-internal-cluster).nodepool— CAPG controller (compute instance admin, network admin)cloud-controller— Cloud Controller Manager (load balancer admin, security admin, compute viewer)storage— GCP PD CSI Driver (storage admin, instance admin, Tag User)image-registry— Image Registry Operator (storage admin, Tag User)cloud-network— Cloud Network Config Controller (instance admin, network user)
hypershift create iam gcp \
--infra-id=<infra-id> \
--project-id=<hosted-cluster-project-id> \
--oidc-jwks-file=jwks.json
Reserved prefix
The --infra-id value must not start with gcp- — GCP reserves this prefix for Workload Identity Pool IDs.
Flags
| Flag | Required | Description |
|---|---|---|
--infra-id |
Yes | Infrastructure ID (must match the value used for create infra gcp) |
--project-id |
Yes | GCP project ID where WIF resources will be created |
--oidc-jwks-file |
Yes | Path to JWKS JSON file containing the OIDC provider's public key |
--oidc-issuer-url |
No | Custom OIDC issuer URL (defaults to https://hypershift-<infra-id>-oidc) |
--output-file |
No | Path to save output JSON with WIF configuration |
Example
hypershift create iam gcp \
--infra-id=my-cluster \
--project-id=my-hc-project \
--oidc-jwks-file=jwks.json \
> iam-output.json
Output
The command outputs JSON with the WIF configuration:
{
"projectId": "my-hc-project",
"projectNumber": "123456789",
"infraId": "my-cluster",
"workloadIdentityPool": {
"poolId": "my-cluster-wi-pool",
"providerId": "my-cluster-k8s-provider"
},
"serviceAccounts": {
"ctrlplane-op": "my-cluster-ctrlplane-op@my-hc-project.iam.gserviceaccount.com",
"nodepool-mgmt": "my-cluster-nodepool-mgmt@my-hc-project.iam.gserviceaccount.com",
"cloud-controller": "my-cluster-cloud-controller@my-hc-project.iam.gserviceaccount.com",
"gcp-pd-csi": "my-cluster-gcp-pd-csi@my-hc-project.iam.gserviceaccount.com",
"image-registry": "my-cluster-image-registry@my-hc-project.iam.gserviceaccount.com",
"cloud-network": "my-cluster-cloud-network@my-hc-project.iam.gserviceaccount.com"
}
}
Save this output — you will need the project number, pool/provider IDs, and service account emails when creating the hosted cluster.
Resource tag permissions
When resourceTags is configured on a GCP HostedCluster, the guest GCP PD CSI
driver uses serviceAccountsEmails.storage to tag new persistent disks, and the
guest image registry operator uses serviceAccountsEmails.imageRegistry to tag
its bucket. hypershift create iam gcp grants both Google service accounts
roles/resourcemanager.tagUser on the hosted cluster project, in addition to
their storage roles. The Cloud Resource Manager API must also be enabled in the
project containing the resources to be tagged. See Google Cloud tag
requirements.
The IAM template is applied only when hypershift create iam gcp runs. If the
service accounts were created with an earlier version of the command, the
image-registry service account does not have Tag User. Re-run the command with
the same inputs, which adds missing role bindings to existing service accounts,
or have an administrator add the project-level role binding.
For an organization-defined TagValue, a project-level grant alone is not enough. An organization administrator must also grant Tag User on each configured TagValue to both service accounts. For example, repeat this command with the storage and image-registry GSA emails:
gcloud resource-manager tags values add-iam-policy-binding <org-id>/<key>/<value> \
--member="serviceAccount:<gsa-email>" \
--role="roles/resourcemanager.tagUser"
HyperShift does not create TagKeys, TagValues, or organization-level IAM bindings. See the gcloud TagValue IAM reference.
Destroy IAM Resources
To clean up WIF resources:
hypershift destroy iam gcp \
--infra-id=<infra-id> \
--project-id=<hosted-cluster-project-id>
Next Steps
- Create a GCP Hosted Cluster — Deploy your hosted cluster using the infrastructure and IAM resources