Skip to content

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

Description

@zoeyrose

Problem

Classic should receive reviewed pull requests when a new compatible content@1.x runtime is published. The organization and atrinik/classic currently default Actions workflows to read-only, and Actions cannot approve pull-request reviews. More importantly, branches or pull requests created with the repository's ordinary GITHUB_TOKEN must not be relied upon to trigger the normal pull-request validation chain.

A dedicated least-privilege automation identity is needed before the Classic updater can safely create a branch and pull request whose events run normal CI.

Required outcome

Provision and document a repository-scoped GitHub App identity that can create or update only Classic dependency-update branches and pull requests, without granting release, administration, organization, issue, package, or approval authority.

Desired App permissions and installation scope

  • Install only on atrinik/classic.
  • Repository metadata: read.
  • Repository contents: write.
  • Pull requests: write.
  • No Actions administration, checks writing, deployments, environments, issues, packages, secrets, organization administration, or pull-request approval permission.
  • Do not grant access to atrinik/content; its release metadata and assets are public read-only inputs.

If GitHub requires an additional permission, document the exact API operation requiring it and obtain separate review before expanding scope.

Implementation requirements

  • Create or select an organization-owned GitHub App with a named accountable owner and rotation/revocation runbook.
  • Store only the App ID and private-key secret in the atrinik/classic Actions configuration.
    • Suggested variable: DEPENDENCY_UPDATE_APP_ID.
    • Suggested secret: DEPENDENCY_UPDATE_APP_PRIVATE_KEY.
    • Never commit or print the key, installation token, or token-bearing API response.
  • Record the App installation, stable repository ID, permissions, consumers, secret/variable names, owner, verification date, and runbook in config/manual-settings.json.
  • If the Classic workflow uses actions/create-github-app-token, pin it to an immutable commit and update the organization selected-Actions policy and Atrinik supply-chain inventory as required.
  • Keep the organization default workflow permission read-only and can_approve_pull_request_reviews: false; this work must not weaken either control.
  • Verify using a disposable bot branch/PR that App-authored push and pull-request events invoke the normal Classic checks. Close the PR and remove the disposable branch after verification.
  • Document token lifetime, branch naming boundary, concurrency, duplicate-PR behavior, incident response, key rotation, and revocation.

Acceptance criteria

  • Live App installation is limited to repository ID 1327289971 (atrinik/classic).
  • Effective permissions are exactly the reviewed minimum.
  • Secret/variable name presence is verified without reading or logging their values.
  • A bot-authored test pull request triggers the existing Classic validation workflows and cannot approve or merge itself.
  • The App cannot publish releases, push tags, modify repository settings, or access other Atrinik repositories.
  • github-settings desired/manual state matches live installation metadata.
  • Any selected-Actions or supply-chain changes are validated and applied through their normal reviewed governance procedures.

Validation

  • bin/validate
  • bin/verify-manual-settings
  • relevant publisher tests
  • ShellCheck/actionlint if workflow code changes
  • bin/publish in plan mode, with the complete plan reviewed before any separately authorized apply
  • git diff --check

Rollback

Disable the updater workflow, revoke the App installation token/key, remove the App from atrinik/classic, and remove the repository secret/variable. Reconcile config/manual-settings.json and selected-Actions policy through a reviewed rollback; do not leave stale credential inventory claiming the App is active.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestgithub_actionsPull requests that update GitHub Actions codereleased

Fields

Priority

None yet

Start date

None yet

Target date

None yet

Effort

None yet

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions