You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/content/reference/process-workflow-fleet-standard.md
+14-5Lines changed: 14 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -136,7 +136,7 @@ decisions before canonical guides, templates, or consumer workflows adopt it:
136
136
| Pull-request activities | Keep all six listed activity types. | Reduce the activity list if a v8 behavior is intentionally unsupported. |
137
137
| 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. |
138
138
| 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. |
139
-
| Fork behavior | Invoke the reusable workflow unconditionally; Plan rejects unsupported fork events before credentialed or repository-defined code. | Add an independent secret-free fork-CI workflow. |
139
+
| 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
140
| Credentials | Explicitly map the three v8 credentials. | Define a narrower credential profile for repositories that cannot publish. |
141
141
| Optional surface | Permit only documented `TestData`, workflow inputs, schedule timing, and presentation metadata. | Allow additional extension points after naming and compatibility rules are agreed. |
142
142
@@ -171,7 +171,7 @@ fleet campaign. Branch names, `latest`, floating minor tags, and unqualified tar
171
171
| Schedule | Keep a scheduled health run. | Exercises current dependencies even when repository code is unchanged. |
172
172
| Concurrency | Use the PR-number-or-ref key and cancel only pull-request runs. | Pull-request changes converge promptly while non-pull-request runs serialize by ref. |
173
173
| 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. |
174
-
| Fork authorization | Leave the caller job unconditional. | Plan rejects unsupported forks before credentials or repository-defined code run. |
174
+
| 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. |
175
175
| 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
176
| Credentials | Explicitly map the three required secrets. | Satisfies the `v7+` contract and prevents unrelated secret inheritance. |
177
177
| Scope | Keep the caller as a single delegation job. | Repository-specific automation remains independently understandable and maintainable. |
@@ -205,9 +205,18 @@ an approved structure:
205
205
- unrelated additional jobs in the caller wrapper;
206
206
- omitted documented permissions without a verified settings-based least-privilege profile.
207
207
208
-
The candidate caller invokes the reusable workflow for fork-originated pull requests. Plan rejects unsupported fork events
209
-
before credentials or repository-defined code run. Supporting fork CI requires a separate, secret-free, read-only workflow;
210
-
issue [#514](https://github.com/PSModule/Process-PSModule/issues/514) must approve that boundary.
208
+
The candidate caller invokes the reusable workflow for fork-originated `pull_request` events. Plan classifies them into a
209
+
restricted, read-only validation mode that permits only repository-local checkout, build, lint, and test with the
210
+
least-privilege built-in token. It emits explicit capabilities that prohibit App-token creation, publication, mutation,
211
+
Pages deployment, cleanup, and user-facing reporting. `pull_request_target` remains unsupported and Plan must reject it
212
+
before credentials or repository-defined code run; issue [#514](https://github.com/PSModule/Process-PSModule/issues/514)
213
+
must approve any separate trust boundary for that event.
214
+
215
+
The controlled upstream `v8` Plan implementation derives that restricted envelope first from immutable GitHub event
216
+
metadata, including fork, base, and head identities. It may then use fork settings and checked-out files only as
217
+
untrusted validation and build inputs; they cannot enable credentials, broaden permissions, or change the capability
218
+
envelope. This permits ordinary fork contributors to receive the standard workflow green/red validation without
219
+
configuring secrets.
211
220
212
221
The candidate keeps repository-specific automation in a separate workflow file. That keeps the Process-PSModule wrapper
213
222
identical enough for automated comparison while allowing modules to own unrelated schedules, generation, or integration
Copy file name to clipboardExpand all lines: docs/content/reference/process-workflow-lifecycle-design.md
+32-6Lines changed: 32 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,6 +25,7 @@ Plan resolves the caller event into one release classification before build and
25
25
| --- | --- | --- | --- | --- |
26
26
|`workflow_dispatch` on the default branch | Recovery or resume | Stable release or no-op | Never cancel | Rebuild and validate the selected commit; reconstruct the unreleased release notes. |
27
27
|`schedule`| Published-artifact validation | No-op after validation | Never cancel | Validate the latest published stable artifact and its documentation. |
28
+
| Fork `pull_request`| Restricted read-only validation | No-op after validation | Cancels a superseded pull-request run; the later run converges state | Perform only safe repository-local checkout, build, lint, and test with no privileged or user-facing operation. |
28
29
| Pull request `opened`, `reopened`, `synchronize`| Pull-request classification | Prerelease or no-op | Cancels a superseded pull-request run; the later run converges state | Report configured validation and execute the planned release action. |
29
30
| Pull request `labeled`, `unlabeled`| Pull-request classification refresh | Prerelease, cleanup-only, or no-op | Cancels a superseded pull-request run; the later run converges state | Resolve the complete current classification and execute its action. |
30
31
| Merged pull request `closed`| Post-merge close | No-op | Cancels a superseded pull-request run; the later run converges state | Do not clean up; the successful main-push release owns promotion cleanup. |
@@ -35,11 +36,29 @@ Plan records its classification and release decision in enriched Settings. Downs
35
36
36
37
## Candidate event authorization
37
38
38
-
The caller invokes the reusable workflow without a caller-level fork or event condition. Plan is the event-authorization boundary: it rejects unsupported fork pull requests before credentialed or repository-defined code runs. An authorization rejection produces no usable Settings and no credentialed follow-on work.
39
-
40
-
Every downstream job depends on a successful authorized Plan and valid Settings. This requirement applies equally to jobs that use `always()`: their conditions first require the Plan result and Settings validity, then apply their own failure-handling logic. A downstream job never parses missing or invalid Settings and cannot bypass the Plan gate.
41
-
42
-
Secret-free fork CI, if needed, is a separate workflow with its own trigger, authorization, and read-only contract. It is not a mode of the credentialed Process-PSModule reusable workflow.
39
+
The caller invokes the reusable workflow without a caller-level fork or event condition. Plan is the event-authorization
40
+
boundary. For a normal fork `pull_request`, the controlled upstream Process-PSModule `v8` Plan implementation first
41
+
derives the security and capability envelope from immutable GitHub event metadata: the fork condition and the base and
42
+
head identities. It may query trusted upstream or base version and state as needed. GitHub withholds fork secrets, so
43
+
Plan then emits an authorized restricted read-only validation record rather than rejecting the event. That record sets
44
+
`IsFork=true`, `AllowAppToken=false`, `AllowPublication=false`, and `AllowMutation=false`. It permits only
45
+
repository-local checkout, build, lint, and test with the least-privilege built-in token, giving the contributor the
46
+
standard green/red validation outcome without configured secrets.
47
+
48
+
Repository settings and checked-out fork files are consumed only after that envelope is fixed, and only as untrusted
49
+
validation or build inputs. They cannot enable an App token; publication, mutation, deployment, or cleanup; or broader
50
+
permissions.
51
+
52
+
No restricted fork path may create an App token; access PowerShell Gallery; comment on, label, or mutate a pull request;
53
+
write a status or other check-facing report; create releases, tags, or assets; perform cleanup; deploy Pages; or perform
54
+
another privileged or user-facing operation. `pull_request_target` remains unsupported because it could combine
55
+
privileged context with untrusted code. Plan rejects that event before credentials or repository-defined code run. An
56
+
authorization rejection produces no usable Settings and no credentialed follow-on work.
57
+
58
+
Every downstream job depends on a successful authorized Plan and valid Settings. This requirement applies equally to jobs
59
+
that use `always()`: their conditions first require the Plan result and Settings validity, then apply their own
60
+
failure-handling logic. Privileged jobs additionally require their relevant explicit capability. A downstream job never
61
+
parses missing or invalid Settings and cannot bypass the Plan gate.
43
62
44
63
## Candidate artifact and version boundary
45
64
@@ -50,6 +69,7 @@ Version resolution is the boundary between planning and release-capable work. Th
50
69
| Event and run type | Identifies the GitHub event and its candidate lifecycle classification. |
51
70
| Event action | Preserves the relevant pull-request activity or non-pull-request action. |
52
71
| Pull-request identity, state, and merged status | Distinguishes active, merged, and abandoned pull-request outcomes. |
72
+
| Authorization capabilities and evidence | Records `IsFork`, the immutable event metadata used to derive it, and the explicit App-token, publication, and mutation capabilities that each downstream job must enforce. |
53
73
| Labels and repository settings result | Captures the input policy state used only by Plan. |
54
74
| Version bump and base version | Explains the selected version transition. |
55
75
| Manifest version, prerelease identifier, and full version or tag | Defines the only version and tag permitted in the built artifact and release. |
@@ -82,6 +102,11 @@ Built-in `GITHUB_TOKEN` authorization is permitted for checkout, repository-loca
82
102
83
103
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.
84
104
105
+
For a Plan-classified restricted fork run, the Settings capabilities override the caller job's otherwise available
106
+
permissions: no App token is created, no Pages deployment runs, and no repository mutation or user-facing action runs.
107
+
The fork path has only the least-privilege built-in-token access required for repository-local checkout, build, lint,
108
+
and test.
109
+
85
110
## Candidate Pages authorization
86
111
87
112
The standard `actions/deploy-pages` path uses the built-in token's `pages: write` and `id-token: write` permissions granted only to the caller's Process-PSModule job. It remains inside the candidate's repository-local, non-user-facing boundary and does not require an App token.
@@ -163,7 +188,8 @@ The lifecycle contract is exercised with event payload fixtures and publication
163
188
| Scoped caller permissions | Empty caller top-level permissions, the three job grants, built-in-token checkout/read, and standard Pages/OIDC verification. |
164
189
| App authorization failure | Missing-App-token fixtures that prove user-facing operations fail closed without built-in token fallback. |
165
190
| Token boundary | Fixtures that prove App tokens are step-scoped and built-in-token operations remain within the caller job's boundary. |
166
-
| Event authorization | Unsupported-fork fixtures that prove Plan rejects before credentialed or repository-defined code, including for downstream `always()` jobs. |
191
+
| 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. |
192
+
| Capability enforcement | Restricted-fork fixtures that prove App-token creation, Gallery access, comments, labels, statuses, releases, tags, assets, cleanup, Pages deployment, and other privileged paths cannot run. |
Copy file name to clipboardExpand all lines: docs/content/reference/process-workflow-lifecycle-specification.md
+43-3Lines changed: 43 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -231,13 +231,46 @@ Scenario: Perform a user-facing repository operation
231
231
232
232
### FR12 — Plan MUST authorize events before downstream execution {#fr12}
233
233
234
-
The caller MUST invoke the reusable workflow without a caller-level fork or event condition. Plan MUST reject unsupported fork pull-request execution before any credentialed or repository-defined code runs. Every downstream job, including a job with `always()`, MUST require a successful authorized Plan and valid Settings. No downstream job MAY evaluate missing or invalid Settings or bypass the Plan gate.
234
+
The caller MUST invoke the reusable workflow without a caller-level fork or event condition. Plan MUST classify a normal
235
+
fork `pull_request` event into an authorized restricted read-only validation mode before downstream execution. Its valid
236
+
Settings MUST explicitly set `IsFork=true`, `AllowAppToken=false`, `AllowPublication=false`, and
237
+
`AllowMutation=false`. That mode MAY perform only safe repository-local checkout, build, lint, and test with the
238
+
least-privilege built-in token. It MUST NOT create an App token; access PowerShell Gallery; create pull-request
239
+
comments, labels, or status mutations; create releases, tags, or assets; perform cleanup; deploy Pages; or run another
240
+
privileged or user-facing operation.
241
+
242
+
The controlled upstream reusable-workflow Plan implementation MUST derive the restricted capability envelope first from
243
+
immutable GitHub event metadata, including fork, base, and head identities, before interpreting repository settings or
244
+
executing checked-out repository code. It MAY query the trusted upstream or base version and state as needed. Fork
245
+
settings and files MAY be consumed only as untrusted validation and build inputs; they MUST NOT enable App tokens,
246
+
mutation, publication, deployment, cleanup, or broaden permissions. The restricted mode MUST provide the ordinary
247
+
green/red validation outcome without requiring contributor-configured secrets.
248
+
249
+
`pull_request_target` MUST remain unsupported until a separate trust boundary is designed and approved. Plan MUST reject
250
+
that event before credentials or repository-defined code run. Every downstream job, including a job with `always()`,
251
+
MUST require a successful authorized Plan and valid Settings, and every privileged downstream job MUST also require its
252
+
relevant planned capability. No downstream job MAY evaluate missing or invalid Settings or bypass the Plan gate.
235
253
236
254
#### Behavioral scenarios {#fr12-scenarios}
237
255
238
256
```gherkin
239
-
Scenario: Reject an unsupported fork pull request
240
-
Given a pull request originates from an unsupported fork
257
+
Scenario: Validate a normal fork pull request in restricted mode
258
+
Given a pull request originates from a fork through the pull_request event
259
+
When Plan evaluates the event
260
+
Then Plan emits valid Settings with IsFork true and App-token, publication, and mutation capabilities false
261
+
And downstream work may perform only repository-local checkout, build, lint, and test with the least-privilege built-in token
262
+
And no App token, Gallery access, user-facing operation, Pages deployment, publication, or cleanup runs
263
+
And the contributor receives the standard green or red validation outcome without configured secrets
264
+
265
+
Scenario: Derive fork capabilities before interpreting untrusted repository inputs
266
+
Given a pull request originates from a fork through the pull_request event
267
+
And its repository settings attempt to enable publication
268
+
When the controlled upstream Plan evaluates immutable fork, base, and head metadata
269
+
Then it fixes the restricted capability envelope before reading the settings or checked-out files
270
+
And the settings cannot enable App tokens, mutation, publication, deployment, cleanup, or broader permissions
271
+
272
+
Scenario: Reject an unsupported pull_request_target event
273
+
Given a pull_request_target event is received
241
274
When Plan evaluates the event
242
275
Then Plan rejects the event before credentialed or repository-defined code runs
243
276
And no downstream job receives authorized Settings
@@ -247,6 +280,13 @@ Scenario: Gate an always-running downstream job
247
280
When a downstream job with an always condition is evaluated
248
281
Then the job does not run
249
282
And it does not evaluate the missing or invalid Settings
283
+
284
+
Scenario: Gate a privileged job for a restricted fork run
285
+
Given Plan emits valid restricted Settings for a fork pull request
286
+
And the planned capability for publication is false
287
+
When a publication job is evaluated
288
+
Then the job does not run
289
+
And it does not create an App token or parse an absent publication configuration
0 commit comments