|
| 1 | +# GitHub App Authentication |
| 2 | + |
| 3 | +Process-PSModule uses GitHub App installation tokens for GitHub API operations in the pipeline instead of `github.token`. |
| 4 | + |
| 5 | +## Secret contract at reusable workflow boundary |
| 6 | + |
| 7 | +The root reusable workflow (`workflow.yml`) requires two caller-provided secrets: |
| 8 | + |
| 9 | +- `GitHubAppClientId`: GitHub App Client ID (identifier, not a secret) |
| 10 | +- `GitHubAppPrivateKey`: GitHub App RSA private key (sensitive) |
| 11 | + |
| 12 | +Callers map their repository or organization secret names into this contract: |
| 13 | + |
| 14 | +```yaml |
| 15 | +secrets: |
| 16 | + GitHubAppClientId: ${{ secrets.PSMODULE_CLIENT_ID }} |
| 17 | + GitHubAppPrivateKey: ${{ secrets.PSMODULE_PRIVATE_KEY }} |
| 18 | +``` |
| 19 | +
|
| 20 | +## Token minting model |
| 21 | +
|
| 22 | +Each workflow that needs GitHub API access mints its own short-lived installation token with a pinned action: |
| 23 | +
|
| 24 | +```yaml |
| 25 | +- uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 |
| 26 | +``` |
| 27 | +
|
| 28 | +### Plan.yml (settings, version resolution, PR labels) |
| 29 | +
|
| 30 | +```yaml |
| 31 | +- uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 |
| 32 | + with: |
| 33 | + app-id: ${{ secrets.GitHubAppClientId }} |
| 34 | + private-key: ${{ secrets.GitHubAppPrivateKey }} |
| 35 | + repositories: ${{ github.event.repository.name }} |
| 36 | + permission-contents: read |
| 37 | + permission-pull-requests: write |
| 38 | +``` |
| 39 | +
|
| 40 | +### Publish-Module.yml (release creation, artifacts, PR comments, prerelease cleanup) |
| 41 | +
|
| 42 | +```yaml |
| 43 | +- uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 |
| 44 | + with: |
| 45 | + app-id: ${{ secrets.GitHubAppClientId }} |
| 46 | + private-key: ${{ secrets.GitHubAppPrivateKey }} |
| 47 | + repositories: ${{ github.event.repository.name }} |
| 48 | + permission-contents: write |
| 49 | + permission-pull-requests: write |
| 50 | +``` |
| 51 | +
|
| 52 | +### Build-Module.yml (repository metadata for module manifest) |
| 53 | +
|
| 54 | +```yaml |
| 55 | +- uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 |
| 56 | + with: |
| 57 | + app-id: ${{ secrets.GitHubAppClientId }} |
| 58 | + private-key: ${{ secrets.GitHubAppPrivateKey }} |
| 59 | + repositories: ${{ github.event.repository.name }} |
| 60 | + # no permission-* inputs required here |
| 61 | + # gh repo view relies on metadata: read (auto-granted to GitHub Apps) |
| 62 | +``` |
| 63 | + |
| 64 | +## Token injection pattern |
| 65 | + |
| 66 | +Inject the minted token as `GH_TOKEN` only on steps that call GitHub APIs (for example, `gh` CLI steps). Do not set it job-wide unless every step requires GitHub API access. |
| 67 | + |
| 68 | +## Why GitHub App tokens are used |
| 69 | + |
| 70 | +- identity is app-scoped, not tied to an individual user |
| 71 | +- pipeline automation can write where `github.token` is constrained in reusable-workflow fork scenarios |
| 72 | +- each token mint is repository-scoped and permission-scoped |
| 73 | +- effective permission ceiling is enforced at app installation level |
| 74 | + |
| 75 | +Required installation permissions for Process-PSModule use cases: |
| 76 | + |
| 77 | +- `contents: write` |
| 78 | +- `pull-requests: write` |
| 79 | +- `metadata: read` (auto-granted) |
| 80 | + |
| 81 | +## Permission model distinctions |
| 82 | + |
| 83 | +1. **Workflow `permissions:` block** controls only `github.token`; it does not change GitHub App installation tokens. |
| 84 | +2. **GitHub App installation permissions** are the hard ceiling for any token minted by that app. |
| 85 | +3. **`repositories:` input** scopes token reach. Default to `${{ github.event.repository.name }}` unless cross-repo access is intentionally required. |
| 86 | +4. **`permission-<scope>:` inputs** request a per-token subset of installation permissions; request only the minimum needed by that workflow. |
0 commit comments