Authentication

The Upbound Official GCP Provider supports multiple authentication methods.

Upbound auth (OIDC)

Note
This method of authentication is only supported in managed control planes running on Upbound Cloud Spaces

When your control plane runs in an Upbound Cloud Space, you can use this authentication method. Upbound authentication uses OpenID Connect (OIDC) to authenticate to GCP without requiring you to store credentials in Upbound.

Create an identity pool

  1. Open the GCP IAM Admin console.
  2. Select Workload Identity Federation.
  3. If this is your first Workload Identity Federation configuration select Get Started
  4. At the top of the page, select Create Pool.
  5. Name the pool, like upbound-oidc-pool.
  6. Enter a description like An identity provider for Upbound.
  7. Enable the pool.
  8. Select Continue

Add Upbound to the pool

Under the Add a provider to pool configuration under Select a provider use OpenID Connect (OIDC)

Provider Name: upbound-oidc-provider Provider ID: upbound-oidc-provider-id Issuer (URL): https://proidc.upbound.io

Select Allowed audiences For Audience 1 enter sts.googleapis.com

Select Continue.

Configure provider attributes

The provider attributes restrict which remote entities you allow access to your resources. When Upbound authenticates to GCP it provides an OIDC subject (sub) in the form:

mcp:<account>/<mcp-name>:provider:<provider-name>

Configure the google.subject attribute as assertion.sub

Under Attribute Conditions select Add Condition.

To authenticate any control plane in your organization, in the Conditional CEL input box put

google.subject.contains("mcp:")
Warning
Not providing a CEL condition allows any managed control plane to access your GCP account if they know the project ID and service account name.

Select Save.

Create a GCP Service Account

GCP requires Upbound to use a Service Account. The required GCP roles of the service account depend on the services managed by your control plane.

  1. Open the GCP IAM Admin console.
  2. Select Service Accounts.
  3. From the top of the page, select Create Service Account.

Service account details

Under Service account details enter Service account name: upbound-service-account Service account ID: upbound-service-account-id Description: Upbound control planes service account

Select Create and Continue.

Grant this service account access to project

For the CloudSQL as a service configuration the service account requires the roles: Cloud SQL Admin Workload Identity User

Select Done.

Record the service account email address

At the list of service accounts copy the service account email. Upbound requires this to authenticate your managed control plane.

Add the service account to the identity pool

Add the service account to the Workload Identity Federation pool to authenticate to Upbound with OIDC.

  1. Return to the Workload Identity Federation page and select the upbound-oidc-pool.
  2. Near the top of the page select Grant Access.
  3. Select the new service account, upbound-service-account.
  4. Under Select principals use All identities in the pool. Select Save. In the Configure your application window, select Dismiss.

Create a ProviderConfig

Create a ProviderConfig to set the provider authentication method to Upbound .

Supply the projectID , providerID , and serviceAccount found in the previous section.

Tip
To apply Upbound based authentication by default name the ProviderConfig default .
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  projectID: crossplane-playground
  credentials:
    source: Upbound
    upbound:
      federation:
        providerID: projects/<project-id>/locations/global/workloadIdentityPools/<identity-pool>/providers/<identity-provider>
        serviceAccount: <service-account-name>@<project-name>.iam.gserviceaccount.com

Service account keys

Using GCP service account keys requires storing the GCP account keys JSON file as a Kubernetes secret.

To create the Kubernetes secret create or download your GCP service account key JSON file.

Create a Kubernetes secret

Create the Kubernetes secret with kubectl create secret generic .

For example, name the secret
gcp-secret in the
crossplane-system namespace
and import the text file with the credentials gcp-credentials.json and assign them to the secret key my-gcp-secret .

kubectl create secret generic \
gcp-secret \
-n crossplane-system \
--from-file=my-gcp-secret=./gcp-credentials.json

To create a secret declaratively requires encoding the authentication keys as a base-64 string.

Create a Secret object with the data containing the secret key name, my-gcp-secret and the base-64 encoded keys.

apiVersion: v1
kind: Secret
metadata:
  name: gcp-secret
  namespace: crossplane-system
