Skip to content

Team Environments cannot push branches that add CI workflows: the App lacks the workflows permission #15

Closed

Description

@immakermatty

Problem

On a shared Team Environment every push goes through the broker as lazurio-for-github[bot]. GitHub refuses any push that creates or changes a file under .github/workflows/ unless the App has the workflows permission:

refusing to allow a GitHub App to create or update workflow .github/workflows/<file>.yml without workflows permission

The installation permissions today are actions: write, contents: write, pull_requests: write, checks: read and a few reads. workflows is missing.

Real case (2026-10-02)

On a Team Environment, an agent built a new module over 22 commits, including its CI workflow, as the module standard asks. The branch could never be pushed. The work existed only on that Environment's disk for days, until an Organization Admin pushed it with a personal account. Users experienced it as "it's saved" while nothing was on GitHub.

Proposal

  • Request workflows: write for the App. Re-approving the permission is needed per installation.
  • Update the policy installation_permissions contract so deploy.sh preflight matches.
  • Make the broker or the adapter report this refusal in plain words on the Environment, so an agent does not silently keep work local.

The Organization's branch rules still decide what reaches main.

Activity

  1. immakermatty commented on Oct 2, 2026

    @immakermatty
    ContributorAuthor

    Sequencing (checked against v0.8.0, 2026-10-02):

    • verifyPolicy runs before every mint (worker.mjs → verifiedGithub.mintToken) and compares the live installation permissions with policy.installation_permissions exactly (core.mjs:198). TOKEN_PERMISSIONS (core.mjs:9) also does not ask for workflows.
    • So the moment an Organization accepts an added App permission, its broker fails closed until a policy with the new permission is deployed. And without a code change the minted token still cannot push workflows.

    Safe order:

    1. App owner: add Repository permission Workflows: Read and write to the App. This only creates a pending request per installation, and nothing changes until it is accepted.
    2. Release: TOKEN_PERMISSIONS includes workflows: write, the installation-permission contract accepts it, and the mint check expects it.
    3. Per Organization, in one short window: accept the pending request in the Organization's installation settings, then immediately run deploy.sh with the new release and installation_permissions including workflows: write, then smoke every Workspace. Expected outage is about a minute for that Organization's Team Environments only.

    Note: the App already lists emails: read, which at least one installation never accepted. Accepting pending requests blindly would also break that broker.

  2. immakermatty commented on Oct 2, 2026

    @immakermatty
    ContributorAuthor

    Step 1 done (2026-10-02): the App owner added Repository permission Workflows: Read and write to Lazurio for GitHub. A before/after comparison of all 83 App permissions showed that only Workflows changed.

    Read-only check with an App JWT right after: none of the 15 installations has accepted it. Accepted permissions are unchanged, so every broker keeps minting. Every installation now has workflows: write and emails: read pending. Two installations (the founder's personal one and one holding) also have older pending scopes.

    Risk until step 2 ships: Organization owners get GitHub's "updated permissions" request. Accepting it before the broker redeploy makes that Organization's broker fail closed. Steps 2–3 stay as described above.

  3. immakermatty commented on Oct 2, 2026

    @immakermatty
    ContributorAuthor

    Resolved on 2026-10-02.

    • Release v0.9.0 (Workflows permission on demand and a Team probe that can see private repositories #16):
      • Tokens ask for workflows: write only when the Organization's reviewed policy declares it.
      • The Team probe now has metadata: read. Without it, the unreleased v2 Team gate refused 170 of 178 real private-repository grants.
    • Rollout to all three broker deployments, in two steps each:
      1. v0.9.0 with schema v2 and unchanged permissions, smoke green.
      2. A policy with workflows: write. The Owner accepted the pending request, and a watcher deployed the matching policy about 40 s after each acceptance. Smoke was green, and a broker token pushed and deleted a branch that changed a workflow file.
    • Lesson: emails: read is an account (user) permission. It never appears in an Organization installation's permissions, so it must not be declared in installation_permissions; otherwise the exact installation gate fails closed forever after acceptance.
    • Before / after: before acceptance, the same push from a Team Environment was refused with refusing to allow a GitHub App to create or update workflow … without workflows permission. Afterwards it succeeds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions