Authentication
The Upbound Official GCP Provider supports multiple authentication methods.
- Upbound auth (OIDC)
- Service account keys
- OAuth 2.0 access token
- Workload identity
for Google managed Kubernetes clusters (
GKE
) - Service account impersonation
Upbound auth (OIDC)
This method of authentication is only supported in 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
- Open the GCP IAM Admin console.
- Select Workload Identity Federation.
- If this is your first Workload Identity Federation configuration select Get Started
- At the top of the page, select Create Pool.
- Name the pool, like upbound-oidc-pool.
- Enter a description like An identity provider for Upbound.
- Enable the pool.
- 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:$@ORGANIZATION_NAME$@")
Not providing a CEL condition allows any 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.
- Open the GCP IAM Admin console.
- Select Service Accounts.
- 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 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.
- Return to the Workload Identity Federation page and select the upbound-oidc-pool.
- Near the top of the page select Grant Access.
- Select the new service account, upbound-service-account.
- 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.
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 toSecret.
Create a secretRef with the namespace, name and key of the secret.
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.
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.
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.
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.
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: $@<GCP_IAM_service_account_email>$@
spec:
serviceAccountName: $@<Kubernetes_service_account_name>$@
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.
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.
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: $@<Project_Name>$@
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.
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]"
For more information on the account requirements 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:
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.
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