From 1bd09be1e44b3806d0cc7abda7baaae8fc037e13 Mon Sep 17 00:00:00 2001 From: Raghunandan Balachandran Date: Thu, 7 Aug 2025 10:29:32 +0200 Subject: [PATCH] Add a googleServiceAccountCredentials json config. Uses the credentials if present else fallback to default application credentials Signed-off-by: Raghunandan Balachandran --- plugins/kubernetes-backend/config.d.ts | 7 +++ .../src/auth/GoogleServiceAccountStrategy.ts | 55 ++++++++++++++++++- .../src/service/KubernetesBuilder.ts | 2 +- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/plugins/kubernetes-backend/config.d.ts b/plugins/kubernetes-backend/config.d.ts index a710b8cb85..74b2f57a31 100644 --- a/plugins/kubernetes-backend/config.d.ts +++ b/plugins/kubernetes-backend/config.d.ts @@ -98,6 +98,13 @@ export interface Config { plural: string; }>; + /** + * (Optional) Google Service Account credentials for authentication + * JSON string containing the service account key + * @visibility secret + */ + googleServiceAccountCredentials?: string; + /** * (Optional) API Version Overrides * If set, the specified api version will be used to make requests for the corresponding object. diff --git a/plugins/kubernetes-backend/src/auth/GoogleServiceAccountStrategy.ts b/plugins/kubernetes-backend/src/auth/GoogleServiceAccountStrategy.ts index f6757d6a64..4dce97ea29 100644 --- a/plugins/kubernetes-backend/src/auth/GoogleServiceAccountStrategy.ts +++ b/plugins/kubernetes-backend/src/auth/GoogleServiceAccountStrategy.ts @@ -20,19 +20,70 @@ import { KubernetesCredential, } from '@backstage/plugin-kubernetes-node'; import * as container from '@google-cloud/container'; +import { Config } from '@backstage/config'; /** + * GoogleServiceAccountStrategy provides authentication using Google Service Account credentials. + * + * Credentials can be provided via configuration: + * ```yaml + * kubernetes: + * googleServiceAccountCredentials: | + * { + * "type": "service_account", + * "project_id": "your-project-id", + * "private_key_id": "key-id", + * "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n", + * "client_email": "your-service-account@your-project.iam.gserviceaccount.com", + * "client_id": "client-id", + * "auth_uri": "https://accounts.google.com/o/oauth2/auth", + * "token_uri": "https://oauth2.googleapis.com/token", + * "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", + * "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..." + * } + * ``` + * + * If no credentials are provided in config, falls back to GOOGLE_APPLICATION_CREDENTIALS or ADC. * * @public */ export class GoogleServiceAccountStrategy implements AuthenticationStrategy { + private readonly credentials?: string; + + constructor(config: Config) { + this.credentials = config.getOptionalString( + 'kubernetes.googleServiceAccountCredentials', + ); + } public async getCredential(): Promise { - const client = new container.v1.ClusterManagerClient(); + let client: container.v1.ClusterManagerClient; + + if (this.credentials) { + // Use credentials from config + try { + const credentialsObject = JSON.parse(this.credentials); + + client = new container.v1.ClusterManagerClient({ + credentials: credentialsObject, + scopes: ['https://www.googleapis.com/auth/cloud-platform'], + }); + } catch (error) { + throw new Error( + `Failed to parse Google Service Account credentials from config: ${ + error instanceof Error ? error.message : 'Invalid JSON' + }`, + ); + } + } else { + // Fall back to Application Default Credentials or GOOGLE_APPLICATION_CREDENTIALS + client = new container.v1.ClusterManagerClient(); + } + const token = await client.auth.getAccessToken(); if (!token) { throw new Error( - 'Unable to obtain access token for the current Google Application Default Credentials', + 'Unable to obtain access token for Google Cloud authentication. Check your credentials configuration.', ); } return { type: 'bearer token', token }; diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index f86dd6cebb..9f87514eb4 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -462,7 +462,7 @@ export class KubernetesBuilder { aws: new AwsIamStrategy({ config: this.env.config }), azure: new AzureIdentityStrategy(this.env.logger), google: new GoogleStrategy(), - googleServiceAccount: new GoogleServiceAccountStrategy(), + googleServiceAccount: new GoogleServiceAccountStrategy(this.env.config), localKubectlProxy: new AnonymousStrategy(), oidc: new OidcStrategy(), serviceAccount: new ServiceAccountStrategy(),