type: Opaque
data:
  my-gcp-secret: ewogICJ0eXBlIjogInNlcnZpY2VfYWNjb3VudCIsCiAgInByb2plY3RfaWQiOiAiZG9jcyIsCiAgInByaXZhdGVfa2V5X2lkIjogIjEyMzRhYmNkIiwKICAicHJpdmF0ZV9rZXkiOiAiLS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tXG5cbi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS1cbiIsCiAgImNsaWVudF9lbWFpbCI6ICJkb2NzQHVwYm91bmQuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLAogICJjbGllbnRfaWQiOiAiMTIzNDUiLAogICJhdXRoX3VyaSI6ICJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vby9vYXV0aDIvYXV0aCIsCiAgInRva2VuX3VyaSI6ICJodHRwczovL29hdXRoMi5nb29nbGVhcGlzLmNvbS90b2tlbiIsCiAgImF1dGhfcHJvdmlkZXJfeDUwOV9jZXJ0X3VybCI6ICJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9vYXV0aDIvdjEvY2VydHMiLAogICJjbGllbnRfeDUwOV9jZXJ0X3VybCI6ICJodHRwczovL3d3dy5nb29nbGVhcGlzLmNvbS9yb2JvdC92MS9tZXRhZGF0YS94NTA5L2RvY3MuaWFtLmdzZXJ2aWNlYWNjb3VudC5jb20iLAogICJ1bml2ZXJzZV9kb21haW4iOiAiZ29vZ2xlYXBpcy5jb20iCn0=

Create a ProviderConfig

Create a ProviderConfig to set the provider authentication method to Secret .

Create a secretRef with the namespace , name and key of the secret.

Tip
To apply key based authentication by default name the ProviderConfig default .
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: gcp-secret
      key: my-gcp-secret

To selectively apply key based authentication name the ProviderConfig and apply it when creating managed resources.

For example, creating an ProviderConfig named key-based-providerconfig .

apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: key-based-providerconfig
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: gcp-secret
      key: my-gcp-secret

Apply the ProviderConfig to a managed resource with a providerConfigRef .

apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
metadata:
  name: my-gcp-bucket
spec:
  forProvider:
    location: US
  providerConfigRef:
    name: key-based-providerconfig

OAuth access tokens

Using GCP access tokens requires storing the GCP account keys JSON file as a Kubernetes secret.

Create a GCP access token for a service account or with the gcloud CLI.

Warning

GCP access tokens are valid for 1 hour by default. When the token expires Crossplane can’t create or delete resources.

The provider-gcp GitHub repository contains an example cron job that automatically refreshes access tokens.

Create a Kubernetes secret

Create the Kubernetes secret with kubectl create secret generic .

For example, name the secret
gcp-secret in the
crossplane-system namespace
and import the text file with the credentials gcp-token.json and assign them to the secret key my-gcp-secret .

kubectl create secret generic \
gcp-secret \
-n crossplane-system \
--from-file=my-gcp-secret=./gcp-token.json

To create a secret declaratively requires encoding the access token as a base-64 string.

Create a Secret object with the data containing the secret key name, my-gcp-secret and the base-64 encoded token.

apiVersion: v1
kind: Secret
metadata:
  name: gcp-secret
  namespace: crossplane-system
type: Opaque
data:
  my-gcp-secret: eWEyOS5hMEFmQl9ieURVVEpSSWt3RDk1c1cxTGE0d3dlLS0xTHpOZkxJeFFYbnIza25VVG9jYV9xY2xsSG1ZUzVycjJwYmNzZnVuR3M5blR6SnVIb2lYb3VmRnBEbGZicGV5bTBJU1lfUmdxWGNCMTdDY3RXZWZOd2hJcVVUblJ2UVdmcHpsODVvbklzUXZaN0F5MEJjUy1ZMGxXYXJXODVJQ2Z5R0RhZEtvYUNnWUtBWXdTQVJFU0ZRSHN2WWxzUnU1Q0w4UVY0OThRc1pvbmxGVXJXQTAxNzE=

Create a ProviderConfig

Create a ProviderConfig to set the provider authentication method to AccessToken .

Create a secretRef with the namespace , name and key of the secret.

Tip
To apply key based authentication by default name the ProviderConfig default .
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: AccessToken
    secretRef:
      namespace: crossplane-system
      name: gcp-secret
      key: my-gcp-secret

To selectively apply key based authentication name the ProviderConfig and apply it when creating managed resources.

For example, creating an ProviderConfig named key-based-providerconfig .

apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: token-based-providerconfig
spec:
  credentials:
    source: AccessToken
    secretRef:
      namespace: crossplane-system
      name: gcp-secret
      key: my-gcp-secret

Apply the ProviderConfig to a managed resource with a providerConfigRef .

apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
metadata:
  name: my-gcp-bucket
spec:
  forProvider:
    location: US
  providerConfigRef:
    name: token-based-providerconfig

