Skip to content

Unblock governance seeding (Phases 10–12): create GitHub App + wire GOVERNANCE_APP_ID / GOVERNANCE_APP_PRIVATE_KEY #20

Description

@cryptoxdog

Unblock governance seeding (Phases 10–12): create GitHub App and wire GOVERNANCE_APP_ID / GOVERNANCE_APP_PRIVATE_KEY

What

seed-governance.yml (merged to main in #18, l9-github-defaults v3.1.0) cannot run. It authenticates as a GitHub App via actions/create-github-app-token, but neither credential exists anywhere on the repo or environment:

# .github/workflows/seed-governance.yml (lines 32, 39-40)
environment: governance-distribution   # add required reviewers here
app-id: ${{ vars.GOVERNANCE_APP_ID }}
private-key: ${{ secrets.GOVERNANCE_APP_PRIVATE_KEY }}

Verified state at time of filing (2026-07-29):

Item State
governance-distribution environment EXISTS (created during v2.0.1 integration)
Environment variables / secrets NONE
Repo variables / secrets NONE
Environment required reviewers NONE
Everything else in the v3.1.0 playbook DONE (tags v3.1.0+v1, evaluate rulesets 19936069/19936070, secret-scanning alerts, labels, weekly posture report → #19)

Why

Seeding is the distribution arm of the governance pack: it opens PRs on consuming repos with the pinned @v1 caller, CODEOWNERS.repo, and dependabot.yml. Current fleet coverage (posture report #19, 30 active repos): CODEOWNERS 30 percent, governance caller 3 percent, dependabot 53 percent. Until credentials exist, coverage cannot move.

A GitHub App (not a PAT) is required by design: scoped installation, short-lived tokens, revocable independently of any user account, and the seed workflow's approval gate (governance-distribution environment) assumes App auth.

Fix — steps for the executing agent (human confirmation needed at App creation)

  1. Create an org GitHub App at https://github.com/organizations/Quantum-L9/settings/apps/new
    • Name: l9-governance-seeder (or similar)
    • Permissions (minimum): Repository → Contents: Read and write, Pull requests: Read and write, Metadata: Read-only, Administration: Read-only
    • Webhook: deactivate (not needed)
    • Where: this account only
  2. Generate a private key (App settings → Private keys → Generate) — downloads a .pem
  3. Install the App on the org: all repositories (or at minimum the repos to be seeded plus .github)
  4. Store credentials on the governance-distribution environment of Quantum-L9/.github:
    gh api -X POST repos/Quantum-L9/.github/environments/governance-distribution/variables \
      -f name=GOVERNANCE_APP_ID -f value=<APP_ID>
    gh secret set GOVERNANCE_APP_PRIVATE_KEY \
      --repo Quantum-L9/.github --env governance-distribution < app-private-key.pem
    Note: vars.GOVERNANCE_APP_ID / secrets.GOVERNANCE_APP_PRIVATE_KEY resolve from the environment because the seeding job declares environment: governance-distribution. Repo-level storage also works but environment-level is preferred (keeps credentials behind the approval gate).
  5. Add a required reviewer to the environment (Settings → Environments → governance-distribution) so every seeding run pauses for human approval — this is the pack's intended control point.
  6. Dry-run first (playbook Phase 11):
    gh workflow run seed-governance.yml --repo Quantum-L9/.github --ref main -f dry_run=true
    Inspect the run summary: it must list target repos and intended files WITHOUT opening PRs.
  7. Live seed (Phase 12) only after dry-run output is reviewed:
    gh workflow run seed-governance.yml --repo Quantum-L9/.github --ref main -f dry_run=false
    Expected: one PR per target repo (advisory — merging them is each repo owner's call).

Acceptance criteria

  • gh api repos/Quantum-L9/.github/environments/governance-distribution/variables shows GOVERNANCE_APP_ID
  • gh api repos/Quantum-L9/.github/environments/governance-distribution/secrets shows GOVERNANCE_APP_PRIVATE_KEY
  • Environment has at least one required reviewer
  • Dry-run seed completes green with a target list in the job summary
  • Live seed opens caller/CODEOWNERS/dependabot PRs on target repos
  • Next weekly posture report (Governance posture (advisory, weekly) #19 successor) shows caller coverage above 3 percent

Context / references

Priority

priority:P1 / scope:M — sole remaining blocker of the v3.1.0 rollout; all other playbook phases are complete.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:ciCI/CD pipelinespriority:P1This sprintscope:MA few days, one repotype:taskKnown work, known solution

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions