feat(gke): support IAM credentials via Application Default Credentials#6610
feat(gke): support IAM credentials via Application Default Credentials#6610aditya-786 wants to merge 3 commits into
Conversation
shahargl
left a comment
There was a problem hiding this comment.
Nice feature — removing the service-account-JSON requirement for GKE Workload Identity users is a real friction win, and extracting build_gke_credentials into a small, well-tested helper is clean. A few things I'd like addressed before merge.
Blocking
1. Silent ADC fallback on malformed JSON (gke_provider.py, __init__)
When service_account_json is provided but json.loads fails, the except block now sets self._service_account_data = None but no longer resets self._project_id. As a result, a user who supplies a malformed SA JSON (and no explicit project_id) will silently fall back to Application Default Credentials instead of getting an error. Previously both were cleared together, so this is a behavior change that can mask a real misconfiguration — the user thinks they're authenticating with their SA, but they're actually using the node's identity.
Please at least log a warning so the fallback is observable, e.g.:
except Exception:
self.logger.warning(
"Invalid service_account_json provided, falling back to Application Default Credentials"
)
self._service_account_data = NoneImportant
2. No test for the changed __init__ credential-selection branch
The helper has good coverage (JSON path, ADC fallback, explicit project_id override, SA project resolution), but the riskiest change in this PR is the provider's __init__ logic — and it's currently untested. Please add a test that covers the malformed-JSON → ADC fallback behavior, since that's where the actual behavior change lives.
3. DefaultCredentialsError not handled with a clear message
google.auth.default() raises google.auth.exceptions.DefaultCredentialsError when neither a SA JSON nor ADC is available (common when running locally without gcloud auth). It propagates raw out of build_gke_credentials. In validate_scopes it gets stringified per-scope; in __generate_client it's wrapped generically. A clearer message ("No service account JSON provided and no Application Default Credentials found") would make this much easier to diagnose. A test for this path would be good too.
Nits
build_gke_credentialshas no type hints — since the file is new, considerservice_account_data: dict | None = None, project_id: str | None = Noneand a return annotation.- In
validate_scopes, theproject_idresolution check runs aftercredentials.refresh(). You could move it before the refresh to fail faster, since refreshing ADC isn't needed to know the project is missing.
Happy to approve once the silent-fallback warning + a test for the __init__ branch are in.
|
Thanks for the careful review. All addressed in the latest push.
Nits: added type hints to both helpers, and moved the All 10 tests pass with |
93b8add to
34c9140
Compare
What
Makes the GKE provider usable without uploading a service account JSON. When
service_account_jsonis left empty, the provider authenticates with Application Default Credentials (for example a GKE Workload Identity service account) throughgoogle.auth.default(). When a JSON is supplied the behavior is unchanged.service_account_jsonis now optional and a new optionalproject_idfield was added. The project is resolved fromproject_id, then the service account JSON, then the Application Default Credentials.Credential selection is centralized in a small helper (
build_gke_credentials) used by bothvalidate_scopesand the Kubernetes client builder.Why
Closes #3721. Workloads running in GKE usually have an IAM service account attached via Workload Identity, so requiring a generated JSON key is unnecessary friction and an extra long-lived secret to manage.
Testing
tests/test_gke_credentials.pycovers credential selection: the JSON path, the ADC fallback when no JSON is given, an explicitproject_idoverride, and project resolution from the JSON. The helper has no app dependencies, so it runs in isolation:The provider docs snippet was regenerated;
python scripts/docs_render_provider_snippets.py --validatepasses.