Workload identity

When running the GCP Provider in an Google managed Kubernetes cluster (GKE) the Provider may use workload identity for authentication.

Workload identity allows the Provider to authenticate to GCP APIs with permissions mapped to an IAM service account.

Important
Workload identity is only supported with Crossplane running in Google managed Kubernetes clusters (GKE).

Configuring workload identity with the GCP Provider requires:

  • a GCP service account
  • a Crossplane ControllerConfig to reference the GCP service account the Provider uses
  • a Crossplane ProviderConfig to apply the workload identity authentication method.

Configure the GCP service account

You may use an existing service account or follow the GCP documentation to create a new service account.

Apply a GCP IAM policy binding to associate the service account with the desired GCP IAM role.

Enable workload identity and link the GCP IAM service account to the Provider Kubernetes service account.

This requires defining a name for the Provider’s Kubernetes service account. The --member in the policy includes the Crossplane namespace and the name of the Provider’s Kubernetes service account.

Tip
Upbound UXP uses the upbound-system namespace.
Crossplane uses the crossplane-system namespace.
gcloud iam service-accounts add-iam-policy-binding \
  <Service_Account_Email_Address> \
--role  roles/iam.workloadIdentityUser    \
--member "serviceAccount:<Project_Name>.svc.id.goog[crossplane-system/<Kubernetes_Service_Account>]" \
--project <Project_Name>

For example with the following settings:

  • service account email docs@upbound.iam.gserviceaccount.com
  • project name upbound
  • namespace crossplane-system
  • Provider Kubernetes service account my-gcp-sa

Creates the following command:

gcloud iam service-accounts add-iam-policy-binding \
 docs@upbound.iam.gserviceaccount.com \
--role  roles/iam.workloadIdentityUser    \
--member "serviceAccount:upbound.svc.id.goog[crossplane-system/my-gcp-sa]" \
--project upbound

Create a ControllerConfig

The ControllerConfig creates a custom Provider service account and applies an annotation to the Provider’s pod.

Create a ControllerConfig object. Add an annotation mapping the key iam.gke.io/gcp-service-account to the email address of the GCP IAM service account.

Add a serviceAccountName to the spec to name the Provider’s service account. This must match the name used in the GCP IAM binding.

apiVersion: pkg.crossplane.io/v1alpha1
kind: ControllerConfig
metadata:
  name: my-controller-config
  annotations:    
    iam.gke.io/gcp-service-account: 
spec:
  serviceAccountName: 

For example, to create a ControllerConfig with the service account docs@upbound.iam.gserviceaccount.com and create a Provider service account named my-gcp-sa .

apiVersion: pkg.crossplane.io/v1alpha1
kind: ControllerConfig
metadata:
  name: my-controller-config
  annotations:    
    iam.gke.io/gcp-service-account: docs@upbound.iam.gserviceaccount.com
spec:
  serviceAccountName: my-gcp-sa

Apply the ControllerConfig

Apply the ControllerConfig to the GCP Provider with a controllerConfigRef referencing the name of the ControllerConfig.

For example, to apply a ControllerConfig named my-controller-config , reference the ControllerConfig name in the controllerConfigRef .

Tip
Apply the ControllerConfig to each family provider using workload identity.
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-gcp-storage
spec:
  package: xpkg.upbound.io/upbound/provider-gcp-storage:v0.35.0
  controllerConfigRef:
    name: my-controller-config

Create a ProviderConfig

Create a ProviderConfig to set the provider authentication method to InjectedIdentity and add the projectID to use.

Tip
To apply key based authentication by default name the ProviderConfig default .
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: InjectedIdentity
  projectID: 

To selectively apply key based authentication name the ProviderConfig and apply it when creating managed resources.

For example, creating an ProviderConfig named workload-id-providerconfig .

apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: workload-id-providerconfig
spec:
  credentials:
    source: InjectedIdentity
  projectID: upbound

Apply the ProviderConfig to a managed resource with a providerConfigRef .

apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
metadata:
  name: my-gcp-bucket
spec:
  forProvider:
    location: US
  providerConfigRef:
    name: workload-id-providerconfig

Service account impersonation

When running the GCP Provider in an Google managed Kubernetes cluster (GKE) the Provider may use service account impersonation for authentication.

Account impersonation allows the Provider to authenticate to GCP APIs with using one service account and request escalated privileges through a second account.

Important
Service account impersonation is only supported with Crossplane running in Google managed Kubernetes clusters (GKE).

