Skip to content

Support GitHub App identities for state_token and release_token #97

@joshua-temple

Description

@joshua-temple

Summary

Let a manifest back a token reference (state_token, release_token) with a GitHub App identity, not just a static secret. The generator would mint a short-lived installation token at runtime and wire it into the steps that need it.

Background

state_token and release_token currently accept a static secret expression, e.g. state_token: ${{ secrets.CASCADE_STATE_TOKEN }} (added in #94, wired for the self-host in #96). A static secret works for a Personal Access Token, which is what the self-host uses today to write manifest state to the protected trunk.

A GitHub App is the better identity for this job, both for cascade's own pipeline and for anyone self-hosting cascade on a protected branch:

  • It is owned by an org or repo, not a person, so it does not break when an individual rotates a PAT or leaves.
  • Tokens are minted per run and expire in about an hour, so no long-lived push-capable secret sits on the trunk. Only the App private key is stored, and it can be rotated independently.
  • Commits and dispatches show as the App identity with a clear audit trail.
  • An App can be added to a repository ruleset bypass list directly, instead of relying on enforce_admins being off plus an admin-owned PAT.

The blocker is that an App token is not static: it is produced at runtime by exchanging the App ID and private key (for example via actions/create-github-app-token), and surfaces as a step output rather than a secret.

Proposed approach

  • Introduce a token-source abstraction so a token reference can be either a static secret (today's behavior) or an App source (app_id + private_key secrets). Additive and non-breaking; existing manifests keep working unchanged.
  • When a token source is an App, the generator emits a token-minting step before the consuming step and references the minted output.
  • Keep the existing real-GitHub vs gitea split: skip the minting step on the act/gitea e2e path, which has no GitHub App, and fall back to the current behavior there.
  • Apply uniformly to every token seam (state_token, release_token) so the policy is consistent.

Out of scope / operator setup

Creating the App, installing it, and adding it to a ruleset bypass list are one-time operator steps, documented but not automated.

Acceptance

  • A manifest can declare an App-backed token source for state_token and release_token.
  • Generated workflows mint the token and reference it; static-secret manifests are unchanged.
  • The act/gitea e2e path is unaffected.
  • Docs cover the App setup and the manifest configuration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions