From 8137b0d960f3ac8178b80dbfd430a8dd1de4f7f6 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:00:36 +0000 Subject: [PATCH 1/5] feat(cli): fall back to Application Default Credentials for secrets commands Co-Authored-By: AJ Steers --- airbyte_cdk/cli/airbyte_cdk/_secrets.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/airbyte_cdk/cli/airbyte_cdk/_secrets.py b/airbyte_cdk/cli/airbyte_cdk/_secrets.py index ef7f5d78f..c14d4f9a3 100644 --- a/airbyte_cdk/cli/airbyte_cdk/_secrets.py +++ b/airbyte_cdk/cli/airbyte_cdk/_secrets.py @@ -414,7 +414,14 @@ def _get_secret_filepath( def _get_gsm_secrets_client() -> "secretmanager.SecretManagerServiceClient": # type: ignore - """Get the Google Secret Manager client.""" + """Get the Google Secret Manager client. + + If the `GCP_GSM_CREDENTIALS` environment variable is set, the client will be + created using service account credentials from that JSON string. Otherwise, the + client will fall back to Application Default Credentials (ADC), which supports + user credentials from `gcloud auth application-default login`, GCE metadata + server credentials, and other standard GCP authentication methods. + """ if not secretmanager: raise ImportError( "google-cloud-secret-manager package is required for Secret Manager integration. " @@ -423,17 +430,17 @@ def _get_gsm_secrets_client() -> "secretmanager.SecretManagerServiceClient": # ) credentials_json = os.environ.get("GCP_GSM_CREDENTIALS") - if not credentials_json: - raise ValueError( - "No Google Cloud credentials found. " - "Please set the `GCP_GSM_CREDENTIALS` environment variable." + if credentials_json: + return cast( + "secretmanager.SecretManagerServiceClient", + secretmanager.SecretManagerServiceClient.from_service_account_info( + json.loads(credentials_json) + ), ) return cast( "secretmanager.SecretManagerServiceClient", - secretmanager.SecretManagerServiceClient.from_service_account_info( - json.loads(credentials_json) - ), + secretmanager.SecretManagerServiceClient(), ) From 22c36d4ffb3f3c0030a2b9682f13192ea69d6792 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:03:53 +0000 Subject: [PATCH 2/5] fix: remove redundant cast flagged by mypy Co-Authored-By: AJ Steers --- airbyte_cdk/cli/airbyte_cdk/_secrets.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/airbyte_cdk/cli/airbyte_cdk/_secrets.py b/airbyte_cdk/cli/airbyte_cdk/_secrets.py index c14d4f9a3..09b14622f 100644 --- a/airbyte_cdk/cli/airbyte_cdk/_secrets.py +++ b/airbyte_cdk/cli/airbyte_cdk/_secrets.py @@ -438,10 +438,7 @@ def _get_gsm_secrets_client() -> "secretmanager.SecretManagerServiceClient": # ), ) - return cast( - "secretmanager.SecretManagerServiceClient", - secretmanager.SecretManagerServiceClient(), - ) + return secretmanager.SecretManagerServiceClient() def _print_ci_secrets_masks( From bb88ac51751ea4f05c524e083e0f9036228dca20 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:05:16 +0000 Subject: [PATCH 3/5] fix: wrap ADC fallback with helpful error message on auth failure Co-Authored-By: AJ Steers --- airbyte_cdk/cli/airbyte_cdk/_secrets.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/airbyte_cdk/cli/airbyte_cdk/_secrets.py b/airbyte_cdk/cli/airbyte_cdk/_secrets.py index 09b14622f..57d13b846 100644 --- a/airbyte_cdk/cli/airbyte_cdk/_secrets.py +++ b/airbyte_cdk/cli/airbyte_cdk/_secrets.py @@ -36,6 +36,7 @@ from pathlib import Path from typing import Any, cast +import google.auth.exceptions import requests import rich_click as click import yaml @@ -438,7 +439,14 @@ def _get_gsm_secrets_client() -> "secretmanager.SecretManagerServiceClient": # ), ) - return secretmanager.SecretManagerServiceClient() + try: + return secretmanager.SecretManagerServiceClient() + except google.auth.exceptions.DefaultCredentialsError: + raise ValueError( + "No Google Cloud credentials found. " + "Either set the `GCP_GSM_CREDENTIALS` environment variable with service account JSON, " + "or run `gcloud auth application-default login` to authenticate with your user account." + ) from None def _print_ci_secrets_masks( From af7197b0e8180d62958d18a08f7be12a7f843497 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:10:13 +0000 Subject: [PATCH 4/5] fix: move google.auth.exceptions import into try/except block for graceful degradation Co-Authored-By: AJ Steers --- airbyte_cdk/cli/airbyte_cdk/_secrets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/airbyte_cdk/cli/airbyte_cdk/_secrets.py b/airbyte_cdk/cli/airbyte_cdk/_secrets.py index 57d13b846..9f8addd45 100644 --- a/airbyte_cdk/cli/airbyte_cdk/_secrets.py +++ b/airbyte_cdk/cli/airbyte_cdk/_secrets.py @@ -36,7 +36,6 @@ from pathlib import Path from typing import Any, cast -import google.auth.exceptions import requests import rich_click as click import yaml @@ -62,10 +61,12 @@ logger = logging.getLogger("airbyte-cdk.cli.secrets") try: + import google.auth.exceptions from google.cloud import secretmanager_v1 as secretmanager from google.cloud.secretmanager_v1 import Secret except ImportError: # If the package is not installed, we will raise an error in the CLI command. + google = None # type: ignore secretmanager = None # type: ignore Secret = None # type: ignore From 0742128243a666ad3664bac9856566420fb38371 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:20:32 +0000 Subject: [PATCH 5/5] feat: add stderr log messages indicating which GCP credentials path is used Co-Authored-By: AJ Steers --- airbyte_cdk/cli/airbyte_cdk/_secrets.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/airbyte_cdk/cli/airbyte_cdk/_secrets.py b/airbyte_cdk/cli/airbyte_cdk/_secrets.py index 9f8addd45..1b6249e20 100644 --- a/airbyte_cdk/cli/airbyte_cdk/_secrets.py +++ b/airbyte_cdk/cli/airbyte_cdk/_secrets.py @@ -433,6 +433,9 @@ def _get_gsm_secrets_client() -> "secretmanager.SecretManagerServiceClient": # credentials_json = os.environ.get("GCP_GSM_CREDENTIALS") if credentials_json: + click.echo( + "Using GCP service account credentials from GCP_GSM_CREDENTIALS env var.", err=True + ) return cast( "secretmanager.SecretManagerServiceClient", secretmanager.SecretManagerServiceClient.from_service_account_info( @@ -440,6 +443,9 @@ def _get_gsm_secrets_client() -> "secretmanager.SecretManagerServiceClient": # ), ) + click.echo( + "GCP_GSM_CREDENTIALS not set. Using Application Default Credentials (ADC).", err=True + ) try: return secretmanager.SecretManagerServiceClient() except google.auth.exceptions.DefaultCredentialsError: