GITHUB_TOKEN stopped working


Have there been any changes in permissions for GITHUB_TOKEN in the last month of so?
In my setup GitHub Actions would trigger Jenkins job and we pass GITHUB_TOKEN as a argument so that we could update deployment status from the Jenkins job. It was working fine for several months, but stopped working exactly 28 days ago. Is it so, that GITHUB_TOKEN cannot be used from external services?


The installation access token expires after 60 minutes. GitHub fetches a token for each job, before the job begins.
Note: When a workflow run or its jobs are queued for more than one hour, the token may expire before the job starts.

It might be the case that you’re hitting this limit. Are you seeing any error messages in the annotations?

No, the job starts right away, runs for about 5 minutes max and I get error:

  "message": "Bad credentials",
  "documentation_url": ""

It used to be working reliably for several months without any modifications I know of.

And by the job in this case I mean Jenkins job, now GitHub Actions job. GitHub Actions job might also take 5 minutes to run, but it’s usually started right away - at last I have never seen it being queued for a long time.

Would you mind sharing the workflow yml file here? Have you tried using personal access token (PAT) ? Could PAT work?
Which API do you use to update deployment status? Is that this one?

I’m already in contact with GitHub support and I also created a reproducer in my personal account:

Essentially the problem seem to be that token expires as soon as workflow finishes. There are two workflows - one terminates immediately and the other one sleeps for 90 seconds.

Yeah, you are right. GitHub automatically creates a GITHUB_TOKEN secret to use in your workflow. It only could be used during the workflow run execution. Once the workflow run finished, token will become invalid.

Unfortunately this is not documented and it was working 30 days ago and then changed suddenly.

@inikolaev In your reproducer repo, are the two workflows with or without sleep 90s both get the Bad credentials issue?

The workflows never fail. The request which uses token outside workflow fails. The token issued by workflow which doesn’t sleep expires immediately, so it cannot be reused, while the token issue by sleeping workflow can still be used for as long as workflow is sleeping.

What I’m trying to say that this was not the case before - it was possible to use token within the 60 minutes after it has been issued even after the workflow, which issued the token, has terminated.

This behavior is not documented, at least I could not find any references to it.

We made a change to enable jobs to run for more than 60 minutes and still use the token. The initial token is good for 60 minutes and the system automatically renews it if your job runs for more than 60 minutes. Upon completion of the job the token is invalidated.

1 Like

My use case is that I’m using a token in a 3rd party application to update deployment status. That process runs when workflow is already terminated, so token is no longer valid.

This use case was working previously for several months.

After the GITHUB_TOKEN expire time changes, I will recommend you use PAT in Jenkins job to update deployment status or sleep the GitHub Actions workflow as a work around.

The document for GITHUB_TOKEN has updated : Before each job begins, GitHub fetches an installation access token for the job. The token expires when the job is finished.

Is PAT always bound to a user? What happens if user leaves the organization in this case?

Yes, PAT is for an account. I would encourage you creating a “machine user”, add it to the organization and give it enough permission, generate a PAT from its account with appropriate scope .