Skip to content

Commit 497420b

Browse files
docs: define caller credential baseline
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent e65b2d4 commit 497420b

3 files changed

Lines changed: 59 additions & 8 deletions

File tree

docs/content/reference/process-workflow-fleet-standard.md

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ decisions before canonical guides, templates, or consumer workflows adopt it:
137137
| Concurrency | Use the PR-number-or-ref key and cancel only superseded pull-request runs. | Use separate groups per event class or disable cancellation for all runs. |
138138
| Permissions | Set top-level permissions to empty and grant only `contents: read`, `pages: write`, and `id-token: write` to the caller job. | Define a narrower profile for repositories that do not publish Pages. |
139139
| Fork behavior | Invoke the reusable workflow unconditionally; Plan classifies normal fork `pull_request` events into restricted read-only validation and rejects `pull_request_target` until separately designed. | Omit fork validation or design a separate `pull_request_target` trust boundary. |
140-
| Credentials | Explicitly map the three v8 credentials. | Define a narrower credential profile for repositories that cannot publish. |
140+
| Credentials | Explicitly map `PSGALLERY_API_KEY`, `GitHubAppClientId`, and `GitHubAppPrivateKey`; `secrets: inherit` is nonconforming. | Define a narrower profile only for repositories with an approved non-publication contract. |
141141
| Optional surface | Permit only documented `TestData`, workflow inputs, schedule timing, and presentation metadata. | Allow additional extension points after naming and compatibility rules are agreed. |
142142

143143
The `v8` reference is the controlled moving major tag for this PSModule-owned workflow. On 2026-08-15, `v8`, `v8.0`,
@@ -173,7 +173,7 @@ fleet campaign. Branch names, `latest`, floating minor tags, and unqualified tar
173173
| Permissions | Use empty top-level permissions and the three caller-job permissions shown above. | Repository-local reads and Pages/OIDC stay narrow; App tokens provide broader authority. |
174174
| Fork authorization | Leave the caller job unconditional. | Plan grants normal fork `pull_request` events only restricted read-only validation capabilities and rejects `pull_request_target` before credentials or repository-defined code run. |
175175
| Reference | Use the intended internal floating major tag (`v8`) after tag governance is enforced. | Compatible owned releases roll out centrally; breaking releases require a new major and campaign. |
176-
| Credentials | Explicitly map the three required secrets. | Satisfies the `v7+` contract and prevents unrelated secret inheritance. |
176+
| Credentials | Explicitly map `PSGALLERY_API_KEY`, `GitHubAppClientId`, and `GitHubAppPrivateKey`; do not use `secrets: inherit`. | Satisfies the `v7+` contract and prevents unrelated secret inheritance. |
177177
| Scope | Keep the caller as a single delegation job. | Repository-specific automation remains independently understandable and maintainable. |
178178

179179
## Candidate optional elements
@@ -182,20 +182,20 @@ These are evidence-based candidate variations, not approved policy.
182182

183183
| Option | When it is appropriate | Constraint |
184184
| --- | --- | --- |
185-
| `TestData` secret | Module-local tests need caller-defined secrets or variables. | Use the documented compact single-line JSON object and expose only required values. |
185+
| `TestData` secret mapping | Module-local tests need caller-defined secrets or variables. | Map `TestData: ${{ secrets.TestData }}` only when used. Its value is a JSON object with separate `secrets` and `variables` maps; omit the mapping when unused. |
186186
| `with.SettingsPath` | The settings file is not `.github/PSModule.yml`. | Prefer the standard path for normal module repositories. |
187187
| `with.WorkingDirectory` | The module is intentionally rooted below the repository root. | Keep the default `.` for the standard layout. |
188188
| `with.ImportantFilePatterns` | A caller must override change detection at the workflow boundary. | Prefer stable configuration in `.github/PSModule.yml`; the supplied list replaces all defaults. |
189-
| `with.Debug`, `Verbose`, `Version`, or `Prerelease` | A deliberate diagnostic or dependency-selection scenario needs it. | Do not hard-code temporary diagnostics into the fleet baseline. |
189+
| `with.Verbose`, `Version`, or `Prerelease` | A deliberate diagnostic or dependency-selection scenario needs it. | Do not hard-code temporary diagnostics into the fleet baseline. |
190190
| Schedule time | Health runs need staggering or a repository-specific maintenance window. | Keep at least one documented schedule unless the repository records why health runs are unnecessary. |
191191
| `run-name` | A repository needs clearer run presentation. | Presentation must not change job names or routing behavior. |
192192

193193
## Variations requiring a decision
194194

195-
The following differ from the candidate. They are inventory classifications, not policy violations, until #514 records
196-
an approved structure:
195+
The following are nonconforming with locked candidate decisions. They remain inventory classifications rather than
196+
approved organization policy until #514 records an approved structure:
197197

198-
- `secrets: inherit`;
198+
- `secrets: inherit`, which is nonconforming because the candidate requires the three explicit baseline mappings;
199199
- `APIKey` or `APIKEY` mappings from the pre-`v7` contract;
200200
- any Process-PSModule reference other than the intended major tag (`v8`), including a branch, `latest`, minor tag,
201201
exact patch tag, or full commit SHA;
@@ -204,6 +204,22 @@ an approved structure:
204204
- trigger-level path filters that bypass Process-PSModule important-file evaluation;
205205
- unrelated additional jobs in the caller wrapper;
206206
- omitted documented permissions without a verified settings-based least-privilege profile.
207+
- `with.Debug: true`, which is nonconforming because the reusable workflow default remains `false`.
208+
209+
When required, the optional test-data mapping extends the candidate baseline without broadening it:
210+
211+
```yaml
212+
secrets:
213+
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
214+
GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }}
215+
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
216+
TestData: ${{ secrets.TestData }}
217+
```
218+
219+
`TestData` is a JSON object with separate `secrets` and `variables` maps, for example
220+
`{"secrets":{"Example":"value"},"variables":{"Feature":"enabled"}}`. Callers omit this mapping entirely when
221+
module-local tests do not need it. No conforming caller sets `with.Debug: true`; the reusable workflow's default remains
222+
`false`.
207223

208224
The candidate caller invokes the reusable workflow for fork-originated `pull_request` events. Plan classifies them into a
209225
restricted, read-only validation mode that permits only repository-local checkout, build, lint, and test with the

