Skip to content

Host the breakglass merge workflow - #18

Merged
ulziibay-kernel merged 1 commit into
mainfrom
hypeship/host-breakglass-merge
Aug 24, 2026
Merged

Host the breakglass merge workflow#18
ulziibay-kernel merged 1 commit into
mainfrom
hypeship/host-breakglass-merge

Conversation

@ulziibay-kernel

@ulziibay-kernelulziibay-kernel commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Moves breakglass-merge.yml here from kernel/infra.

Why it has to move

kernel/infra is 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 in infra would have looked installed and silently done nothing. During an incident that's the worst failure mode available: someone types /breakglass and 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.yml are both called from infra), 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_call secrets 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/infra except 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-workflows and 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, a workflow_call reusable workflow that org repos invoke when someone comments /breakglass <reason> on a PR. It replaces hosting in private kernel/infra so 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, not secrets: 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.

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>

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 1c84dd3. Configure here.

rebase) allowed="$(echo "$repo_info" | jq -r .allow_rebase_merge)" ;;
esac
[ "$allowed" = "true" ] && break
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 1c84dd3. Configure here.

@ulziibay-kernel
ulziibay-kernel merged commit c39b889 into mainAug 24, 2026
1 check passed
ulziibay-kernel added a commit to kernel/cli that referenced this pull request Aug 24, 2026
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>
ulziibay-kernel added a commit to kernel/kernel-images that referenced this pull request Aug 24, 2026
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>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@ulziibay-kernel