Configuring workload identity with the GCP Provider requires:

  • a lower privileged GCP service account.
  • an elevated privileged GCP service account
  • a Crossplane ControllerConfig to reference the lower-privileged GCP service account.
  • a Crossplane ProviderConfig to reference the elevated privileged GCP service account.

Configure the GCP service accounts

You may use an existing service accounts or follow the GCP documentation to create a new service accounts.

The lower privilege role requires a GCP IAM policy binding role for the project which includes iam.serviceAccountTokenCreator .

gcloud projects add-iam-policy-binding <Project_Name> \
    --member "serviceAccount:<Lower_Privilege_Service_Account>@<Project_Name>.iam.gserviceaccount.com" \
    --role  roles/iam.serviceAccountTokenCreator \
    --project <Project_Name>

For example, to create a role-binding for:

  • project upbound
  • account docs-unprivileged
gcloud projects add-iam-policy-binding upbound \
    --member "serviceAccount:docs-unprivileged@upbound.iam.gserviceaccount.com" \
    --role  roles/iam.serviceAccountTokenCreator \
    --project upbound

The lower privileged service account requires a GCP IAM service account policy binding between the unprivileged account and the Kubernetes provider service account.

gcloud iam service-accounts add-iam-policy-binding <Lower_Privilege_Service_Account>@<Project_Name>.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:<Project_Name>.svc.id.goog[<Crossplane_Namespace>/<Kubernetes_Service_Account_Name>]"

For example, to create a policy binding for:

  • project upbound
  • account docs-unprivileged
  • namespace crossplane-system
  • Provider service account name gcp-provider-sa
gcloud iam service-accounts add-iam-policy-binding docs-unprivileged@upbound.iam.gserviceaccount.com \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:upbound.svc.id.goog[crossplane-system/gcp-provider-sa]"
Tip
For more information on the account requirements for for account impersonation read the GCP service account impersonation documentation

Create a ControllerConfig

The ControllerConfig creates a custom Provider service account and applies an annotation to the Provider’s pod.

Create a ControllerConfig object. Add an annotation mapping the key iam.gke.io/gcp-service-account to the email address of the GCP IAM service account.

Add a serviceAccountName to the spec to create the Provider’s service account. This must match the name used in the GCP IAM binding.

apiVersion: pkg.crossplane.io/v1alpha1
kind: ControllerConfig
metadata:
  name: my-controller-config
  annotations:    
    iam.gke.io/gcp-service-account: <Lower_Privilege_Service_Account>@<Project_Name>.iam.gserviceaccount.com
spec:
  serviceAccountName: <Kubernetes_service_account_name>

For example, to use a GCP service account named docs-unprivileged and a service account name gcp-provider-sa :

Important
The `serviceAccountName must match the service account referenced in the GCP IAM policy binding.
apiVersion: pkg.crossplane.io/v1alpha1
kind: ControllerConfig
metadata:
  name: my-controller-config
  annotations:    
    iam.gke.io/gcp-service-account: docs@upbound.iam.gserviceaccount.com
spec:
  serviceAccountName: my-gcp-sa

Create a ProviderConfig

Create a ProviderConfig to set the provider authentication method to ImpersonateServiceAccount . Add the impersonateServiceAccount object and provide the name of the privileged account to impersonate. Include the projectID to use.

Tip
To apply key based authentication by default name the ProviderConfig default .
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: ImpersonateServiceAccount
    impersonateServiceAccount:
      name: <Privileged_Service_Account>}@<Project_Name>.iam.gserviceaccount.com
  projectID: <Project_Name>

For example to create a ProviderConfig with:

  • service account named docs-privileged
  • project named upbound
apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: ImpersonateServiceAccount
    impersonateServiceAccount:
      name: docs-privileged@upbound.iam.gserviceaccount.com
  projectID: upbound

To selectively apply key based authentication name the ProviderConfig and apply it when creating managed resources.

For example, creating an ProviderConfig named workload-id-providerconfig .

apiVersion: gcp.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: impersonation-providerconfig
spec:
  credentials:
    source: ImpersonateServiceAccount
    impersonateServiceAccount:
      name: <Privileged_Service_Account>}@<Project_Name>.iam.gserviceaccount.com
  projectID: <Project_Name>

Apply the ProviderConfig to a managed resource with a providerConfigRef .

apiVersion: storage.gcp.upbound.io/v1beta1
kind: Bucket
metadata:
  name: my-gcp-bucket
spec:
  forProvider:
    location: US
  providerConfigRef:
    name: impersonation-providerconfig