Skip to content

feat(automation): govern Classic dependency updater identity - #65

Merged
zoeyrose merged 3 commits into
mainfrom
feat/classic-dependency-update-app
Aug 12, 2026
Merged

feat(automation): govern Classic dependency updater identity#65
zoeyrose merged 3 commits into
mainfrom
feat/classic-dependency-update-app

Conversation

@zoeyrose

@zoeyrose zoeyrose commented Aug 12, 2026

Copy link
Copy Markdown
Member

Summary

  • record the organization-owned Classic dependency updater App, installation, exact permissions, intended consumer, lifecycle ownership, and value-free Actions metadata names;
  • extend manual-settings validation and live verification to fail closed on App identity, permission, event, selection-mode, suspension, repository, pagination, secret-name, or variable-name drift;
  • document token lifetime, Classic-only owner verification, stable branch and one-PR boundaries, non-cancelling concurrency, duplicate handling, key rotation, incident response, revocation, and downstream functional proof.

Live state reconciled

  • App: atrinik-classic-dependency-updater (4564008)
  • Installation: 153045686, organization-owned, selected mode, unsuspended, no webhook events
  • Exact permissions: metadata read, contents write, pull requests write
  • Repository: only atrinik/classic (1327289971), confirmed through the organization-owner installation UI
  • Classic Actions metadata names: DEPENDENCY_UPDATE_APP_ID and DEPENDENCY_UPDATE_APP_PRIVATE_KEY
  • Organization defaults preserved: workflow permission read; Actions PR-review approval disabled

The GitHub permission model couples branch/ref/release operations under contents: write and PR mutation/review operations under pull requests: write. The runbook documents that limitation explicitly and makes every non-branch/PR operation a consumer-contract violation and incident instead of claiming the credential is technically release- or review-incapable.

Validation

  • bin/validate
  • shellcheck bin/* tests/*.sh
  • for test in tests/*.sh; do "${test}"; done
  • bin/verify-manual-settings against live metadata
  • bin/publish in plan mode only
  • git diff --check origin/main...HEAD

All passed at 96f037333b5c17814b3c5a7853d93742ab5a5906. The aggregate rerun includes the project-health and planning-health fixtures aligned to the App record's truthful August 11 verification date, plus a leap-day fixture that advances both governed credential lifecycles coherently. No publisher apply was run and no credential value was read or logged.

Ordered rollout

Part of #63 and atrinik/atrinik#356. This PR intentionally does not close #63. After human review and merge, atrinik/classic#169 owns the pinned consumer workflow and its root supply-chain inventory update. The issue remains open until a manually dispatched App-authored disposable PR triggers the ordinary Classic checks, cannot satisfy its own human approval or merge gate, and is safely closed with its branch removed.

@zoeyrose
zoeyrose merged commit 82b2f28 into main Aug 12, 2026
3 checks passed
@zoeyrose
zoeyrose deleted the feat/classic-dependency-update-app branch August 12, 2026 00:19
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.9.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(automation): provision a least-privilege Classic dependency update identity

1 participant