docs/content/reference/process-workflow-lifecycle-design.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,22 @@ jobs:
9696
contents: read
9797
pages: write
9898
id-token: write
99+
secrets:
100+
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
101+
GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }}
102+
GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }}
99103
```
100104
105+
These three explicit mappings are the required caller baseline; `secrets: inherit` is nonconforming. The only optional
106+
secret mapping is `TestData` for module-local tests:
107+
108+
```yaml
109+
TestData: ${{ secrets.TestData }}
110+
```
111+
112+
When present, `TestData` contains a JSON object with separate `secrets` and `variables` maps. It is omitted when
113+
unused. A conforming caller does not set `with.Debug: true`; the reusable workflow default remains `false`.
114+
101115
Built-in `GITHUB_TOKEN` authorization is permitted for checkout, repository-local reads, and standard Pages/OIDC deployment within that job boundary. GitHub App installation tokens are step-scoped and authorize every user-facing interaction and every operation that needs broader reach or permissions: pull-request comments and labels, commit statuses and check-facing reporting, releases, tags, assets, and cleanup.
102116

103117
Each App-token step requests only the installation permissions required for its operation. A missing App token is an authorization failure for App-required work: that operation stops before its API request or mutation, without silently falling back to the built-in workflow token. Built-in-token reads and Pages deployment remain available only within the explicit caller job permissions.
@@ -186,6 +200,7 @@ The lifecycle contract is exercised with event payload fixtures and publication
186200
| Gallery immutability | Deterministic pull-request identity, existing-version detection, supported-unlist, and retained-version fixtures across the cancellation boundary. |
187201
| Stable aggregation | Bursts of main-push, manual-dispatch, and scheduled fixtures that replace an intermediate pending run and prove the later stable target aggregates all unreleased merged pull requests. |
188202
| Scoped caller permissions | Empty caller top-level permissions, the three job grants, built-in-token checkout/read, and standard Pages/OIDC verification. |
203+
| Caller credential contract | Explicit baseline mappings for `PSGALLERY_API_KEY`, `GitHubAppClientId`, and `GitHubAppPrivateKey`; rejected `secrets: inherit`; optional `TestData` JSON with separate `secrets` and `variables` maps; and no `with.Debug: true`. |
189204
| App authorization failure | Missing-App-token fixtures that prove user-facing operations fail closed without built-in token fallback. |
190205
| Token boundary | Fixtures that prove App tokens are step-scoped and built-in-token operations remain within the caller job's boundary. |
191206
| Event authorization | Normal-fork `pull_request` fixtures that prove the controlled upstream Plan derives restricted capabilities from immutable fork/base/head metadata before it consumes settings or checked-out code, then permits only checkout/build/lint/test with a green/red outcome and no configured secrets; `pull_request_target` fixtures prove Plan rejects before credentialed or repository-defined code, including for downstream `always()` jobs. |

docs/content/reference/process-workflow-lifecycle-specification.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ Scenario: Recover a range of unreleased merged pull requests
211211

212212
### FR11 — Repository operations MUST use scoped authorization {#fr11}
213213

214-
The caller MUST declare top-level `permissions: {}`. Its Process-PSModule job MUST grant only `contents: read`, `pages: write`, and `id-token: write`. Built-in `GITHUB_TOKEN` MAY authorize repository-local, non-user-facing work when those permissions are sufficient, including checkout, reads, and standard Pages/OIDC deployment. GitHub App installation tokens MUST authorize all user-facing interactions and any operation that exceeds the built-in token's reach or permissions, including pull-request comments and labels, commit statuses and check-facing reporting, releases, tags, assets, and cleanup. Tokens MUST remain scoped to the steps that require them.
214+
The caller MUST declare top-level `permissions: {}`. Its Process-PSModule job MUST grant only `contents: read`, `pages: write`, and `id-token: write`. It MUST explicitly map `PSGALLERY_API_KEY`, `GitHubAppClientId`, and `GitHubAppPrivateKey`; `secrets: inherit` is nonconforming. It MAY additionally map `TestData` only for module-local tests. When present, `TestData` MUST contain a JSON object with separate `secrets` and `variables` maps; callers MUST omit it when unused. No conforming caller MAY set `with.Debug: true`; the reusable workflow default remains `false`.
215+
216+
Built-in `GITHUB_TOKEN` MAY authorize repository-local, non-user-facing work when those permissions are sufficient, including checkout, reads, and standard Pages/OIDC deployment. GitHub App installation tokens MUST authorize all user-facing interactions and any operation that exceeds the built-in token's reach or permissions, including pull-request comments and labels, commit statuses and check-facing reporting, releases, tags, assets, and cleanup. Tokens MUST remain scoped to the steps that require them.
215217

216218
#### Behavioral scenarios {#fr11-scenarios}
217219

@@ -222,6 +224,24 @@ Scenario: Run with the caller's minimum permissions
222224
When the reusable workflow performs checkout or standard Pages deployment
223225
Then it may use the built-in workflow token within that granted boundary
224226
227+
Scenario: Provide the required caller credentials explicitly
228+
Given a conforming caller invokes the reusable workflow
229+
When it maps credentials to the Process-PSModule job
230+
Then it maps PSGALLERY_API_KEY, GitHubAppClientId, and GitHubAppPrivateKey explicitly
231+
And it does not use secrets inherit
232+
233+
Scenario: Provide optional module-local test data
234+
Given module-local tests require caller-provided data
235+
When the caller maps TestData
236+
Then its secret value is a JSON object with separate secrets and variables maps
237+
And the caller omits TestData when tests do not require it
238+
239+
Scenario: Keep caller debug disabled
240+
Given a conforming caller invokes the reusable workflow
241+
When it sets workflow inputs
242+
Then it does not set Debug to true
243+
And the reusable workflow uses its false default
244+
225245
Scenario: Perform a user-facing repository operation
226246
Given the reusable workflow must create a pull-request comment or release
227247
When the operation requires authority beyond the built-in token boundary

0 commit comments

Comments
 (0)