{
  "id": 19797844,
  "title": "One Stolen Token Should Not Ship Your App: A Two-Person Release Gate in GitHub Actions",
  "url": "https://urgent.news/2026/11/13/one-stolen-token-should-not-ship-your-app-a-two-person-release-gate",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-11-13T11:24:47.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/wamzii/one-stolen-token-should-not-ship-your-app-a-two-person-release-gate-in-github-actions-330c"
  },
  "original_language": "en",
  "account": "A stolen access token was used by an attacker to push harmful code into every repository of the organization, compromising sensitive secrets. The incident led to the creation of a two-person release gate in GitHub Actions, which ensures that a merge is not the same as a release. This gate requires a merge request from one person and approval from a different, named person before the app can be released to users. The design includes three workflows: Request, Approve, and Publish. The Request workflow builds nothing and merely writes a JSON file into a release-requests/ folder on a new branch, then opens a pull request into a dedicated release-gate branch. The Approve workflow checks certain conditions before approving the release, and the Publish workflow is the only one that interacts with signing keys and store credentials. The request must be authored by the bot to prevent self-approval, and the hard-coded approver list ensures that only authorized individuals can release the app. Four bugs were discovered through testing, including issues with finding the reusable workflow, permissions, file selection, and handling failed publishes. These measures make it difficult for attackers to exploit the system and ensure that code is properly reviewed and approved before being released to the public.",
  "summary": "One Stolen Token Should Not Ship Your App An attacker got hold of one admin's access token. Within minutes they had pushed a workflow file into every repository in the organisation, each one tailored to that repo, each one written to read the repo's secrets and send them out. We contained it. Tokens revoked, secrets rotated, signatures enforced. I've written about that part separately. This post…",
  "key_points": [
    "Two-person release gate prevents single-point release",
    "Request workflow builds nothing, writes JSON file",
    "Approve workflow checks conditions before release"
  ],
  "editors_take": "Separating the merge process from the release workflow prevents a single compromised credential from automatically deploying malicious code by requiring mandatory human oversight through a multi-step approval gate.",
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}