Uh oh!
There was an error while loading. Please reload this page.
Host the breakglass merge workflow - #18
Conversation
Moved from kernel/infra, which is private -- and a public repository cannot call a reusable workflow stored in a private one. The run is created and then fails with no job, no log and nothing on the pull request, which is close to undiagnosable if you do not know the rule. Four of the twelve repos that require an approval are public: hypeman, cli, kernel-images and kernel-mcp-server. Installing the caller there while the mechanism lived in infra would have looked installed and silently done nothing, which during an incident is the worst possible failure. Hosting it here, next to semgrep and vuln-remediation, is what lets one identical caller work in all twelve. Nothing here is secret. The app id and private key arrive as named inputs from the caller, and the logic is visible in run logs on any public repo regardless. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1c84dd3. Configure here.
| # also the only functional difference between the configuration that provably | ||
| # merged a PR past an approval rule and every configuration since, which has been | ||
| # refused. Until that is understood, the token stays owner-wide. Narrowing it again | ||
| # needs a test that shows the merge still works. |
There was a problem hiding this comment.
Token minted before auth checks
Medium Severity
The owner-wide app token is minted before command validation or the OWNER/MEMBER gate. On public repos anyone can comment, and the caller's prefix if: also matches non-commands like /breakglass-anything, so untrusted comments still cause the private key to be used and an installation token to be created. The script itself notes the association check needs no app permission, so that work can happen first.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 1c84dd3. Configure here.
| rebase) allowed="$(echo "$repo_info" | jq -r .allow_rebase_merge)" ;; | ||
| esac | ||
| [ "$allowed" = "true" ] && break | ||
| done |
There was a problem hiding this comment.
Merge with no allowed method
Low Severity
The merge-method loop picks the first allowed of squash/merge/rebase, but if none are enabled it still falls through with method set to rebase and attempts the merge. That is the same blind 405 the surrounding comment says this logic exists to avoid during an incident.
Reviewed by Cursor Bugbot for commit 1c84dd3. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Nineteen lines, no logic — the whole per-repo install for breakglass. Comment `/breakglass <reason>` on a PR here and it merges without its required approval, recording the reason on the PR. The mechanism lives in [kernel/security-workflows](kernel/security-workflows#18) and is shared, so changes to it need no PR here. **This repo is public**, which is why the mechanism is hosted in a public repo — a public repository cannot call a reusable workflow stored in a private one, and the failure is silent (run created, zero jobs, nothing on the PR). Why a file per repo: `issue_comment` fires in the repo where the comment is left, and GitHub only runs a workflow if the file is on *that* repo's default branch. Reusable workflows share logic, not triggers. Docs: [kernel/infra docs/breakglass.md](https://github.com/kernel/infra/blob/main/docs/breakglass.md) Depends on kernel/security-workflows#18 landing first. Requires the org-level `BREAKGLASS_APP_ID` / `BREAKGLASS_APP_PRIVATE_KEY` secrets shared with this repo, and the `kernel-breakglass` app installed on it. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces an approval-bypass merge path tied to org breakglass app credentials; impact is limited by the thin caller and narrowly scoped secrets, but misuse or misconfiguration could merge PRs without normal review gates. > > **Overview** > Adds a minimal **Breakglass** GitHub Actions workflow so reviewers can comment `/breakglass <reason>` on a PR to merge without required approvals, with the reason recorded on the PR. > > The new `.github/workflows/breakglass.yml` only wires the trigger: it runs on `issue_comment` when the comment is on a PR and starts with `/breakglass`, then calls the shared reusable workflow `kernel/security-workflows/.github/workflows/breakglass-merge.yml@main`. Workflow-level `permissions` are empty, and only `BREAKGLASS_APP_ID` and `BREAKGLASS_APP_PRIVATE_KEY` are passed (not `secrets: inherit`) so the external workflow does not receive this repo’s other secrets. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3f88d13. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: ulziibay-kernel <253135130+ulziibay-kernel@users.noreply.github.com>
Nineteen lines, no logic — the whole per-repo install for breakglass. Comment `/breakglass <reason>` on a PR here and it merges without its required approval, recording the reason on the PR. The mechanism lives in [kernel/security-workflows](kernel/security-workflows#18) and is shared, so changes to it need no PR here. **This repo is public**, which is why the mechanism is hosted in a public repo — a public repository cannot call a reusable workflow stored in a private one, and the failure is silent (run created, zero jobs, nothing on the PR). Why a file per repo: `issue_comment` fires in the repo where the comment is left, and GitHub only runs a workflow if the file is on *that* repo's default branch. Reusable workflows share logic, not triggers. Docs: [kernel/infra docs/breakglass.md](https://github.com/kernel/infra/blob/main/docs/breakglass.md) Depends on kernel/security-workflows#18 landing first. Requires the org-level `BREAKGLASS_APP_ID` / `BREAKGLASS_APP_PRIVATE_KEY` secrets shared with this repo, and the `kernel-breakglass` app installed on it. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Introduces an approval-bypass merge path gated by org secrets and a GitHub App; misconfiguration or compromised breakglass credentials could allow unauthorized merges. > > **Overview** > Adds a thin **Breakglass** GitHub Actions workflow so reviewers can comment `/breakglass <reason>` on a PR to merge without required approvals; the reason is recorded on the PR. > > The workflow listens for `issue_comment` on pull requests, runs with **no default permissions**, and delegates all behavior to the shared reusable workflow `kernel/security-workflows/.github/workflows/breakglass-merge.yml@main`. Only `BREAKGLASS_APP_ID` and `BREAKGLASS_APP_PRIVATE_KEY` are passed explicitly—**not** `secrets: inherit`—so the external workflow cannot access this repo’s other secrets. > > This is the full per-repo install; repo-specific logic is intentionally avoided here. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a347489. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: ulziibay-kernel <253135130+ulziibay-kernel@users.noreply.github.com>


Moves
breakglass-merge.ymlhere fromkernel/infra.Why it has to move
kernel/infrais private, and a public repository cannot call a reusable workflow stored in a private one. The run gets created and then fails with zero jobs, no log, and nothing posted to the PR.Four of the twelve repos with a required approval are public —
hypeman,cli,kernel-images,kernel-mcp-server. Installing the caller there while the mechanism lived ininfrawould have looked installed and silently done nothing. During an incident that's the worst failure mode available: someone types/breakglassand gets silence.Found the hard way during testing — the end-to-end test passed while the test repo was private and started producing zero-job failures the moment it went public.
This repo is public and already hosts shared workflows this way (
semgrep.yml,vuln-remediation.ymlare both called frominfra), so one identical caller now works in all twelve repos, and the untested internal→private case disappears too.Is it safe to be public?
Yes. The app ID and private key arrive as named
workflow_callsecrets from the caller — nothing is embedded. And the logic is already visible in run logs on any public repo that uses it, so publishing the source reveals nothing new. Security here rests on the gates and the app's narrow permissions, not on the file being unreadable.What's in it
Unchanged from
kernel/infraexcept an added header comment explaining why it lives here. Full context: kernel/infra docs/breakglass.md.Merging this needs to land before the caller PRs that point at it — I'll repoint those to
kernel/security-workflowsand open the four public ones once this is in.Note
High Risk
Introduces org-wide emergency merge bypass of required approvals with authorization checks and GitHub App credentials; a misconfiguration or logic bug could allow unreviewed merges into protected branches.
Overview
Adds
.github/workflows/breakglass-merge.yml, aworkflow_callreusable workflow that org repos invoke when someone comments/breakglass <reason>on a PR. It replaces hosting in privatekernel/infraso public repos can actually run it (GitHub blocks calling reusable workflows in private repos from public callers).The workflow mints a pinned GitHub App token from caller-supplied
BREAKGLASS_APP_ID/BREAKGLASS_APP_PRIVATE_KEY(explicit secrets, notsecrets: inherit), then merges the PR past required approval while enforcing gates: org OWNER/MEMBER requester (silent deny otherwise), open PR, same-repo head (no fork merges), org-member PR author, and a ≥10 character reason. It posts an audit comment before merge, picks an allowed merge method, merges with a pinned head SHA, writes a step summary, and on member-visible failures posts a refusal comment (non-members get no PR reply).Reviewed by Cursor Bugbot for commit 1c84dd3. Bugbot is set up for automated code reviews on this repo. Configure here.