Skip to content

feat: add support for external_account credentials#146

Closed
AprilNEA wants to merge 3 commits intodjc:mainfrom
AprilNEA:main
Closed

feat: add support for external_account credentials#146
AprilNEA wants to merge 3 commits intodjc:mainfrom
AprilNEA:main

Conversation

@AprilNEA
Copy link

@AprilNEA AprilNEA commented Jan 12, 2026

Summary

This PR adds support for the external_account credential type, enabling authentication via GCP Workload Identity Federation from external identity providers such as GitHub Actions OIDC, AWS, Azure AD, and other OIDC/SAML providers.

Motivation

Currently, gcp_auth only supports:

  • service_account credentials
  • authorized_user credentials
  • GCE metadata server
  • gcloud CLI

When using GOOGLE_APPLICATION_CREDENTIALS with an external_account type credential file (generated by tools like google-github-actions/auth), the library fails with:

failed to deserialize ApplicationCredentials: missing field private_key

This is because the library assumes all credential files are service account keys.

External Account Flow

sequenceDiagram
      participant ST as Subject Token<br/>(OIDC JWT)
      participant STS as GCP STS API<br/>/v1/token
      participant FT as Federated Token
      participant IAM as IAM Credentials<br/>:generateAccessToken
      participant AT as Access Token<br/>(SA Impersonated)

      ST->>STS: Exchange token
      STS->>FT: Return federated token

      alt Service Account Impersonation configured
          FT->>IAM: Request impersonation
          IAM->>AT: Return access token
      end
Loading

Related

… Federation)

This adds support for the `external_account` credential type, which is used
by GCP Workload Identity Federation to authenticate from external identity
providers such as GitHub Actions OIDC, AWS, Azure, etc.

Changes:
- Add `ExternalAccountCredentials` type in types.rs
- Add `CredentialFile` enum to auto-detect credential types from
  GOOGLE_APPLICATION_CREDENTIALS
- Add `ExternalAccount` provider that implements TokenProvider
- Update `provider()` to handle all three credential types:
  - service_account (existing)
  - authorized_user (existing)
  - external_account (new)

The external_account flow:
1. Read subject token from credential_source (file or URL)
2. Exchange it with GCP STS for a federated access token
3. Optionally impersonate a service account if configured

This enables gcp_auth to work with GitHub Actions OIDC authentication
without requiring service account keys.
@djc
Copy link
Owner

djc commented Jan 12, 2026

Both the PR description and the code seems to be obviously LLM-generated. At the very least, edit your PR description down to a concise (that is, human) description of what you're trying to achieve and if/how this is supported by official Google SDKs. There's a lot of new code which, from a quick look, suffers from the typical verboseness exhibited by LLMs as well -- which means I don't want to maintain it.

@AprilNEA
Copy link
Author

Both the PR description and the code seems to be obviously LLM-generated. At the very least, edit your PR description down to a concise (that is, human) description of what you're trying to achieve and if/how this is supported by official Google SDKs. There's a lot of new code which, from a quick look, suffers from the typical verboseness exhibited by LLMs as well -- which means I don't want to maintain it.

I am very sorry about this. But I did indeed carefully edit the description, and I believe that the parts retained are necessary for this PR.
For this code, I have already used it in internal business. If there is a possibility of simplification, I will continue to maintain it.
You can choose to close this PR. I will wait until the code is sufficiently streamlined and robust before submitting a PR at an appropriate time.

Thank you for your time.

- Remove unused ExternalAccountCredentials::from_file method
- Fix potential race condition in token caching by adding double-check
  after acquiring write lock
- Simplify CustomServiceAccount::token by removing duplicate code
- Remove unnecessary token_url.clone() in ExternalAccount
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants