actions-warden 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +189 -0
- package/CONTRIBUTING.md +109 -0
- package/README.md +272 -224
- package/RELEASING.md +338 -0
- package/SECURITY.md +25 -3
- package/docs/AI-AGENTS.md +458 -0
- package/docs/CLI.md +421 -0
- package/docs/CONFIGURATION.md +340 -0
- package/docs/DEVELOPMENT.md +350 -0
- package/docs/GITHUB-ACTION.md +281 -0
- package/docs/JAVASCRIPT-API.md +355 -0
- package/docs/OUTPUTS.md +409 -0
- package/docs/README.md +27 -0
- package/examples/org-scan.yml +42 -0
- package/examples/upgrade-pr.yml +57 -0
- package/llms.txt +38 -0
- package/package.json +32 -10
- package/skills/actions-warden/SKILL.md +140 -38
- package/src/action.js +317 -0
- package/src/cli.js +267 -22
- package/src/commands/audit.js +189 -36
- package/src/commands/org-scan.js +549 -0
- package/src/commands/pin.js +59 -56
- package/src/commands/report.js +122 -10
- package/src/commands/upgrade.js +102 -62
- package/src/commands/verify.js +193 -0
- package/src/index.js +21 -4
- package/src/lib/action-status.js +27 -0
- package/src/lib/agent-mode.js +175 -0
- package/src/lib/annotations.js +250 -0
- package/src/lib/baseline.js +103 -0
- package/src/lib/cache.js +47 -10
- package/src/lib/concurrency.js +27 -0
- package/src/lib/config.js +185 -0
- package/src/lib/execution.js +71 -0
- package/src/lib/formatter.js +127 -8
- package/src/lib/github-org.js +374 -0
- package/src/lib/identity.js +62 -0
- package/src/lib/ignore.js +7 -6
- package/src/lib/org-checkpoint.js +378 -0
- package/src/lib/org-progress.js +60 -0
- package/src/lib/parser.js +326 -52
- package/src/lib/patcher.js +199 -0
- package/src/lib/paths.js +35 -12
- package/src/lib/redact.js +65 -4
- package/src/lib/resolver.js +225 -43
- package/src/lib/targets.js +28 -0
- package/src/lib/triggers.js +12 -0
- package/src/lib/writer.js +45 -8
- package/src/rules/excessive-permissions.js +24 -33
- package/src/rules/index.js +19 -1
- package/src/rules/pull-request-target-checkout.js +149 -18
- package/src/rules/reusable-workflow-secrets.js +32 -0
- package/src/rules/script-injection.js +77 -12
- package/src/rules/secrets-in-env.js +101 -18
- package/src/rules/unpinned-action.js +3 -2
- package/src/rules/unpinned-container-image.js +39 -0
- package/src/rules/unpinned-docker-action.js +30 -0
- package/src/rules/untrusted-self-hosted-runner.js +109 -0
- package/src/rules/workflow-run-artifact-execution.js +122 -0
- package/src/rules/workflow-structure.js +396 -0
- package/src/version.js +3 -0
package/RELEASING.md
ADDED
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
# Releasing actions-warden
|
|
2
|
+
|
|
3
|
+
This is the authoritative maintainer and coding-agent runbook. `actions-warden`
|
|
4
|
+
has no long-running service to deploy. In this repository, a release or deploy
|
|
5
|
+
means publishing one coordinated version through four distribution channels:
|
|
6
|
+
|
|
7
|
+
- the `actions-warden` npm package;
|
|
8
|
+
- an immutable GitHub tag and release named `vX.Y.Z`;
|
|
9
|
+
- the floating GitHub Action tag `vX`;
|
|
10
|
+
- the `chiz0me/claude-plugins` marketplace entry.
|
|
11
|
+
|
|
12
|
+
The tag-triggered
|
|
13
|
+
[release workflow](https://github.com/chiz0me/actions-warden/blob/main/.github/workflows/release.yml)
|
|
14
|
+
is the only normal publication path. Do not run `npm publish` from a workstation
|
|
15
|
+
except for an explicitly approved bootstrap or incident-recovery operation.
|
|
16
|
+
|
|
17
|
+
## Agent authorization contract
|
|
18
|
+
|
|
19
|
+
Repository-aware agents must map release requests as follows. A direct request
|
|
20
|
+
is enough authorization for the matching row; the maintainer does not need to
|
|
21
|
+
repeat the commands in this guide.
|
|
22
|
+
|
|
23
|
+
| Maintainer request | Authorized work | Remote publication |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| “check/review release readiness” | Read-only local, GitHub, and npm checks | none |
|
|
26
|
+
| “prepare release `X.Y.Z`” or “bump to `X.Y.Z`” | Update local version sources, rebuild `dist/`, inspect the package, and validate | none |
|
|
27
|
+
| “release/publish/deploy actions-warden `X.Y.Z`” | Preflight, prepare, commit intended release changes, push `main`, wait for CI, create and push the immutable tag, monitor, and verify | yes |
|
|
28
|
+
| “release/publish/deploy actions-warden” | The same full workflow, with the version selected by the policy below | yes |
|
|
29
|
+
| “retry release `vX.Y.Z`” | Classify existing state and rerun the existing workflow when recovery is idempotent | only missing stages |
|
|
30
|
+
|
|
31
|
+
“Prepare,” “bump,” “check,” and “review” do not authorize a commit, push, tag,
|
|
32
|
+
GitHub release, npm publish, or marketplace write. A full release request does
|
|
33
|
+
not authorize force-moving or deleting an immutable version tag, publishing
|
|
34
|
+
unreviewed files, weakening validation, changing repository protections, npm
|
|
35
|
+
unpublishing, or npm deprecation. Those require separate explicit direction.
|
|
36
|
+
|
|
37
|
+
Before any full release, the agent must state the chosen version and the
|
|
38
|
+
preflight result in a short progress update. It should continue without asking
|
|
39
|
+
the maintainer to restate this runbook when every check passes.
|
|
40
|
+
|
|
41
|
+
### Hard stops
|
|
42
|
+
|
|
43
|
+
Stop before creating a remote commit or tag when any of these is true:
|
|
44
|
+
|
|
45
|
+
- the worktree contains changes whose ownership or release intent is unknown;
|
|
46
|
+
- the current branch is not `main`, or local `main` is behind or diverged from
|
|
47
|
+
`origin/main` after a fresh fetch;
|
|
48
|
+
- the intended release commit is not contained in `origin/main`;
|
|
49
|
+
- the candidate is not a stable `X.Y.Z`, is not newer than npm `latest`, or an
|
|
50
|
+
immutable tag/release already exists outside an intentional retry;
|
|
51
|
+
- another release run is queued or in progress;
|
|
52
|
+
- GitHub authentication, trusted publishing, the marketplace secret, branch
|
|
53
|
+
access, or tag access is unavailable;
|
|
54
|
+
- tests, lint, audit, documentation, package inspection, or bundle
|
|
55
|
+
reproducibility fails.
|
|
56
|
+
|
|
57
|
+
A clean checkout that is only behind may be updated with a fast-forward pull.
|
|
58
|
+
Never reset, overwrite, stash, or merge a dirty/diverged checkout to get around
|
|
59
|
+
a blocker. Report the exact evidence and the smallest required correction.
|
|
60
|
+
|
|
61
|
+
## Choose the version
|
|
62
|
+
|
|
63
|
+
Use the version the maintainer supplies when it is a valid, unpublished stable
|
|
64
|
+
SemVer greater than npm `latest`. If no version is supplied, compare the latest
|
|
65
|
+
immutable release with the intended diff and choose the highest applicable
|
|
66
|
+
bump:
|
|
67
|
+
|
|
68
|
+
| Change | Version bump |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Compatible fix, documentation, internal refactor, or dependency maintenance | patch |
|
|
71
|
+
| New public command, option, rule, output capability, or other compatible feature | minor |
|
|
72
|
+
| Incompatible public behavior while the package is `0.x` | minor |
|
|
73
|
+
| Incompatible public behavior after `1.0.0` | major |
|
|
74
|
+
|
|
75
|
+
Stable releases only are currently supported. Do not create prerelease tags or
|
|
76
|
+
invent a lower version from the checkout: npm and GitHub are the live source of
|
|
77
|
+
truth. If compatibility cannot be determined safely, stop and ask only for the
|
|
78
|
+
version decision.
|
|
79
|
+
|
|
80
|
+
## Full release procedure
|
|
81
|
+
|
|
82
|
+
### 1. Inspect live state
|
|
83
|
+
|
|
84
|
+
Start without mutating project files:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
git status --short --branch
|
|
88
|
+
git fetch --prune origin main
|
|
89
|
+
git branch --show-current
|
|
90
|
+
git rev-list --left-right --count HEAD...origin/main
|
|
91
|
+
npm view actions-warden version dist-tags --json
|
|
92
|
+
gh auth status
|
|
93
|
+
gh run list --workflow=release.yml --limit=20 \
|
|
94
|
+
--json databaseId,status,conclusion,headSha,displayTitle,url
|
|
95
|
+
gh secret list --repo chiz0me/actions-warden
|
|
96
|
+
gh api repos/chiz0me/actions-warden/rulesets \
|
|
97
|
+
--jq 'map({name,target,enforcement})'
|
|
98
|
+
gh api repos/chiz0me/actions-warden/branches/main/protection \
|
|
99
|
+
--jq '{required_status_checks,required_pull_request_reviews,enforce_admins}'
|
|
100
|
+
gh api repos/chiz0me/actions-warden/environments \
|
|
101
|
+
--jq '[.environments[].name]'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The branch must be `main`; before preparation, `HEAD...origin/main` must be
|
|
105
|
+
`0 0`. The status output must contain only understood, intended changes. The
|
|
106
|
+
secret list must include `MARKETPLACE_SYNC_TOKEN`; never request or print its
|
|
107
|
+
value. No release workflow may be `queued`, `pending`, `waiting`, or
|
|
108
|
+
`in_progress`. Observe the live branch, tag, and environment rules and follow
|
|
109
|
+
them without bypass; an empty result means those optional protections are not
|
|
110
|
+
configured. HTTP 404 from the legacy branch-protection query means no legacy
|
|
111
|
+
rule is configured; evaluate repository rulesets separately. Neither result
|
|
112
|
+
authorizes an agent to invent repository settings during a release.
|
|
113
|
+
|
|
114
|
+
Set the selected version locally for the remaining examples and verify that no
|
|
115
|
+
immutable object already owns it:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
release_version=X.Y.Z
|
|
119
|
+
git tag --list "v${release_version}"
|
|
120
|
+
git ls-remote --tags --refs origin "refs/tags/v${release_version}"
|
|
121
|
+
gh release view "v${release_version}"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The first two commands must print nothing and `gh release view` must report no
|
|
125
|
+
release. Existing state is acceptable only for the retry procedure.
|
|
126
|
+
|
|
127
|
+
### 2. Prepare and inspect the candidate
|
|
128
|
+
|
|
129
|
+
Install the committed graph, update every version-bearing source, and rebuild
|
|
130
|
+
the GitHub Action bundle:
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
npm ci
|
|
134
|
+
npm run release:prepare -- "$release_version"
|
|
135
|
+
npm run build:action
|
|
136
|
+
git diff --check
|
|
137
|
+
git status --short
|
|
138
|
+
git diff
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`release:prepare` updates `package.json`, both lockfile version fields,
|
|
142
|
+
`.claude-plugin/plugin.json`, `src/version.js`, and exact public
|
|
143
|
+
`actions-warden@X.Y.Z` invocations. It never commits, tags, pushes, or
|
|
144
|
+
publishes.
|
|
145
|
+
|
|
146
|
+
Review every changed file. Stage exact intended paths—do not use a broad add in
|
|
147
|
+
a dirty worktree—then run the release gate:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
git add <reviewed-paths>
|
|
151
|
+
npm run release:check
|
|
152
|
+
git diff --cached --check
|
|
153
|
+
git diff --cached
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`release:check` verifies registry version monotonicity, version synchronization,
|
|
157
|
+
exact dependencies, YAML, documentation links, lint, tests, dependency audit,
|
|
158
|
+
the exact npm tarball manifest, and the staged/working Action bundle against a
|
|
159
|
+
clean rebuild. On a workflow retry, the registry guard also requires the local
|
|
160
|
+
tarball integrity to equal the already-published immutable artifact. The gate
|
|
161
|
+
intentionally fails if `dist/index.js` or
|
|
162
|
+
`dist/package.json` is not staged.
|
|
163
|
+
|
|
164
|
+
### 3. Commit and pass main CI
|
|
165
|
+
|
|
166
|
+
```sh
|
|
167
|
+
git commit -m "release: v${release_version}"
|
|
168
|
+
release_sha="$(git rev-parse HEAD)"
|
|
169
|
+
git push origin HEAD:main
|
|
170
|
+
gh run list --workflow=ci.yml --commit "$release_sha" --limit=1 \
|
|
171
|
+
--json databaseId,status,conclusion,url
|
|
172
|
+
gh run watch <CI_RUN_ID> --exit-status
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The direct push is the current repository path. If branch policy later requires
|
|
176
|
+
a pull request, push a dedicated release branch, open the release PR, and wait
|
|
177
|
+
for its required review and CI instead of bypassing protection. After the
|
|
178
|
+
approved merge, set `release_sha` to the resulting `origin/main` commit. A full
|
|
179
|
+
release request authorizes that normal release PR flow, but not a protection
|
|
180
|
+
bypass.
|
|
181
|
+
|
|
182
|
+
Wait for the CI run belonging to `release_sha`; do not substitute an older
|
|
183
|
+
green run. After it succeeds, fetch again and require a clean worktree plus an
|
|
184
|
+
exact remote match:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
git fetch --prune origin main
|
|
188
|
+
git status --short --branch
|
|
189
|
+
test "$(git rev-parse HEAD)" = "$(git rev-parse origin/main)"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 4. Create the immutable trigger
|
|
193
|
+
|
|
194
|
+
The remote version tag is the irreversible publication trigger:
|
|
195
|
+
|
|
196
|
+
```sh
|
|
197
|
+
git tag -a "v${release_version}" -m "v${release_version}" "$release_sha"
|
|
198
|
+
git push origin "refs/tags/v${release_version}"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Never use `--force` for `vX.Y.Z`. If the push races with an existing tag, stop
|
|
202
|
+
and compare its commit before doing anything else.
|
|
203
|
+
|
|
204
|
+
### 5. Monitor publication
|
|
205
|
+
|
|
206
|
+
Find the release run for the exact commit and watch it to completion:
|
|
207
|
+
|
|
208
|
+
```sh
|
|
209
|
+
gh run list --workflow=release.yml --commit "$release_sha" --limit=1 \
|
|
210
|
+
--json databaseId,status,conclusion,url
|
|
211
|
+
gh run watch <RELEASE_RUN_ID> --exit-status
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The workflow is serialized with a
|
|
215
|
+
[queued concurrency group](https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency?apiVersion=2022-11-28).
|
|
216
|
+
Its publication chain is:
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
validate -> release-draft -> publish-npm -> release
|
|
220
|
+
|-> floating-major-tag
|
|
221
|
+
`-> sync-marketplace
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
| Job | Responsibility |
|
|
225
|
+
|---|---|
|
|
226
|
+
| `validate` | Stable tag, package match, `main` ancestry, npm monotonicity/retry integrity, tests, lint, YAML/docs, exact dependencies, version sync, audit, tarball inspection, and bundle reproduction |
|
|
227
|
+
| `release-draft` | Create or reuse a draft GitHub release for the immutable tag |
|
|
228
|
+
| `publish-npm` | Publish with npm OIDC and provenance, or safely skip an already-published retry |
|
|
229
|
+
| `release` | Make the GitHub release final only after npm succeeds |
|
|
230
|
+
| `floating-major-tag` | Move the intentionally mutable `vN` Action tag to the release commit |
|
|
231
|
+
| `sync-marketplace` | Update and commit the external Claude plugin marketplace version |
|
|
232
|
+
|
|
233
|
+
The draft-first order prevents a final GitHub release from advertising an npm
|
|
234
|
+
publication that failed. Timeouts bound every job, and queued concurrency
|
|
235
|
+
prevents overlapping releases from racing the npm dist-tag or floating Action
|
|
236
|
+
tag.
|
|
237
|
+
|
|
238
|
+
### 6. Verify every channel
|
|
239
|
+
|
|
240
|
+
```sh
|
|
241
|
+
npm view actions-warden version dist-tags --json
|
|
242
|
+
npm view "actions-warden@${release_version}" version dist.integrity --json
|
|
243
|
+
gh release view "v${release_version}" \
|
|
244
|
+
--json tagName,isDraft,isPrerelease,targetCommitish,url
|
|
245
|
+
git ls-remote --tags origin \
|
|
246
|
+
"refs/tags/v${release_version}" \
|
|
247
|
+
"refs/tags/v${release_version}^{}" \
|
|
248
|
+
"refs/tags/v${release_version%%.*}"
|
|
249
|
+
gh api repos/chiz0me/claude-plugins/contents/.claude-plugin/marketplace.json \
|
|
250
|
+
--jq '.content' | base64 -d \
|
|
251
|
+
| node -e "let s='';process.stdin.on('data',c=>s+=c).on('end',()=>{const d=JSON.parse(s);console.log(d.plugins.find(p=>p.name==='actions-warden').version)})"
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Confirm that npm `latest`, the npm package, the final GitHub release, the
|
|
255
|
+
immutable tag, the floating major tag, and the marketplace entry all identify
|
|
256
|
+
the new version/commit. Also confirm the npm package page shows provenance.
|
|
257
|
+
For the annotated immutable tag, its peeled `^{}` row and the floating `vN` row
|
|
258
|
+
must equal `release_sha`. Record the release and workflow URLs in the handoff.
|
|
259
|
+
|
|
260
|
+
Do not use a local floating `vN` tag as evidence. It is expected to become stale
|
|
261
|
+
when a release workflow moves the remote tag, and a blanket `git fetch --tags`
|
|
262
|
+
may reject that update as a clobber. The explicit `git ls-remote` result above
|
|
263
|
+
is authoritative; immutable `vX.Y.Z` tags are never moved.
|
|
264
|
+
|
|
265
|
+
## Retry and recovery
|
|
266
|
+
|
|
267
|
+
Classify the failure before acting. Reruns are designed to be idempotent, but
|
|
268
|
+
version tags and npm versions are immutable.
|
|
269
|
+
|
|
270
|
+
| Observed state | Safe action |
|
|
271
|
+
|---|---|
|
|
272
|
+
| Validation or transient infrastructure failed; nothing published | Rerun the same workflow only if the tagged commit needs no code change. If code must change, fix `main` and release a new version. |
|
|
273
|
+
| Draft release exists; npm is absent | Correct the external/OIDC problem and rerun the same workflow. The draft is reused. |
|
|
274
|
+
| npm version exists; GitHub release is still a draft | Rerun. Registry checks and publish are safe no-ops, then the draft is finalized. |
|
|
275
|
+
| Final GitHub release exists; floating tag or marketplace sync failed | Rerun the failed jobs or whole workflow. Do not republish or create a replacement tag. |
|
|
276
|
+
| Marketplace authentication or push failed | Restore `MARKETPLACE_SYNC_TOKEN` access or resolve the marketplace branch conflict, then rerun. |
|
|
277
|
+
| Published package is defective | Fix forward with a newer version. Deprecate only on explicit maintainer instruction; never unpublish automatically. |
|
|
278
|
+
| Remote tag exists but no workflow run exists | Verify the tag commit and that the workflow existed there. Do not force-push the tag; use a new version unless the maintainer explicitly directs recovery. |
|
|
279
|
+
|
|
280
|
+
Use GitHub's **Re-run all jobs** or `gh run rerun <RUN_ID>` for an unchanged
|
|
281
|
+
tagged commit. Do not delete a draft, release, package, or remote tag as an
|
|
282
|
+
automatic cleanup step.
|
|
283
|
+
|
|
284
|
+
## One-time repository setup
|
|
285
|
+
|
|
286
|
+
### npm Trusted Publisher
|
|
287
|
+
|
|
288
|
+
The package is configured with
|
|
289
|
+
[npm trusted publishing](https://docs.npmjs.com/trusted-publishers/) and this
|
|
290
|
+
publisher identity:
|
|
291
|
+
|
|
292
|
+
- Organization or user: `chiz0me`
|
|
293
|
+
- Repository: `actions-warden`
|
|
294
|
+
- Workflow filename: `release.yml`
|
|
295
|
+
- Environment: blank
|
|
296
|
+
|
|
297
|
+
The workflow grants only the publish job `id-token: write`, uses a GitHub-hosted
|
|
298
|
+
runner, disables package-manager caching, and pins Node `24.18.0` plus npm
|
|
299
|
+
`12.0.2`. That Node version satisfies npm `12.0.2`'s engine range. npm trusted
|
|
300
|
+
publishing currently requires npm 11.5.1 or newer and Node 22.14.0 or newer.
|
|
301
|
+
Update both pins deliberately when requirements or security fixes change;
|
|
302
|
+
never replace them with mutable `latest` installs in the release job. The
|
|
303
|
+
publish command ignores package lifecycle scripts after the tagged source has
|
|
304
|
+
passed validation and requests an npm
|
|
305
|
+
[provenance statement](https://docs.npmjs.com/generating-provenance-statements/).
|
|
306
|
+
|
|
307
|
+
After OIDC publication is verified, configure npm package access to require 2FA
|
|
308
|
+
and disallow token-based publishing where the account policy permits it. If a
|
|
309
|
+
GitHub environment is added to the publish job later, the npm trusted publisher
|
|
310
|
+
environment must be updated to the exact same name.
|
|
311
|
+
|
|
312
|
+
### `MARKETPLACE_SYNC_TOKEN`
|
|
313
|
+
|
|
314
|
+
Cross-repository writes require a fine-grained personal access token because
|
|
315
|
+
the source repository's default `GITHUB_TOKEN` cannot write to
|
|
316
|
+
`chiz0me/claude-plugins`.
|
|
317
|
+
|
|
318
|
+
1. Limit repository access to `chiz0me/claude-plugins`.
|
|
319
|
+
2. Grant only **Contents: Read and write**.
|
|
320
|
+
3. Store it in `chiz0me/actions-warden` as the Actions secret
|
|
321
|
+
`MARKETPLACE_SYNC_TOKEN`.
|
|
322
|
+
4. Rotate or replace it without placing its value in logs, issues, prompts, or
|
|
323
|
+
this repository.
|
|
324
|
+
|
|
325
|
+
### Repository protections
|
|
326
|
+
|
|
327
|
+
For stronger remote enforcement, protect `main` with required CI and review
|
|
328
|
+
rules appropriate to the project. Add a tag ruleset that prevents update and
|
|
329
|
+
deletion of immutable `v*.*.*` tags while still allowing maintainers to create
|
|
330
|
+
new versions and the release workflow to move only floating `vN` tags. Do not
|
|
331
|
+
apply an immutable-tag rule broadly enough to block `vN`.
|
|
332
|
+
|
|
333
|
+
A protected publish environment is optional. Adding one requires the exact
|
|
334
|
+
environment name in both `publish-npm.environment` and npm's trusted publisher
|
|
335
|
+
settings, so make those changes together and test them before relying on the
|
|
336
|
+
next release. GitHub Action Marketplace enrollment is a one-time manual action
|
|
337
|
+
from a successfully published release; `action.yml` already contains the
|
|
338
|
+
required branding metadata.
|
package/SECURITY.md
CHANGED
|
@@ -12,7 +12,7 @@ Please include:
|
|
|
12
12
|
|
|
13
13
|
- A clear description of the issue.
|
|
14
14
|
- A minimal reproduction (workflow YAML, command line, expected vs. actual).
|
|
15
|
-
- The version of `actions-warden` (`npx actions-warden --version`).
|
|
15
|
+
- The version of `actions-warden` (`npx --yes actions-warden@0.3.0 --version`).
|
|
16
16
|
- Any disclosure constraints on your side.
|
|
17
17
|
|
|
18
18
|
We aim to acknowledge within **3 business days** and to ship a fix or a
|
|
@@ -22,10 +22,13 @@ documented mitigation within **30 days** of triage for high-severity issues.
|
|
|
22
22
|
|
|
23
23
|
In scope:
|
|
24
24
|
|
|
25
|
-
- Path traversal or arbitrary file write in `pin`, `upgrade`,
|
|
26
|
-
|
|
25
|
+
- Path traversal or arbitrary file write in `pin`, `upgrade`, `report`, or
|
|
26
|
+
organization checkpoint/report output.
|
|
27
|
+
- Bypasses of the explicit `--write` authorization boundary.
|
|
27
28
|
- Logging or persisting credentials anywhere (cache, output, stderr).
|
|
28
29
|
- Workflow parser crashes on attacker-controlled YAML.
|
|
30
|
+
- Organization scans that silently omit repositories or workflow files while
|
|
31
|
+
reporting complete coverage.
|
|
29
32
|
- Network requests sent to hosts other than `api.github.com`.
|
|
30
33
|
|
|
31
34
|
Out of scope:
|
|
@@ -40,7 +43,26 @@ Out of scope:
|
|
|
40
43
|
- All runtime dependencies are pinned to exact versions (`save-exact=true`).
|
|
41
44
|
- `ignore-scripts=true` in `.npmrc` to disable arbitrary postinstall scripts.
|
|
42
45
|
- CI runs `npm audit --audit-level=high` on every PR.
|
|
46
|
+
- CI lints the source, runs tests across Linux, macOS, Windows, and supported
|
|
47
|
+
Node.js versions, and verifies the committed Action bundle is reproducible.
|
|
43
48
|
- Releases are published with `npm publish --provenance`.
|
|
49
|
+
- The bundled Action runs on GitHub's managed Node.js runtime and does not
|
|
50
|
+
install dependencies in consumer workflows.
|
|
51
|
+
- Repository policy and baseline files should be protected with CODEOWNERS or
|
|
52
|
+
branch rules; changes to them can intentionally alter which findings fail CI.
|
|
53
|
+
- Parser failures are operational errors and cannot be suppressed by a finding
|
|
54
|
+
baseline.
|
|
55
|
+
- Organization scans read count- and size-bounded Git blobs in memory and never
|
|
56
|
+
clone, check out, or execute code from scanned repositories. Truncated trees,
|
|
57
|
+
exceeded limits, and unreadable blobs are operational errors.
|
|
58
|
+
- Organization checkpoints are opt-in, guarded atomic writes. They omit tokens
|
|
59
|
+
and raw workflow YAML, validate tool/rule/scope/policy identity, and reuse an
|
|
60
|
+
error-free result only after a fresh repository/default-branch tree-SHA
|
|
61
|
+
match. They still contain redacted repository and finding evidence and should
|
|
62
|
+
be protected like organization reports.
|
|
63
|
+
- Explicit CLI agent mode creates scope-keyed report and checkpoint files with
|
|
64
|
+
the same guarded writer and `0600` creation mode. Its stdout receipt contains
|
|
65
|
+
only paths and bounded counts; the artifact files remain sensitive.
|
|
44
66
|
|
|
45
67
|
## Responsible-disclosure timeline
|
|
46
68
|
|