Skip to content

Build Not yet confirmed elsewhere1 publisher 2 min read Published

One personal GitHub OAuth token carried 276 Terraform Enterprise workspaces until it was revoked

One revoked personal OAuth token stopped runs across 276 Terraform Enterprise workspaces, according to a dev.to write-up. Nobody was paged and the team needed two days to notice, so it moved the workspaces onto a GitHub App owned by the org.

The Engineer · Build desk

How we use AI Send a correction

Illustration accompanying One personal GitHub OAuth token carried 276 Terraform Enterprise workspaces until it was revoked
Generated illustration
Post blames a token limit; the fix is an org App The token limit the dev.to post blames, then the time to set up the org-level GitHub App in TFE and the calls to move workspaces onto it.

Key figures: an OAuth app can hold at most 10 tokens per user, which the dev.to post gives as the most likely reason the token was revoked. Setting up the org-level GitHub App in TFE took about 15 minutes. Moving 276 workspaces takes at least 276 PATCH calls, one per workspace.

Post blames a token limit; the fix is an org App
FigureValueNoteClaim
Tokens an OAuth app can hold per user, at most10 tokenspost's likeliest cause of the revocation18
GitHub App setup in TFE, about15 minutes9
PATCH calls to move 276 workspaces, at least276 callsone per workspace16

What happened

  • The error 'Repository doesn't exist or isn't accessible' read like a single-repo permissions problem, though the credential was dead for every repo.
  • Re-authorising the OAuth connection restored runs straight away, with the same token ID and the same webhooks.
  • The team eliminated rate limiting, repo permissions and SSO de-authorisation as causes, along with the possibility that the app was shared with the old instance.
  • The org-level GitHub App took about 15 minutes to set up in TFE, with read access to contents and metadata and write access to commit statuses.

Why it matters

  • exposure If the 10-token theory holds, re-authorising during a migration can revoke the connection production is using. Any TFE org that routes all its workspaces through one personal OAuth connection carries that risk.
  • cost Creating the App is cheap. The bill is the migration: at least 276 PATCH calls, one per workspace, with no partial-update shortcut.
  • decision Any team with auto-apply workspaces has to choose, workspace by workspace, whether an unreviewed apply of the branch head is acceptable at cutover.

A 200 on every webhook meant nothing looked wrong from GitHub's side [4]. The failure came in the next step, when TFE tried to download the code [4]. TFE has no alert for "I can't read GitHub", the post says [7]. An empty run list passes for a quiet afternoon [7].

The root cause is an inference. The team could not prove why GitHub revoked the token [17]. Its best explanation is a GitHub limit of 10 tokens per user for an OAuth app: each Reauthorize click creates a new token, and past 10 the oldest is silently revoked [18]. Migrations produce those clicks, on the old instance, on the new one, during testing, and again when the first attempt looks stuck [19]. The post gets to the limit by elimination [20]. For it to be right, the production token had to be the oldest of more than ten. In our view the remedy holds either way, because it takes the personal account out of the path [10].

Re-authorising was a stopgap, since it would break again the next time anyone clicked the button [8]. Creating the App was the short part [9]. Moving the workspaces was the bigger job [11], and the post counts about 275 workspaces before the fix and 276 in the move [3][11]. Each one takes a PATCH to its vcs-repo block that sets github-app-installation-id in place of the OAuth token ID [12]. The PATCH wants the whole block. Send less and the workspace loses its branch, submodule setting and tag regex [12].

The script's guard is the sound engineering here. Changing a workspace's VCS connection queues a run, and with auto-apply on, that run applies whatever is on the branch, unreviewed [13]. So the script skips auto-apply workspaces unless an allow flag is passed, and it has a dry-run mode [13]. It also skips workspaces with no VCS block and ones already switched, so a second pass leaves finished workspaces alone [13]. The CSV report records each old OAuth token ID, and --revert-from report.csv rolls workspaces back [14]. The team backed up every workspace's vcs-repo block before touching anything [14].

The migration has a personal-account step of its own. The API token has to come from a user who has authorised the GitHub App in TFE themselves [15]. If not, TFE throws the identical "Repository doesn't exist or isn't accessible" error, for a different cause [15]. The post does not describe adding an alert for a dead VCS credential.

What to watch

  • Confirmation from GitHub, or from token audit data, that a 10-token revocation hit the production token. Until then the cause is an inference by elimination.
  • Whether the team adds a zero-runs or failed-clone alert, since TFE has none built in for losing GitHub access, per the post.
  • How many auto-apply workspaces the script skipped, and how the team switched them.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence55
Adoption
Insufficient
Hype gap−10
Incentives
Insufficient
Confidence50
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    After the Terraform Enterprise cutover to EKS, two days later every pipeline in the organisation stopped producing runs at the same moment, and nobody got paged.

    Reported Supported Source: dev.to postView cited source
  2. [2]

    The whole platform reached GitHub through a single OAuth token belonging to a single personal account, and GitHub had quietly revoked it.

    Reported Supported Source: dev.to postView cited source
  3. [3]

    On paper the organisation had about 275 workspaces with dozens of owning teams, but in practice they all went through one token.

    Reported SupportedView cited source

Get this ledger inside ChatGPT. Ask about any of our stories and the answer brings its figure, each claim’s verdict and the sources. Free, no account.

Add to ChatGPTAdd to Claude

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · October 13, 2026

    One Personal Token Was Holding Up 276 Terraform Workspaces

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Topics

Loading related stories