Issue with Google Drive API Authentication using GitHub Actions
I created my workload identity pool according to the Google GitHub Actions Auth documentation without any service account. Then I tried to connect to Google Drive, which requires an OAuth 2.0 access token. I used the following configuration:
- name: Authenticate with Google Cloud
uses: 'google-github-actions/auth@v2'
with:
project_id: 'my-project'
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
- name: Upload files to Google Drive
uses: 'Burak-Atak/drive-upload@master'
with:
google_credentials_file_path: ${{ env.GOOGLE_APPLICATION_CREDENTIALS }}
files_to_create: "app.spec"
drive_folder_id: "242fgdfg345345"
files_to_update: "requirements.txt"
file_ids_to_update: "asdas3534fdgg"
However, I got the following error with below code:
def authenticate_google(self):
credentials, project_id = load_credentials_from_file(
os.environ["GOOGLE_APPLICATION_CREDENTIALS"],
scopes=[
'https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.metadata'
]
)
return build("drive", "v3", credentials=credentials)
googleapiclient.errors.HttpError: <HttpError 401 when requesting https://www.googleapis.com/upload/drive/v3/files?fields=id&alt=json&uploadType=multipart returned "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.". Details: "[{'message': 'Invalid Credentials', 'domain': 'global', 'reason': 'authError', 'location': 'Authorization', 'locationType': 'header'}]">
I realized I should use OAuth 2.0 for the Google Drive API. Then I changed my configuration to this:
- name: Authenticate with Google Cloud
uses: google-github-actions/auth@v2
with:
workload_identity_provider: 'projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider'
project_id: '<PROJECT_ID>'
service_account: '<PROJECT_ID>@<PROJECT_ID>.iam.gserviceaccount.com'
token_format: 'access_token'
access_token_lifetime: '60s'
access_token_scopes: 'https://www.googleapis.com/auth/drive.file,https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/drive.metadata'
- name: Upload files to Google Drive
uses: 'Burak-Atak/drive-upload@master'
with:
google_credentials_file_path: ${{ env.GOOGLE_APPLICATION_CREDENTIALS }}
files_to_create: "app.spec"
drive_folder_id: "242fgdfg345345"
files_to_update: "requirements.txt"
file_ids_to_update: "asdas3534fdgg"
After this change, I started to get the following error even though I have the Service Account Token Creator and Owner roles in my service account:
google-github-actions/auth failed with: failed to generate Google Cloud OAuth 2.0 Access Token for <PROJECT_ID>@<PROJECT_ID>.iam.gserviceaccount.com: {
"error": {
"code": 403,
"message": "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).",
"status": "PERMISSION_DENIED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "IAM_PERMISSION_DENIED",
"domain": "iam.googleapis.com",
"metadata": {
"permission": "iam.serviceAccounts.getAccessToken"
}
}
]
}
}
Solution
I figured out that I should add a service account to my workload pool. Check the "Connected service accounts" part in the Google Cloud Console. If there is no connected service account, you should add one.

Using GitHub Actions to authenticate to Google Workload Identity Federation for credentials to use in a Python script - Stack Overflow
Use Github workflow to deploy to cloud run with workload identity provider without a service account
google cloud platform - GCP workload identity federation - Github provider - 'Unable to acquire impersonated credentials' - Stack Overflow
How to set up Workload Identity Federation to securely authorize Github Actions workflows to manage Google Cloud resources
Videos
In addition to the OP's own answer of the service account not being connected (bound) at all, this can result from the service account binding being constrained using attribute mappings.
In the default setup for GitHub Actions discussed here on the google blog for WIF, the provider is set up with a set of attribute mappings:
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository"
Those attributes can be used to restrict access when you connect (bind) the service account... in the following, the member uses the repository attribute to constrain it so that only actions executing in my-org/my-repo on GitHub will be permitted.
gcloud iam service-accounts add-iam-policy-binding "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/attribute.repository/my-org/my-repo"
A cross-repository provider
Of course, you want to use strong restrictions here. Restricting to a repository, or even a particular branch (so only main branch actions have privilege to deploy to production, for example). No restrictions allows anything, which is absolutely not what you want!!!
In my case, I set up my WIF provider, then tried to reuse it from another repository, resulting in the error experienced by the OP.
I chose to add the repository_owner attribute mapping from the list of all possible attributes that are in GitHub's OIDC token (the attribute mappings are editable in the google cloud console), then bind my service account to that rather than the repository-specific principal:
--attribute-mapping="google.subject=assertion.sub,attribute.repository_owner=assertion.repository_owner"
and
gcloud iam service-accounts add-iam-policy-binding "my-service-account@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/my-pool/attribute.repository_owner/my-org"
Bingo, it works a charm now.
Take care to think about your attack surface though, loosening this constraint too widely creates real vulnerability.
So I later found out what this was. Despite running:
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
--role=roles/iam.workloadIdentityUser \
--member="MEMBER_EXPRESSION"
As per the docs, it had not granted permission - I went into the console and checked the workload identity pool under "connected service accounts" menu (to the left) and the service account wasn't in there, so I added it manually.
Traditional solution to authorizing CI/CD workflows to modify cloud environments is by using service accounts.
In 2021, GitHub introduced support for OpenID Connect (OIDC) to enable secure cloud deployments using short-lived tokens. It leverages security mechanisms of cloud providers to ensure GitHub Actions workflows get very narrow access to cloud resources. Plus, there's no need for storing any long-lived secrets like service account keys in GitHub.
GItHub's support for OIDC made it compatible with the Google Cloud's mechanism called Workload Identity Federation.
With Workload Identity Federation, Identity and Access Management (IAM) can be used to grant external identities (like GitHub repositories/users/branches) IAM roles, and thus direct access to Google cloud resources.
If you’d like to learn more about this topic, I’ve set up the connection between GitHub Actions and Google cloud platform using precisely workload identity federation.
Read more about it here and let me know what you think: https://www.toolongautomated.com/posts/2025/one-branch-to-rule-them-all-4.html#authorize-github-actions-workflows