actions-warden 0.3.0 → 0.4.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 +14 -4
- package/README.md +14 -2
- package/SECURITY.md +10 -5
- package/docs/AI-AGENTS.md +21 -5
- package/docs/CLI.md +76 -23
- package/docs/DEVELOPMENT.md +25 -2
- package/docs/GITHUB-ACTION.md +11 -7
- package/docs/JAVASCRIPT-API.md +7 -5
- package/docs/OUTPUTS.md +10 -5
- package/examples/upgrade-pr.yml +1 -1
- package/package.json +1 -1
- package/skills/actions-warden/SKILL.md +31 -22
- package/src/action.js +4 -15
- package/src/cli.js +314 -121
- package/src/commands/org-scan.js +6 -11
- package/src/lib/agent-mode.js +5 -6
- package/src/lib/org-checkpoint.js +90 -7
- package/src/lib/path-equality.js +30 -0
- package/src/lib/writer.js +3 -0
- package/src/version.js +1 -1
package/AGENTS.md
CHANGED
|
@@ -58,10 +58,11 @@ actions-warden org-scan ORG --agent-mode
|
|
|
58
58
|
checkpoint. It emits only a bounded JSON receipt to stdout. The packaged
|
|
59
59
|
skill should pass the flag; an integration may instead set
|
|
60
60
|
`ACTIONS_WARDEN_MODE=agent` once.
|
|
61
|
-
- Automatic artifact names are derived from the
|
|
62
|
-
An exact-scope later run resumes its checkpoint
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
- Automatic artifact names are derived from the checkpoint compatibility
|
|
62
|
+
identity. An exact-scope later run resumes its checkpoint across compatible
|
|
63
|
+
package versions; a changed filter, severity, policy, baseline, analysis
|
|
64
|
+
generation, or rule catalog receives a different path. Compatibility
|
|
65
|
+
validation still fails closed.
|
|
65
66
|
- Preserve the scope the user requested. Reducing LLM context use is not
|
|
66
67
|
permission to omit repositories, severities, findings, or errors.
|
|
67
68
|
- Explicit CLI choices override agent defaults. If the user asks to watch live
|
|
@@ -112,8 +113,13 @@ deprecating a package. A release request does not authorize those actions.
|
|
|
112
113
|
## Non-negotiable invariants
|
|
113
114
|
|
|
114
115
|
- `pin` and `upgrade` are dry-run by default.
|
|
116
|
+
- CLI usage errors return `2`; numeric limits and change IDs are parsed
|
|
117
|
+
strictly, and contradictory flags fail before command work begins.
|
|
115
118
|
- Writes remain within the real repository root, reject symlink escapes, are
|
|
116
119
|
atomic, preserve permissions, and reparse modified YAML.
|
|
120
|
+
- CLI report, baseline, and checkpoint destinations are preflighted before
|
|
121
|
+
network or workflow mutation and cannot replace workflow or policy-control
|
|
122
|
+
files.
|
|
117
123
|
- GitHub ref resolution and commit ownership fail closed.
|
|
118
124
|
- Credentials are redacted in every format, annotation, and top-level error.
|
|
119
125
|
- Finding IDs are clone-independent; pin findings and plans share an ID.
|
|
@@ -123,6 +129,10 @@ deprecating a package. A release request does not authorize those actions.
|
|
|
123
129
|
- Organization resume requires fresh discovery and matching default-branch tree
|
|
124
130
|
SHAs; never reuse failed results. Checkpoints remain guarded, atomic, and free
|
|
125
131
|
of tokens or raw YAML.
|
|
132
|
+
- `ORGANIZATION_ANALYSIS_GENERATION` is the organization-result compatibility
|
|
133
|
+
boundary. Increment it whenever discovery, parser, finding identity, rule
|
|
134
|
+
evaluation, or persisted result semantics can change; do not increment it
|
|
135
|
+
for a version-only compatible release.
|
|
126
136
|
- CLI progress stays on stderr and never corrupts structured report stdout.
|
|
127
137
|
- Attacker-controlled text cannot forge output records or workflow commands.
|
|
128
138
|
|
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ actions-warden verify
|
|
|
57
57
|
For a one-off run without a global install:
|
|
58
58
|
|
|
59
59
|
```sh
|
|
60
|
-
npx --yes actions-warden@0.
|
|
60
|
+
npx --yes actions-warden@0.4.0 audit --explain
|
|
61
61
|
```
|
|
62
62
|
|
|
63
63
|
`audit` returns exit code `1` when it finds issues. That is a completed scan,
|
|
@@ -109,6 +109,12 @@ reused; changed and previously failed repositories are scanned again. Progress
|
|
|
109
109
|
defaults to interactive terminals; use `--progress=always` for redirected logs
|
|
110
110
|
or `--progress=never` to disable it.
|
|
111
111
|
|
|
112
|
+
Compatible package upgrades reuse the same checkpoint. The producing package
|
|
113
|
+
version is recorded as metadata, while an explicit analysis generation plus
|
|
114
|
+
the rule catalog controls compatibility. A parser, discovery, or rule behavior
|
|
115
|
+
change advances that generation and requires a fresh scan. Compatible older
|
|
116
|
+
checkpoints are rewritten atomically on their first successful resume.
|
|
117
|
+
|
|
112
118
|
When a coding agent initiates the scan, use the explicit bounded mode:
|
|
113
119
|
|
|
114
120
|
```sh
|
|
@@ -150,8 +156,14 @@ audit/report/pin/upgrade plan → review IDs and diffs → --fix=<id> --write
|
|
|
150
156
|
- `pin` and `upgrade` are dry-runs unless `--write` is present.
|
|
151
157
|
- `--write --dry-run` is rejected instead of guessing intent.
|
|
152
158
|
- `--fix=<id>` limits a pin or upgrade to one exact source occurrence.
|
|
159
|
+
- Numeric limits and change IDs are parsed strictly; partial, fractional, and
|
|
160
|
+
imprecise values fail before network or write work begins.
|
|
153
161
|
- Rewrites preserve surrounding YAML and are reparsed before an atomic write.
|
|
154
|
-
-
|
|
162
|
+
- `--output-path` implies file output; contradictory or incomplete output flags
|
|
163
|
+
are rejected before a scan or authorized mutation begins.
|
|
164
|
+
- Paths, output files, and symlinks are constrained to the selected repository,
|
|
165
|
+
and report/baseline/checkpoint destinations cannot replace workflows or
|
|
166
|
+
policy controls.
|
|
155
167
|
- Credential-like values are recursively redacted from every output format.
|
|
156
168
|
- Repository policy is strictly validated; unknown keys and rule IDs fail.
|
|
157
169
|
- Remote organization source is kept in memory and is not persisted in cache.
|
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 --yes actions-warden@0.
|
|
15
|
+
- The version of `actions-warden` (`npx --yes actions-warden@0.4.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
|
|
@@ -50,16 +50,21 @@ Out of scope:
|
|
|
50
50
|
install dependencies in consumer workflows.
|
|
51
51
|
- Repository policy and baseline files should be protected with CODEOWNERS or
|
|
52
52
|
branch rules; changes to them can intentionally alter which findings fail CI.
|
|
53
|
+
- CLI report, baseline, and checkpoint destinations are guarded and preflighted;
|
|
54
|
+
they cannot replace selected/default-discovery workflows or reserved policy
|
|
55
|
+
paths, and active control-file collisions are rejected before output writes.
|
|
53
56
|
- Parser failures are operational errors and cannot be suppressed by a finding
|
|
54
57
|
baseline.
|
|
55
58
|
- Organization scans read count- and size-bounded Git blobs in memory and never
|
|
56
59
|
clone, check out, or execute code from scanned repositories. Truncated trees,
|
|
57
60
|
exceeded limits, and unreadable blobs are operational errors.
|
|
58
61
|
- Organization checkpoints are opt-in, guarded atomic writes. They omit tokens
|
|
59
|
-
and raw workflow YAML, validate
|
|
60
|
-
error-free result only after a fresh
|
|
61
|
-
match.
|
|
62
|
-
|
|
62
|
+
and raw workflow YAML, validate analysis-generation/rule/scope/policy
|
|
63
|
+
identity, and reuse an error-free result only after a fresh
|
|
64
|
+
repository/default-branch tree-SHA match. The producing package version is
|
|
65
|
+
metadata rather than a compatibility boundary. They still contain redacted
|
|
66
|
+
repository and finding evidence and should be protected like organization
|
|
67
|
+
reports.
|
|
63
68
|
- Explicit CLI agent mode creates scope-keyed report and checkpoint files with
|
|
64
69
|
the same guarded writer and `0600` creation mode. Its stdout receipt contains
|
|
65
70
|
only paths and bounded counts; the artifact files remain sensitive.
|
package/docs/AI-AGENTS.md
CHANGED
|
@@ -88,6 +88,15 @@ found something. Parse and present the report.
|
|
|
88
88
|
|
|
89
89
|
Exit code `2` is an invocation-level problem. Read stderr, do not assume stdout
|
|
90
90
|
contains valid JSON, and do not retry by weakening policy or changing paths.
|
|
91
|
+
Unknown options, conflicting flags, malformed numeric values, invalid change
|
|
92
|
+
IDs, unsafe destinations, and a missing command all use this exit code. These
|
|
93
|
+
checks happen before network requests or authorized workflow mutations whenever
|
|
94
|
+
the required path information is available.
|
|
95
|
+
|
|
96
|
+
When saving a report, `--output-path=<path>` is sufficient and implies file
|
|
97
|
+
output. Do not combine it with explicit `--output=stdout`. Create the parent
|
|
98
|
+
directory first, and never select a workflow, policy, baseline, or checkpoint
|
|
99
|
+
path as the report destination.
|
|
91
100
|
|
|
92
101
|
For an organization scan, report coverage before findings:
|
|
93
102
|
|
|
@@ -260,19 +269,26 @@ Agent mode is an explicit contract, not heuristic detection. By default it:
|
|
|
260
269
|
- selects JSON and writes the full report to a guarded hidden file;
|
|
261
270
|
- disables progress;
|
|
262
271
|
- creates a guarded hidden checkpoint on the first run;
|
|
263
|
-
- resumes that checkpoint on a later run with the
|
|
264
|
-
|
|
272
|
+
- resumes that checkpoint on a later run with the same compatibility identity,
|
|
273
|
+
including across package-version-only upgrades;
|
|
265
274
|
- emits only a bounded JSON receipt containing status, coverage summary,
|
|
266
275
|
report path, report format, checkpoint path, and whether resume was used.
|
|
267
276
|
|
|
268
277
|
The automatic artifact key covers the organization, repository filters,
|
|
269
278
|
inclusion flags, repository limit, severity, explanation setting, normalized
|
|
270
|
-
policy, baseline contents,
|
|
271
|
-
|
|
272
|
-
|
|
279
|
+
policy, baseline contents, analysis generation, and rule catalog. A compatible
|
|
280
|
+
package upgrade keeps the same path and atomically migrates older checkpoint
|
|
281
|
+
metadata on the first successful resume. A changed scope, security control, or
|
|
282
|
+
analysis behavior receives a different path instead of replacing an
|
|
283
|
+
incompatible checkpoint.
|
|
284
|
+
The generated files begin
|
|
273
285
|
`.actions-warden-agent.`; protect them as sensitive report artifacts and add
|
|
274
286
|
that pattern to the consuming repository's ignore rules when appropriate.
|
|
275
287
|
|
|
288
|
+
Version-only upgrades do not accumulate new automatic artifacts. A deliberate
|
|
289
|
+
analysis-generation change does retain the older keyed files as audit evidence;
|
|
290
|
+
remove them only under the consuming repository's retention policy.
|
|
291
|
+
|
|
276
292
|
Explicit CLI options take precedence over agent defaults. Use
|
|
277
293
|
`--progress=always` when the user requests live progress. Use
|
|
278
294
|
`--output=stdout` only when the caller intentionally wants the complete report
|
package/docs/CLI.md
CHANGED
|
@@ -21,7 +21,7 @@ actions-warden --version
|
|
|
21
21
|
For reproducible one-off automation, invoke an exact package version:
|
|
22
22
|
|
|
23
23
|
```sh
|
|
24
|
-
npx --yes actions-warden@0.
|
|
24
|
+
npx --yes actions-warden@0.4.0 audit
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
Network-backed commands resolve credentials in this order:
|
|
@@ -38,16 +38,20 @@ metadata and contents read access needed for the requested scope.
|
|
|
38
38
|
## Target and output options
|
|
39
39
|
|
|
40
40
|
The repository commands (`audit`, `pin`, `verify`, `upgrade`, and `report`)
|
|
41
|
-
share these options:
|
|
41
|
+
share these target and output options:
|
|
42
42
|
|
|
43
43
|
| option | default | behavior |
|
|
44
44
|
|---|---|---|
|
|
45
45
|
| `-w, --workflow <pattern...>` | discovery | One or more files, directories, or globs |
|
|
46
46
|
| `--cwd <dir>` | current directory | Repository and path-safety root |
|
|
47
|
-
| `--token <token>` | environment | GitHub API credential for network-backed work |
|
|
48
47
|
| `--format <format>` | `toon` | `toon`, `json`, `text`, or `sarif` |
|
|
49
48
|
| `--output <destination>` | `stdout` | `stdout` or `file` |
|
|
50
|
-
| `--output-path <path>` | none |
|
|
49
|
+
| `--output-path <path>` | none | Report path inside `--cwd`; implies `--output=file` |
|
|
50
|
+
|
|
51
|
+
`pin`, `verify`, `upgrade`, and online `report` also accept `--token`. `audit`
|
|
52
|
+
is entirely local and does not accept a token. `report --offline` rejects an
|
|
53
|
+
explicit token, mode, or cooldown because those options would otherwise be
|
|
54
|
+
silently unused.
|
|
51
55
|
|
|
52
56
|
Without `--workflow`, actions-warden discovers:
|
|
53
57
|
|
|
@@ -72,19 +76,28 @@ actions-warden audit --cwd ../service
|
|
|
72
76
|
```
|
|
73
77
|
|
|
74
78
|
Output files are created atomically and must remain within the real working
|
|
75
|
-
directory after symlinks are resolved
|
|
79
|
+
directory after symlinks are resolved. Their parent directory must already
|
|
80
|
+
exist. `--output=file` without a path and an explicit
|
|
81
|
+
`--output=stdout --output-path=...` are invocation errors. Report, baseline,
|
|
82
|
+
and checkpoint destinations are preflighted before network or mutation work;
|
|
83
|
+
they cannot be directories, symlinks, selected workflows, default workflow
|
|
84
|
+
discovery paths, or the reserved `.actions-warden.yml` and
|
|
85
|
+
`.actions-warden.yaml` policy paths. Active configuration and baseline paths
|
|
86
|
+
are checked again before any report or baseline destination is written.
|
|
76
87
|
|
|
77
88
|
```sh
|
|
78
89
|
actions-warden audit \
|
|
79
90
|
--format=sarif \
|
|
80
|
-
--output=file \
|
|
81
91
|
--output-path=reports/actions-warden.sarif
|
|
82
92
|
```
|
|
83
93
|
|
|
94
|
+
`--output=file --output-path=...` remains valid when an explicit destination
|
|
95
|
+
is clearer in automation.
|
|
96
|
+
|
|
84
97
|
## `audit`
|
|
85
98
|
|
|
86
99
|
Scan local workflows and composite actions without making network calls or
|
|
87
|
-
changing
|
|
100
|
+
changing workflows. It writes only an explicitly requested report or baseline.
|
|
88
101
|
|
|
89
102
|
```sh
|
|
90
103
|
actions-warden audit \
|
|
@@ -105,8 +118,10 @@ actions-warden audit \
|
|
|
105
118
|
--create-baseline=.actions-warden-baseline.json
|
|
106
119
|
```
|
|
107
120
|
|
|
108
|
-
`--create-baseline` cannot be combined with `--baseline
|
|
109
|
-
|
|
121
|
+
`--create-baseline` cannot be combined with `--baseline`, cannot share the
|
|
122
|
+
report output path, and is validated before the audit begins. Parser failures
|
|
123
|
+
are never written into the baseline. See
|
|
124
|
+
[configuration and baselines](./CONFIGURATION.md).
|
|
110
125
|
|
|
111
126
|
Exit code `0` means no unsuppressed findings; `1` means findings were reported;
|
|
112
127
|
`2` means the scan could not be invoked safely or correctly.
|
|
@@ -141,7 +156,9 @@ or one exact stable ID:
|
|
|
141
156
|
actions-warden pin --fix=18b82e86d7c14fe2 --write
|
|
142
157
|
```
|
|
143
158
|
|
|
144
|
-
`--write` and `--dry-run` together are rejected.
|
|
159
|
+
`--write` and `--dry-run` together are rejected. `--fix` must be one exact
|
|
160
|
+
16-character hexadecimal ID from a current plan; uppercase input is normalized
|
|
161
|
+
for convenience.
|
|
145
162
|
|
|
146
163
|
## `verify`
|
|
147
164
|
|
|
@@ -176,7 +193,9 @@ Defaults are `--mode=minor --min-age=7` and dry-run. Tag discovery is paginated;
|
|
|
176
193
|
prereleases and downgrades are excluded. A candidate tag must be older than the
|
|
177
194
|
cooldown. The age comes from GitHub release publication data when available,
|
|
178
195
|
then from locally recorded first-seen evidence for the exact tag-to-SHA mapping.
|
|
179
|
-
Missing evidence fails closed.
|
|
196
|
+
Missing evidence fails closed. `--min-age` accepts only a non-negative integer;
|
|
197
|
+
values such as `7days`, `1.5`, and values outside JavaScript's safe integer
|
|
198
|
+
range are rejected rather than truncated.
|
|
180
199
|
|
|
181
200
|
SHA-pinned references need `actions-warden-ref` metadata to establish the
|
|
182
201
|
current semantic version. Legacy plain-semver comments remain readable.
|
|
@@ -207,7 +226,8 @@ actions-warden report \
|
|
|
207
226
|
The audit determines the target set; pin and upgrade use exactly that same
|
|
208
227
|
scope. A location with an upgrade is not duplicated as a pin proposal.
|
|
209
228
|
`--offline` skips both network-backed planning phases and returns only the
|
|
210
|
-
local audit.
|
|
229
|
+
local audit. Because they cannot affect an offline report, explicitly combining
|
|
230
|
+
`--offline` with `--token`, `--mode`, or `--min-age` is rejected.
|
|
211
231
|
|
|
212
232
|
Use report for review, issue generation, or an AI planning step. It never
|
|
213
233
|
accepts `--write`.
|
|
@@ -244,7 +264,9 @@ Defaults:
|
|
|
244
264
|
|
|
245
265
|
Repository patterns match either `name` or `owner/name`, case-insensitively.
|
|
246
266
|
An explicit pattern set that matches no eligible repository is an error.
|
|
247
|
-
Selection is stable before `--max-repos` is applied.
|
|
267
|
+
Selection is stable before `--max-repos` is applied. `--max-repos` must be a
|
|
268
|
+
positive safe integer, and `--concurrency` must be an integer from 1 through
|
|
269
|
+
16; malformed, fractional, or imprecise values fail before any API request.
|
|
248
270
|
|
|
249
271
|
```sh
|
|
250
272
|
actions-warden org-scan my-org \
|
|
@@ -287,8 +309,9 @@ When the corresponding options were not explicitly supplied, agent mode sets:
|
|
|
287
309
|
|
|
288
310
|
The artifact key includes the organization, repository filters, inclusion
|
|
289
311
|
flags, repository limit, severity, explanation setting, normalized policy,
|
|
290
|
-
baseline contents,
|
|
291
|
-
|
|
312
|
+
baseline contents, analysis generation, and rule catalog. A compatible package
|
|
313
|
+
upgrade therefore keeps the same paths, while a scope, security-control, or
|
|
314
|
+
analysis-behavior change selects a different checkpoint rather than
|
|
292
315
|
overwriting incompatible state. Generated paths have these shapes:
|
|
293
316
|
|
|
294
317
|
```text
|
|
@@ -321,7 +344,8 @@ an invocation error. Explicit `--format`, `--output`, `--output-path`,
|
|
|
321
344
|
`--progress`, `--checkpoint`, and `--resume` choices override agent defaults.
|
|
322
345
|
With explicit `--output=stdout`, stdout is the complete selected report and no
|
|
323
346
|
receipt is added. Use `--no-agent-mode` to override an inherited environment
|
|
324
|
-
marker.
|
|
347
|
+
marker. Passing both agent-mode flags is rejected. `ACTIONS_WARDEN_MODE` must
|
|
348
|
+
be exactly `agent` when set.
|
|
325
349
|
|
|
326
350
|
### Progress and resume
|
|
327
351
|
|
|
@@ -345,8 +369,8 @@ actions-warden org-scan my-org \
|
|
|
345
369
|
```
|
|
346
370
|
|
|
347
371
|
Resume with the same organization, filters, inclusion flags, repository limit,
|
|
348
|
-
severity, explanation setting, configuration, baseline,
|
|
349
|
-
catalog:
|
|
372
|
+
severity, explanation setting, configuration, baseline, analysis generation,
|
|
373
|
+
and rule catalog:
|
|
350
374
|
|
|
351
375
|
```sh
|
|
352
376
|
actions-warden org-scan my-org \
|
|
@@ -358,11 +382,18 @@ actions-warden org-scan my-org \
|
|
|
358
382
|
```
|
|
359
383
|
|
|
360
384
|
The token, concurrency, output format, progress mode, and report destination do
|
|
361
|
-
not affect checkpoint compatibility.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
385
|
+
not affect checkpoint compatibility. Neither does a package-version-only
|
|
386
|
+
upgrade: the producing version is retained as checkpoint metadata, and a
|
|
387
|
+
compatible older checkpoint is rewritten atomically on its first successful
|
|
388
|
+
resume. The
|
|
389
|
+
explicit analysis generation is advanced when discovery, parsing, finding
|
|
390
|
+
identity, rule evaluation, or persisted result behavior changes. An
|
|
391
|
+
incompatible generation fails closed; automatic agent mode selects a new keyed
|
|
392
|
+
path. A resumed scan always lists repositories again and fetches a fresh
|
|
393
|
+
default-branch tree for each selected repository. An error-free result is
|
|
394
|
+
reused only when repository identity, default branch, and tree SHA still match.
|
|
395
|
+
Changed repositories and any checkpointed result with an operational error are
|
|
396
|
+
scanned again.
|
|
366
397
|
|
|
367
398
|
`--checkpoint` starts a new checkpoint and replaces an existing file at that
|
|
368
399
|
path. `--resume` requires a valid existing checkpoint and updates it. The
|
|
@@ -373,6 +404,11 @@ not the token or raw YAML, but can still reveal private repository names,
|
|
|
373
404
|
paths, findings, and security posture; protect and retain them accordingly.
|
|
374
405
|
Checkpoint reads and writes are capped at 256 MiB.
|
|
375
406
|
|
|
407
|
+
Version-only upgrades no longer create extra agent artifacts. When an analysis
|
|
408
|
+
generation intentionally changes, the older keyed report and checkpoint are
|
|
409
|
+
retained rather than deleted automatically because they may be needed as audit
|
|
410
|
+
evidence; remove them according to the consuming repository's retention policy.
|
|
411
|
+
|
|
376
412
|
The scanner reads the default-branch Git tree and YAML blobs in memory. It
|
|
377
413
|
never clones, checks out, or executes remote content. It fails closed on
|
|
378
414
|
truncated trees and enforces these bounds per repository:
|
|
@@ -398,6 +434,23 @@ actions-warden rules --format=json
|
|
|
398
434
|
|
|
399
435
|
This command has no repository or network dependency.
|
|
400
436
|
|
|
437
|
+
## Exit status and invocation errors
|
|
438
|
+
|
|
439
|
+
Every command uses the same process contract:
|
|
440
|
+
|
|
441
|
+
- `0`: completed with status `OK`, or displayed help/version information;
|
|
442
|
+
- `1`: completed with a structured `FAIL` result, such as findings or
|
|
443
|
+
operational errors;
|
|
444
|
+
- `2`: could not start or complete safely because the command line, paths,
|
|
445
|
+
configuration, inputs, or environment were invalid.
|
|
446
|
+
|
|
447
|
+
Commander-level failures such as unknown flags, missing values, invalid
|
|
448
|
+
choices, conflicts, excess arguments, and a missing command also return `2`.
|
|
449
|
+
Argument parsing and destination preflight run before network requests and
|
|
450
|
+
before authorized workflow writes; active-control collisions are checked again
|
|
451
|
+
before output. On exit `2`, treat stderr as the error channel and do not assume
|
|
452
|
+
stdout contains a complete structured result.
|
|
453
|
+
|
|
401
454
|
## Cache and network behavior
|
|
402
455
|
|
|
403
456
|
Local `pin`, `verify`, `upgrade`, and online `report` work caches successful
|
package/docs/DEVELOPMENT.md
CHANGED
|
@@ -81,6 +81,7 @@ src/
|
|
|
81
81
|
lib/
|
|
82
82
|
parser.js YAML-to-normalized-workflow model
|
|
83
83
|
targets.js, paths.js repository target discovery
|
|
84
|
+
path-equality.js real-path destination/control comparisons
|
|
84
85
|
config.js, baseline.js policy and accepted-finding controls
|
|
85
86
|
resolver.js, cache.js GitHub API, caching, ref and ownership checks
|
|
86
87
|
github-org.js read-only organization/tree/blob access
|
|
@@ -139,11 +140,17 @@ Changes must preserve these boundaries:
|
|
|
139
140
|
|
|
140
141
|
- `pin` and `upgrade` default to dry-run at the command and API layers.
|
|
141
142
|
- CLI and Action mutation require an explicit write option.
|
|
143
|
+
- CLI integers and 16-hex change IDs use strict whole-value parsing. Commander
|
|
144
|
+
usage failures and application-level invocation failures both exit `2`.
|
|
142
145
|
- A resolver failure must not fall back to a guessed tag or SHA.
|
|
143
146
|
- Commits must be verified as belonging to the referenced repository.
|
|
144
147
|
- Workflow rewrites operate on parsed scalar ranges and reparse before write.
|
|
145
148
|
- Writes and configured paths remain inside the real repository root.
|
|
146
149
|
- Symlink escapes and explicit targets that match nothing fail.
|
|
150
|
+
- CLI report, baseline, and checkpoint destinations are preflighted before
|
|
151
|
+
network or workflow mutation, cannot replace selected/default-discovery
|
|
152
|
+
workflows or reserved policy paths, and are checked against active controls
|
|
153
|
+
again before output is written.
|
|
147
154
|
- Credentials are redacted in JSON, TOON, text, SARIF, annotations, and
|
|
148
155
|
top-level errors.
|
|
149
156
|
- Finding and change IDs exclude absolute checkout paths.
|
|
@@ -154,14 +161,19 @@ Changes must preserve these boundaries:
|
|
|
154
161
|
- Organization resume never trusts a stale result without fresh discovery and
|
|
155
162
|
a matching repository identity, default branch, and tree SHA. Failed results
|
|
156
163
|
are never reused.
|
|
164
|
+
- Organization result compatibility is controlled by
|
|
165
|
+
`ORGANIZATION_ANALYSIS_GENERATION`, not by the package version. Producer
|
|
166
|
+
versions remain checkpoint metadata and compatible checkpoints migrate
|
|
167
|
+
through the guarded atomic writer.
|
|
157
168
|
- Checkpoints use guarded atomic writes, remain inside the working directory,
|
|
158
169
|
omit tokens and raw YAML, and cannot replace active policy or baseline files.
|
|
159
170
|
- Progress stays outside deterministic report serialization; CLI progress is
|
|
160
171
|
stderr-only and Action progress cannot form workflow commands.
|
|
161
172
|
- Agent mode is an explicit opt-in, never a TTY, parent-process, CI, or
|
|
162
173
|
vendor-environment heuristic. Explicit CLI output and progress options win.
|
|
163
|
-
Its automatic artifact key uses the validated checkpoint
|
|
164
|
-
stdout receipt never includes findings or repository result
|
|
174
|
+
Its automatic artifact key uses the validated checkpoint compatibility
|
|
175
|
+
identity, and its stdout receipt never includes findings or repository result
|
|
176
|
+
arrays.
|
|
165
177
|
- Attacker-controlled values cannot forge TOON lines or GitHub annotations.
|
|
166
178
|
|
|
167
179
|
Tests should demonstrate the fail-closed behavior for any change touching these
|
|
@@ -276,6 +288,17 @@ previous repository errors, output equivalence, and concurrent completions.
|
|
|
276
288
|
Persist each completed result before emitting its completion event so an
|
|
277
289
|
observer failure or process interruption loses at most in-flight work.
|
|
278
290
|
|
|
291
|
+
`ORGANIZATION_ANALYSIS_GENERATION` in `src/lib/org-checkpoint.js` is the manual
|
|
292
|
+
semantic compatibility switch. Increment it whenever organization workflow
|
|
293
|
+
selection, parsing, finding identity, rule evaluation, suppression, summaries,
|
|
294
|
+
or other persisted repository-result semantics can change. Keep it unchanged
|
|
295
|
+
for documentation, release metadata, progress rendering, authentication,
|
|
296
|
+
concurrency, or internal refactors that preserve those results. The rule
|
|
297
|
+
catalog hash independently invalidates catalog changes. A generation change
|
|
298
|
+
must add tests proving the old checkpoint fails closed and agent mode selects a
|
|
299
|
+
new artifact key; a compatible format migration must prove the old checkpoint
|
|
300
|
+
is validated, rewritten atomically, and still subject to fresh tree checks.
|
|
301
|
+
|
|
279
302
|
## Output compatibility
|
|
280
303
|
|
|
281
304
|
JSON is the public machine interface. Raw command results and serialized JSON
|
package/docs/GITHUB-ACTION.md
CHANGED
|
@@ -182,7 +182,9 @@ emission.
|
|
|
182
182
|
if-no-files-found: error
|
|
183
183
|
```
|
|
184
184
|
|
|
185
|
-
The output path must remain inside `working-directory
|
|
185
|
+
The output path must remain inside `working-directory`, its parent directory
|
|
186
|
+
must already exist, and an existing destination must be a regular file rather
|
|
187
|
+
than a directory or symlink.
|
|
186
188
|
|
|
187
189
|
## Organization report
|
|
188
190
|
|
|
@@ -249,12 +251,14 @@ those inputs directly when an agent generates a workflow.
|
|
|
249
251
|
the working directory before the actions-warden step, remove
|
|
250
252
|
`checkpoint-path`, and set `resume-from` to the restored path. The Action does
|
|
251
253
|
not itself retain files between ephemeral runners; use a protected artifact or
|
|
252
|
-
other caller-managed storage. Scope, policy, baseline,
|
|
253
|
-
identity must match
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
254
|
+
other caller-managed storage. Scope, policy, baseline, analysis generation, and
|
|
255
|
+
rule identity must match; a compatible package-version change is allowed and
|
|
256
|
+
atomically refreshes checkpoint metadata on the first successful resume. Fresh
|
|
257
|
+
repository discovery and tree checks still occur, and changed or previously
|
|
258
|
+
failed repositories are rescanned. Checkpoints hold redacted report evidence
|
|
259
|
+
about repositories and findings, so protect them like the organization report.
|
|
260
|
+
`checkpoint-path` and `resume-from` are mutually exclusive and cannot equal
|
|
261
|
+
`output-path`.
|
|
258
262
|
|
|
259
263
|
## Mutation workflows
|
|
260
264
|
|
package/docs/JAVASCRIPT-API.md
CHANGED
|
@@ -205,11 +205,13 @@ possible; failures that prevent organization discovery throw.
|
|
|
205
205
|
`checkpointPath` explicitly enables atomic checkpoint writes inside `cwd`.
|
|
206
206
|
Set `resume: true` to require, validate, and update an existing checkpoint at
|
|
207
207
|
that path. The organization, selection and audit options, normalized policy,
|
|
208
|
-
baseline contents,
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
208
|
+
baseline contents, analysis generation, and rule catalog must match.
|
|
209
|
+
Concurrency, token, and compatible package-version changes are allowed. The
|
|
210
|
+
producing package version remains metadata, and compatible older checkpoints
|
|
211
|
+
are atomically migrated on the first successful resume. Resume performs fresh
|
|
212
|
+
discovery and tree reads; it reuses only error-free results whose repository,
|
|
213
|
+
default branch, and tree SHA remain unchanged. Checkpoints contain redacted
|
|
214
|
+
report data and revision metadata, never tokens or raw YAML.
|
|
213
215
|
|
|
214
216
|
`onProgress` may be synchronous or asynchronous and is awaited in event order
|
|
215
217
|
at each emission point. A callback error rejects the scan; repository results
|
package/docs/OUTPUTS.md
CHANGED
|
@@ -47,8 +47,10 @@ The CLI maps results to process codes:
|
|
|
47
47
|
| `1` | Semantic status `FAIL`; inspect the emitted report |
|
|
48
48
|
| `2` | Invalid arguments, invalid policy, unsafe paths, or another invocation-level failure |
|
|
49
49
|
|
|
50
|
-
An invocation-level failure is written to stderr as `error: <message>`.
|
|
51
|
-
|
|
50
|
+
An invocation-level failure is written to stderr as `error: <message>`. Unknown
|
|
51
|
+
options, missing values, invalid choices, conflicting flags, malformed numeric
|
|
52
|
+
values, unsafe destinations, and a missing command all return `2`. The failure
|
|
53
|
+
may occur before a structured payload can be rendered, so do not assume stdout
|
|
52
54
|
contains JSON when the process exits `2`.
|
|
53
55
|
|
|
54
56
|
Organization-scan live progress is also a stderr-only channel. It never becomes
|
|
@@ -119,16 +121,19 @@ node -e '
|
|
|
119
121
|
'
|
|
120
122
|
```
|
|
121
123
|
|
|
122
|
-
Writing reports through
|
|
123
|
-
repository path containment matters:
|
|
124
|
+
Writing reports through a guarded output path is safer than shell redirection
|
|
125
|
+
when repository path containment matters. `--output-path` implies file output:
|
|
124
126
|
|
|
125
127
|
```sh
|
|
126
128
|
actions-warden audit \
|
|
127
129
|
--format=json \
|
|
128
|
-
--output=file \
|
|
129
130
|
--output-path=reports/actions-warden.json
|
|
130
131
|
```
|
|
131
132
|
|
|
133
|
+
The parent directory must exist. Destination safety is checked before command
|
|
134
|
+
work, then active policy and baseline collisions are checked again before the
|
|
135
|
+
report is written. Explicit `--output=stdout --output-path=...` is rejected.
|
|
136
|
+
|
|
132
137
|
## TOON
|
|
133
138
|
|
|
134
139
|
TOON is Token-Oriented Object Notation. Each line is:
|
package/examples/upgrade-pr.yml
CHANGED
|
@@ -26,7 +26,7 @@ jobs:
|
|
|
26
26
|
- name: Apply eligible upgrades
|
|
27
27
|
env:
|
|
28
28
|
GITHUB_TOKEN: ${{ github.token }}
|
|
29
|
-
run: npx --yes actions-warden@0.
|
|
29
|
+
run: npx --yes actions-warden@0.4.0 upgrade --mode=minor --min-age=7 --write
|
|
30
30
|
|
|
31
31
|
- name: Open or update pull request
|
|
32
32
|
env:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "actions-warden",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Audit GitHub Actions across repositories and organizations; pin, verify, and upgrade dependencies.",
|
|
5
5
|
"author": "Naveen Yagati",
|
|
6
6
|
"homepage": "https://github.com/chiz0me/actions-warden#readme",
|
|
@@ -33,27 +33,31 @@ Invoke `actions-warden` when the user:
|
|
|
33
33
|
The package is on npm as `actions-warden`. Invoke the reviewed version exactly:
|
|
34
34
|
|
|
35
35
|
```sh
|
|
36
|
-
npx --yes actions-warden@0.
|
|
37
|
-
npx --yes actions-warden@0.
|
|
38
|
-
npx --yes actions-warden@0.
|
|
39
|
-
npx --yes actions-warden@0.
|
|
40
|
-
npx --yes actions-warden@0.
|
|
41
|
-
npx --yes actions-warden@0.
|
|
42
|
-
npx --yes actions-warden@0.
|
|
43
|
-
npx --yes actions-warden@0.
|
|
44
|
-
npx --yes actions-warden@0.
|
|
45
|
-
npx --yes actions-warden@0.
|
|
46
|
-
npx --yes actions-warden@0.
|
|
47
|
-
npx --yes actions-warden@0.
|
|
48
|
-
npx --yes actions-warden@0.
|
|
49
|
-
npx --yes actions-warden@0.
|
|
50
|
-
npx --yes actions-warden@0.
|
|
51
|
-
npx --yes actions-warden@0.
|
|
36
|
+
npx --yes actions-warden@0.4.0 audit
|
|
37
|
+
npx --yes actions-warden@0.4.0 audit --severity=high --explain
|
|
38
|
+
npx --yes actions-warden@0.4.0 audit --create-baseline=.actions-warden-baseline.json
|
|
39
|
+
npx --yes actions-warden@0.4.0 audit --baseline=.actions-warden-baseline.json
|
|
40
|
+
npx --yes actions-warden@0.4.0 audit --format=sarif
|
|
41
|
+
npx --yes actions-warden@0.4.0 pin
|
|
42
|
+
npx --yes actions-warden@0.4.0 pin --write
|
|
43
|
+
npx --yes actions-warden@0.4.0 upgrade --mode=minor
|
|
44
|
+
npx --yes actions-warden@0.4.0 upgrade --min-age=14 --write
|
|
45
|
+
npx --yes actions-warden@0.4.0 verify
|
|
46
|
+
npx --yes actions-warden@0.4.0 report --offline
|
|
47
|
+
npx --yes actions-warden@0.4.0 org-scan my-org --severity=high --format=json
|
|
48
|
+
npx --yes actions-warden@0.4.0 org-scan my-org --severity=high --agent-mode
|
|
49
|
+
npx --yes actions-warden@0.4.0 org-scan my-org --severity=high --checkpoint=.actions-warden-org-checkpoint.json
|
|
50
|
+
npx --yes actions-warden@0.4.0 org-scan my-org --severity=high --resume=.actions-warden-org-checkpoint.json
|
|
51
|
+
npx --yes actions-warden@0.4.0 rules
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Useful
|
|
55
|
-
`--format toon|json|text|sarif`, `--output stdout|file`,
|
|
56
|
-
`--
|
|
54
|
+
Useful shared command flags: `--workflow <path-or-glob>` (repeatable),
|
|
55
|
+
`--cwd <dir>`, `--format toon|json|text|sarif`, `--output stdout|file`, and
|
|
56
|
+
`--output-path <path>`. An output path implies file output; never combine it
|
|
57
|
+
with explicit `--output=stdout`, and create its parent directory first.
|
|
58
|
+
Network-backed commands accept `--token <gh-token>` and also read
|
|
59
|
+
`GITHUB_TOKEN` / `GH_TOKEN`; prefer the environment. Local `audit` does not
|
|
60
|
+
accept or need a token.
|
|
57
61
|
Audit, report, and org-scan also accept `--config <path>` and `--baseline <path>`.
|
|
58
62
|
`.actions-warden.yml` is loaded automatically when present.
|
|
59
63
|
Organization scans accept `--repository <glob...>`, `--visibility`,
|
|
@@ -69,7 +73,10 @@ precedence.
|
|
|
69
73
|
Exit codes: `0` for a normal `OK` result, `1` for a normal structured `FAIL`
|
|
70
74
|
result (findings or operational errors), and `2` for an invocation-level error.
|
|
71
75
|
For code `1`, inspect the report. For code `2`, read stderr and do not assume
|
|
72
|
-
stdout contains a complete structured payload.
|
|
76
|
+
stdout contains a complete structured payload. Do not retry code `2` by
|
|
77
|
+
guessing alternative flags: fix the named conflict, integer, ID, working
|
|
78
|
+
directory, or destination. The CLI rejects those errors before network or
|
|
79
|
+
authorized workflow mutation whenever the needed path information is known.
|
|
73
80
|
|
|
74
81
|
## What to do when invoked
|
|
75
82
|
|
|
@@ -124,7 +131,7 @@ stdout contains a complete structured payload.
|
|
|
124
131
|
agent-initiated broad scan must use the explicit agent mode:
|
|
125
132
|
|
|
126
133
|
```sh
|
|
127
|
-
npx --yes actions-warden@0.
|
|
134
|
+
npx --yes actions-warden@0.4.0 org-scan my-org \
|
|
128
135
|
--agent-mode
|
|
129
136
|
```
|
|
130
137
|
|
|
@@ -144,7 +151,9 @@ stdout contains a complete structured payload.
|
|
|
144
151
|
inference tokens to plan, monitor, and summarize; output admitted to its
|
|
145
152
|
context adds to that usage. Resume primarily saves GitHub API/blob work and
|
|
146
153
|
elapsed time. A changed scope or security control receives a different
|
|
147
|
-
artifact key rather than overwriting an incompatible checkpoint.
|
|
154
|
+
artifact key rather than overwriting an incompatible checkpoint. Compatible
|
|
155
|
+
package upgrades retain the same key and resume state; an analysis-behavior
|
|
156
|
+
change receives a new key.
|
|
148
157
|
|
|
149
158
|
## Audit rules
|
|
150
159
|
|