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/README.md
CHANGED
|
@@ -8,309 +8,357 @@
|
|
|
8
8
|
[](https://www.npmjs.com/package/actions-warden)
|
|
9
9
|
[](./LICENSE)
|
|
10
10
|
|
|
11
|
-
Audit
|
|
12
|
-
|
|
11
|
+
Audit GitHub Actions in one repository or across an entire organization, then
|
|
12
|
+
pin, verify, and safely upgrade workflow dependencies.
|
|
13
13
|
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
|
|
14
|
+
`actions-warden` is available as a CLI, a bundled GitHub Action, and a
|
|
15
|
+
JavaScript API. It finds supply-chain, permission, injection, artifact, secret,
|
|
16
|
+
container, reusable-workflow, and runner risks without executing the workflows
|
|
17
|
+
it inspects.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
update/pin core borrows its overall shape - YAML parsing plus regex-based
|
|
21
|
-
source rewrites that preserve formatting - and adds an audit layer, an
|
|
22
|
-
LLM-friendly TOON output format, inline ignore directives, an upgrade
|
|
23
|
-
cooldown, a Claude Code plugin, and a composite GitHub Action so the same
|
|
24
|
-
engine runs locally, in CI, and from inside Claude.
|
|
19
|
+
## Start here
|
|
25
20
|
|
|
26
|
-
|
|
21
|
+
| I want to… | Start with |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Check this repository | `actions-warden audit --explain` |
|
|
24
|
+
| See every proposed security and dependency change | `actions-warden report` |
|
|
25
|
+
| Scan a GitHub organization | `actions-warden org-scan ORG --format=json` |
|
|
26
|
+
| Pin mutable action refs | `actions-warden pin`, review, then add `--write` |
|
|
27
|
+
| Verify existing SHA pins | `actions-warden verify` |
|
|
28
|
+
| Upgrade pinned actions | `actions-warden upgrade`, review, then add `--write` |
|
|
29
|
+
| Run in GitHub Actions | [GitHub Action guide](./docs/GITHUB-ACTION.md) |
|
|
30
|
+
| Integrate from JavaScript | [JavaScript API](./docs/JAVASCRIPT-API.md) |
|
|
31
|
+
| Use it from a coding agent | [AI and agent guide](./docs/AI-AGENTS.md) |
|
|
32
|
+
| Contribute | [Contributing guide](./CONTRIBUTING.md) |
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
repo (or a stolen maintainer token) can rewrite `v3` to point at malicious code.
|
|
30
|
-
Pinning to a 40-character commit SHA closes that hole. `actions-warden` finds
|
|
31
|
-
the holes, plans the fix, and applies it - but never without your explicit
|
|
32
|
-
say-so. `--dry-run` is the default for every destructive command.
|
|
34
|
+
## Quick start
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
Node.js 20 or newer is required.
|
|
35
37
|
|
|
36
38
|
```sh
|
|
37
|
-
npm install
|
|
38
|
-
# or one-shot
|
|
39
|
-
npx actions-warden audit
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Requires Node.js 20 or newer.
|
|
43
|
-
|
|
44
|
-
## Quick start
|
|
39
|
+
npm install --global actions-warden
|
|
45
40
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
actions-warden audit
|
|
41
|
+
# Local and read-only
|
|
42
|
+
actions-warden audit --explain
|
|
49
43
|
|
|
50
|
-
#
|
|
51
|
-
actions-warden
|
|
44
|
+
# Network-backed, but still read-only
|
|
45
|
+
actions-warden report --format=json
|
|
52
46
|
|
|
53
|
-
#
|
|
47
|
+
# Preview pins; this does not change files
|
|
54
48
|
actions-warden pin
|
|
55
49
|
|
|
56
|
-
#
|
|
50
|
+
# Apply the reviewed pin plan
|
|
57
51
|
actions-warden pin --write
|
|
58
52
|
|
|
59
|
-
#
|
|
60
|
-
actions-warden
|
|
61
|
-
|
|
62
|
-
# Get one combined LLM-friendly report
|
|
63
|
-
actions-warden report --format=toon
|
|
53
|
+
# Confirm the pins against GitHub
|
|
54
|
+
actions-warden verify
|
|
64
55
|
```
|
|
65
56
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
### TOON (default - `--format=toon`)
|
|
57
|
+
For a one-off run without a global install:
|
|
69
58
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
`STATUS:` trailer.
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
SCAN: file=.github/workflows/release.yml
|
|
76
|
-
FINDING: id=18b82e86d7 type=unpinned-action sev=high action=actions/checkout@v3 line=15
|
|
77
|
-
FINDING: id=b50d0d45ab type=secrets-in-env sev=critical key=AWS_SECRET line=4
|
|
78
|
-
SUMMARY: files=1 findings=2 critical=1 high=1 medium=0 low=0
|
|
79
|
-
STATUS: FAIL
|
|
59
|
+
```sh
|
|
60
|
+
npx --yes actions-warden@0.3.0 audit --explain
|
|
80
61
|
```
|
|
81
62
|
|
|
82
|
-
|
|
63
|
+
`audit` returns exit code `1` when it finds issues. That is a completed scan,
|
|
64
|
+
not a malformed command; its JSON, TOON, text, or SARIF output remains the
|
|
65
|
+
report to inspect. Exit code `2` means the command could not be used as
|
|
66
|
+
requested. See [outputs and exit behavior](./docs/OUTPUTS.md).
|
|
83
67
|
|
|
84
|
-
|
|
68
|
+
## Scan a GitHub organization
|
|
85
69
|
|
|
86
|
-
|
|
70
|
+
Set a token that can see the repositories you intend to scan, then write a
|
|
71
|
+
versioned JSON report:
|
|
87
72
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
73
|
+
```sh
|
|
74
|
+
export GITHUB_TOKEN="$(gh auth token)"
|
|
75
|
+
|
|
76
|
+
actions-warden org-scan my-org \
|
|
77
|
+
--severity=high \
|
|
78
|
+
--checkpoint=.actions-warden-org-checkpoint.json \
|
|
79
|
+
--format=json \
|
|
80
|
+
--output=file \
|
|
81
|
+
--output-path=actions-warden-org.json
|
|
82
|
+
```
|
|
93
83
|
|
|
94
|
-
|
|
84
|
+
The scanner:
|
|
95
85
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
| `--cwd <dir>` | `.` | working directory |
|
|
86
|
+
- paginates every repository visible to the token;
|
|
87
|
+
- excludes archived, disabled, and forked repositories by default;
|
|
88
|
+
- reads workflow and composite-action YAML from each default branch;
|
|
89
|
+
- applies the same rules, policy, and baseline model as a local audit;
|
|
90
|
+
- returns per-repository findings, source links, coverage counts, and errors;
|
|
91
|
+
- checkpoints each completed repository when requested and can safely resume;
|
|
92
|
+
- shows live repository and retry progress on stderr without corrupting reports;
|
|
93
|
+
- never clones, checks out, or executes repository code.
|
|
105
94
|
|
|
106
|
-
|
|
95
|
+
Resume an interrupted scan with the same scope and policy:
|
|
107
96
|
|
|
108
|
-
|
|
97
|
+
```sh
|
|
98
|
+
actions-warden org-scan my-org \
|
|
99
|
+
--severity=high \
|
|
100
|
+
--resume=.actions-warden-org-checkpoint.json \
|
|
101
|
+
--format=json \
|
|
102
|
+
--output=file \
|
|
103
|
+
--output-path=actions-warden-org.json
|
|
104
|
+
```
|
|
109
105
|
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
Resume still performs fresh organization discovery and checks every selected
|
|
107
|
+
default-branch tree SHA. Only unchanged, error-free repository results are
|
|
108
|
+
reused; changed and previously failed repositories are scanned again. Progress
|
|
109
|
+
defaults to interactive terminals; use `--progress=always` for redirected logs
|
|
110
|
+
or `--progress=never` to disable it.
|
|
112
111
|
|
|
113
|
-
|
|
114
|
-
|---|---|---|
|
|
115
|
-
| `-w, --workflow <pattern>` | discover | repeatable |
|
|
116
|
-
| `--write` | `false` | apply changes (otherwise dry-run) |
|
|
117
|
-
| `--dry-run <bool>` | `true` | explicit dry-run toggle |
|
|
118
|
-
| `--token <token>` | `$GITHUB_TOKEN` | GitHub API token |
|
|
119
|
-
| `--fix <id>` | - | apply only the change with this id |
|
|
120
|
-
| `--format <fmt>` | `toon` | |
|
|
112
|
+
When a coding agent initiates the scan, use the explicit bounded mode:
|
|
121
113
|
|
|
122
|
-
|
|
114
|
+
```sh
|
|
115
|
+
actions-warden org-scan my-org --agent-mode
|
|
116
|
+
```
|
|
123
117
|
|
|
124
|
-
|
|
118
|
+
It writes a scope-keyed JSON report and checkpoint, resumes compatible state,
|
|
119
|
+
disables progress, and returns only a compact JSON receipt with the report path
|
|
120
|
+
unless explicit CLI options override those defaults.
|
|
125
121
|
|
|
126
|
-
|
|
127
|
-
|---|---|---|
|
|
128
|
-
| `--mode <m>` | `minor` | `major`, `minor`, or `patch` |
|
|
129
|
-
| `--write` | `false` | apply changes |
|
|
130
|
-
| `--fix <id>` | - | apply only this change id |
|
|
131
|
-
| `--token <token>` | `$GITHUB_TOKEN` | |
|
|
122
|
+
Limit scope with repository globs and visibility:
|
|
132
123
|
|
|
133
|
-
|
|
124
|
+
```sh
|
|
125
|
+
actions-warden org-scan my-org \
|
|
126
|
+
--repository 'service-*' 'my-org/platform-*' \
|
|
127
|
+
--visibility=private \
|
|
128
|
+
--max-repos=100 \
|
|
129
|
+
--concurrency=8 \
|
|
130
|
+
--format=sarif \
|
|
131
|
+
--output=file \
|
|
132
|
+
--output-path=actions-warden-org.sarif
|
|
133
|
+
```
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
Private and internal scans require repository metadata and contents read
|
|
136
|
+
access. A truncated tree, inaccessible repository, oversized workflow, or
|
|
137
|
+
failed blob read is reported as an error so incomplete coverage cannot appear
|
|
138
|
+
clean. See the [organization-scan reference](./docs/CLI.md#org-scan) and the
|
|
139
|
+
[scheduled workflow example](./examples/org-scan.yml).
|
|
136
140
|
|
|
137
|
-
|
|
138
|
-
|---|---|---|
|
|
139
|
-
| `--mode <m>` | `minor` | upgrade scope |
|
|
140
|
-
| `--offline` | `false` | skip network-dependent stages |
|
|
141
|
+
## Safe by default
|
|
141
142
|
|
|
142
|
-
|
|
143
|
+
The write boundary is deliberately explicit:
|
|
143
144
|
|
|
144
|
-
|
|
145
|
+
```text
|
|
146
|
+
audit/report/pin/upgrade plan → review IDs and diffs → --fix=<id> --write → verify
|
|
147
|
+
```
|
|
145
148
|
|
|
146
|
-
|
|
149
|
+
- `audit`, `report`, `verify`, and `org-scan` do not modify workflows.
|
|
150
|
+
- `pin` and `upgrade` are dry-runs unless `--write` is present.
|
|
151
|
+
- `--write --dry-run` is rejected instead of guessing intent.
|
|
152
|
+
- `--fix=<id>` limits a pin or upgrade to one exact source occurrence.
|
|
153
|
+
- Rewrites preserve surrounding YAML and are reparsed before an atomic write.
|
|
154
|
+
- Paths, output files, and symlinks are constrained to the selected repository.
|
|
155
|
+
- Credential-like values are recursively redacted from every output format.
|
|
156
|
+
- Repository policy is strictly validated; unknown keys and rule IDs fail.
|
|
157
|
+
- Remote organization source is kept in memory and is not persisted in cache.
|
|
147
158
|
|
|
148
|
-
|
|
149
|
-
|
|
159
|
+
See [SECURITY.md](./SECURITY.md) for the threat model and vulnerability
|
|
160
|
+
reporting process.
|
|
150
161
|
|
|
151
|
-
|
|
152
|
-
permissions:
|
|
153
|
-
contents: read
|
|
162
|
+
## Commands
|
|
154
163
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
| command | network | writes by default | purpose |
|
|
165
|
+
|---|---:|---:|---|
|
|
166
|
+
| `audit` | no | no | Scan workflows and composite actions for security findings |
|
|
167
|
+
| `report` | yes | no | Combine audit results with dry-run pin and upgrade plans |
|
|
168
|
+
| `pin` | yes | no | Resolve mutable action refs to immutable commit SHAs |
|
|
169
|
+
| `verify` | yes | no | Verify SHA ownership and human-readable version metadata |
|
|
170
|
+
| `upgrade` | yes | no | Plan or apply cooldown-aware dependency upgrades |
|
|
171
|
+
| `org-scan` | yes | no | Audit eligible repositories across a GitHub organization |
|
|
172
|
+
| `rules` | no | no | Print the live audit-rule catalog |
|
|
173
|
+
|
|
174
|
+
Run `actions-warden <command> --help` for live option help, or use the complete
|
|
175
|
+
[CLI reference](./docs/CLI.md).
|
|
176
|
+
|
|
177
|
+
By default, local commands discover:
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
.github/workflows/*.yml
|
|
181
|
+
.github/workflows/*.yaml
|
|
182
|
+
action.yml
|
|
183
|
+
action.yaml
|
|
184
|
+
**/action.yml
|
|
185
|
+
**/action.yaml
|
|
168
186
|
```
|
|
169
187
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
| input | default | applies to | description |
|
|
173
|
-
|---|---|---|---|
|
|
174
|
-
| `command` | `audit` | all | `audit`, `pin`, `upgrade`, `report`, `rules` |
|
|
175
|
-
| `workflow` | discover | all | space-separated paths or globs |
|
|
176
|
-
| `severity` | - | audit/report | `low` / `medium` / `high` / `critical` |
|
|
177
|
-
| `format` | `toon` | all | `toon` / `json` / `text` |
|
|
178
|
-
| `mode` | `minor` | upgrade/report | `major` / `minor` / `patch` |
|
|
179
|
-
| `min-age` | `7` | upgrade/report | cooldown in days before accepting a new tag |
|
|
180
|
-
| `write` | `false` | pin/upgrade | `true` to apply changes |
|
|
181
|
-
| `explain` | `false` | audit | include remediation hints |
|
|
182
|
-
| `offline` | `false` | report | skip network calls |
|
|
183
|
-
| `output-path` | - | all | also save the report to this file |
|
|
184
|
-
| `token` | - | all | GitHub token (pass `${{ github.token }}`) |
|
|
185
|
-
| `working-directory` | `$GITHUB_WORKSPACE` | all | directory to scan |
|
|
186
|
-
| `node-version` | `20` | - | Node.js version to install |
|
|
187
|
-
|
|
188
|
-
Outputs:
|
|
189
|
-
|
|
190
|
-
| output | description |
|
|
191
|
-
|---|---|
|
|
192
|
-
| `status` | `OK` or `FAIL` (mirrors the CLI's exit signal) |
|
|
193
|
-
| `findings` | number of audit findings (audit/report) |
|
|
194
|
-
| `report-path` | absolute path of the saved report, if `output-path` was set |
|
|
195
|
-
|
|
196
|
-
The action also writes a job summary block with the output of the command,
|
|
197
|
-
making findings visible directly in the GitHub UI.
|
|
188
|
+
Select exact files, directories, or globs with `--workflow`:
|
|
198
189
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
190
|
+
```sh
|
|
191
|
+
actions-warden audit -w .github/workflows/release.yml --explain
|
|
192
|
+
actions-warden audit -w '.github/workflows/*.yml' --severity=high
|
|
193
|
+
actions-warden audit -w .github/workflows .github/actions
|
|
194
|
+
```
|
|
202
195
|
|
|
203
|
-
|
|
196
|
+
Explicit targets that match nothing are errors.
|
|
204
197
|
|
|
205
|
-
|
|
206
|
-
`actions-warden` automatically whenever a prompt asks to audit, pin, or
|
|
207
|
-
upgrade GitHub Actions workflows.
|
|
198
|
+
## Configuration
|
|
208
199
|
|
|
209
|
-
|
|
200
|
+
Add `.actions-warden.yml` to make repository policy reviewable:
|
|
210
201
|
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
|
|
202
|
+
```yaml
|
|
203
|
+
version: 1
|
|
204
|
+
baseline: .actions-warden-baseline.json
|
|
205
|
+
|
|
206
|
+
ignore-paths:
|
|
207
|
+
- .github/workflows/generated/**
|
|
208
|
+
|
|
209
|
+
rules:
|
|
210
|
+
excessive-permissions:
|
|
211
|
+
severity: high
|
|
212
|
+
unpinned-container-image:
|
|
213
|
+
enabled: false
|
|
214
|
+
|
|
215
|
+
runner-policy:
|
|
216
|
+
self-hosted-labels:
|
|
217
|
+
- private-*
|
|
218
|
+
trusted-groups:
|
|
219
|
+
- github-hosted-*
|
|
220
|
+
flag-unknown-groups: true
|
|
214
221
|
```
|
|
215
222
|
|
|
216
|
-
|
|
223
|
+
Create a baseline only after reviewing the current findings:
|
|
217
224
|
|
|
218
225
|
```sh
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
-o ~/.claude/skills/actions-warden/SKILL.md
|
|
226
|
+
actions-warden audit \
|
|
227
|
+
--create-baseline=.actions-warden-baseline.json
|
|
222
228
|
```
|
|
223
229
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
230
|
+
Protect the policy and baseline with `CODEOWNERS` or branch rules; changing
|
|
231
|
+
either can intentionally alter what fails CI. The [configuration guide](./docs/CONFIGURATION.md)
|
|
232
|
+
covers strict validation, inline ignores, baselines, runner policy, and
|
|
233
|
+
organization-wide path matching.
|
|
228
234
|
|
|
229
|
-
|
|
235
|
+
List the current rules instead of relying on a copied table:
|
|
230
236
|
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
skills/actions-warden/SKILL.md # the skill itself
|
|
237
|
+
```sh
|
|
238
|
+
actions-warden rules --format=json
|
|
234
239
|
```
|
|
235
240
|
|
|
236
|
-
##
|
|
241
|
+
## Output built for people and automation
|
|
237
242
|
|
|
238
|
-
|
|
239
|
-
|
|
243
|
+
| format | best for |
|
|
244
|
+
|---|---|
|
|
245
|
+
| `toon` | Compact terminal and LLM context; the default |
|
|
246
|
+
| `json` | Versioned programmatic integrations |
|
|
247
|
+
| `text` | Human-readable line-oriented logs |
|
|
248
|
+
| `sarif` | Code scanning and SARIF-compatible systems |
|
|
240
249
|
|
|
241
|
-
|
|
242
|
-
import { audit, pin, upgrade, report } from 'actions-warden';
|
|
250
|
+
TOON output is one labeled record per line:
|
|
243
251
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
252
|
+
```text
|
|
253
|
+
SCAN: file=.github/workflows/release.yml
|
|
254
|
+
FINDING: id=18b82e86d7c14fe2 type=unpinned-action sev=high action=actions/checkout@v5 line=15
|
|
255
|
+
SUMMARY: files=1 findings=1 totalFindings=1 suppressed=0 critical=0 high=1 medium=0 low=0
|
|
256
|
+
STATUS: FAIL
|
|
248
257
|
```
|
|
249
258
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
`format`, `redact`.
|
|
254
|
-
|
|
255
|
-
## Audit rules
|
|
259
|
+
Findings and proposed changes have stable, clone-independent IDs. JSON payloads
|
|
260
|
+
carry `schemaVersion: "1.0"`; SARIF is 2.1.0. See [output contracts](./docs/OUTPUTS.md)
|
|
261
|
+
for schemas, record labels, redaction, status, and shell/CI handling.
|
|
256
262
|
|
|
257
|
-
|
|
258
|
-
|---|---|---|
|
|
259
|
-
| `unpinned-action` | high | workflow steps, job-level reusable workflows, and composite-action `uses:` refs that aren't 40-char SHAs |
|
|
260
|
-
| `excessive-permissions` | medium | `write-all` and broad write scopes |
|
|
261
|
-
| `secrets-in-env` | critical | secrets at workflow/job env (leaks to every step) |
|
|
262
|
-
| `script-injection` | critical | `github.event.*` interpolated into `run:` |
|
|
263
|
-
| `pull-request-target-checkout` | critical | "pwn-request" pattern |
|
|
263
|
+
## GitHub Action
|
|
264
264
|
|
|
265
|
-
|
|
265
|
+
Pin the Action itself to a reviewed full commit SHA:
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
```yaml
|
|
268
|
+
name: actions-warden
|
|
268
269
|
|
|
269
|
-
|
|
270
|
+
on:
|
|
271
|
+
pull_request:
|
|
272
|
+
push:
|
|
273
|
+
branches: [main]
|
|
270
274
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
- Output is deterministic and idempotent - re-running on an unchanged repo
|
|
274
|
-
produces identical bytes.
|
|
275
|
-
- Every finding and every planned change carries a stable `id`. To apply a
|
|
276
|
-
single fix without scope creep, pass `--fix=<id>`.
|
|
277
|
-
- The CLI never prompts interactively. All decisions are flag-driven.
|
|
278
|
-
- Secrets that leak into log lines (tokens, AWS keys, PEM blocks) are passed
|
|
279
|
-
through a redactor before output.
|
|
275
|
+
permissions:
|
|
276
|
+
contents: read
|
|
280
277
|
|
|
281
|
-
|
|
278
|
+
jobs:
|
|
279
|
+
audit:
|
|
280
|
+
runs-on: ubuntu-latest
|
|
281
|
+
steps:
|
|
282
|
+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # actions-warden-ref: v5.0.0
|
|
283
|
+
with:
|
|
284
|
+
persist-credentials: false
|
|
282
285
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
+
- uses: chiz0me/actions-warden@<FULL_COMMIT_SHA>
|
|
287
|
+
with:
|
|
288
|
+
command: audit
|
|
289
|
+
severity: high
|
|
290
|
+
explain: 'true'
|
|
286
291
|
```
|
|
287
292
|
|
|
288
|
-
The
|
|
289
|
-
|
|
290
|
-
|
|
293
|
+
The committed bundle runs on GitHub's managed Node 24 runtime and installs no
|
|
294
|
+
consumer-side dependencies. Findings become native annotations and a job
|
|
295
|
+
summary. See the [Action inputs, outputs, permissions, and examples](./docs/GITHUB-ACTION.md).
|
|
291
296
|
|
|
292
|
-
##
|
|
297
|
+
## AI-assisted use
|
|
293
298
|
|
|
294
|
-
|
|
295
|
-
TTL defaults to 1 hour. Delete the directory to force a refresh.
|
|
299
|
+
The CLI is non-interactive and flag-driven. For a safe agent loop:
|
|
296
300
|
|
|
297
|
-
|
|
301
|
+
```sh
|
|
302
|
+
actions-warden audit --format=json --explain
|
|
303
|
+
actions-warden pin --format=json
|
|
304
|
+
# After the user approves one planned ID:
|
|
305
|
+
actions-warden pin --fix=<ID> --write --format=json
|
|
306
|
+
actions-warden verify --format=json
|
|
307
|
+
actions-warden audit --format=json
|
|
308
|
+
```
|
|
298
309
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
310
|
+
Use JSON when the caller has a parser and TOON when context size matters.
|
|
311
|
+
Agents should treat policy changes, baselines, `--write`, and organization
|
|
312
|
+
tokens as security-sensitive boundaries. For an agent-initiated organization
|
|
313
|
+
scan, use `actions-warden org-scan ORG --agent-mode`. It automatically writes a
|
|
314
|
+
scope-keyed report and checkpoint, resumes compatible state, disables progress,
|
|
315
|
+
and returns only a compact JSON receipt unless explicit flags override those
|
|
316
|
+
defaults. The agent then reads bounded summaries and relevant finding batches
|
|
317
|
+
instead of placing the full report in model context. This preserves requested
|
|
318
|
+
coverage while controlling LLM token use. The
|
|
319
|
+
[AI and agent guide](./docs/AI-AGENTS.md#default-for-an-ai-initiated-scan)
|
|
320
|
+
defines the exact command, inspection sequence, decision loop, and parsing
|
|
321
|
+
contract.
|
|
322
|
+
Repository-local guidance is also available in [AGENTS.md](./AGENTS.md), and a
|
|
323
|
+
Claude Code skill ships in [`skills/actions-warden`](./skills/actions-warden/SKILL.md).
|
|
324
|
+
|
|
325
|
+
## JavaScript API
|
|
326
|
+
|
|
327
|
+
Every command is available without spawning a subprocess:
|
|
304
328
|
|
|
305
|
-
|
|
329
|
+
```js
|
|
330
|
+
import { audit, scanOrganization } from 'actions-warden';
|
|
331
|
+
|
|
332
|
+
const local = await audit({
|
|
333
|
+
cwd: '/path/to/repository',
|
|
334
|
+
severity: 'high',
|
|
335
|
+
explain: true,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
const organization = await scanOrganization({
|
|
339
|
+
organization: 'my-org',
|
|
340
|
+
token: process.env.GITHUB_TOKEN,
|
|
341
|
+
severity: 'high',
|
|
342
|
+
});
|
|
343
|
+
```
|
|
306
344
|
|
|
307
|
-
See [
|
|
345
|
+
See the [JavaScript API guide](./docs/JAVASCRIPT-API.md) for command options,
|
|
346
|
+
result shapes, renderers, lower-level exports, and error handling.
|
|
308
347
|
|
|
309
|
-
##
|
|
348
|
+
## Documentation
|
|
310
349
|
|
|
311
|
-
|
|
312
|
-
[
|
|
350
|
+
- [Documentation index](./docs/README.md)
|
|
351
|
+
- [CLI reference](./docs/CLI.md)
|
|
352
|
+
- [Configuration and baselines](./docs/CONFIGURATION.md)
|
|
353
|
+
- [Output contracts](./docs/OUTPUTS.md)
|
|
354
|
+
- [GitHub Action guide](./docs/GITHUB-ACTION.md)
|
|
355
|
+
- [JavaScript API](./docs/JAVASCRIPT-API.md)
|
|
356
|
+
- [AI and coding-agent guide](./docs/AI-AGENTS.md)
|
|
357
|
+
- [Developer guide](./docs/DEVELOPMENT.md)
|
|
358
|
+
- [Contributing](./CONTRIBUTING.md)
|
|
359
|
+
- [Security policy](./SECURITY.md)
|
|
360
|
+
- [Maintainer and agent release runbook](./RELEASING.md)
|
|
313
361
|
|
|
314
362
|
## License
|
|
315
363
|
|
|
316
|
-
MIT
|
|
364
|
+
[MIT](./LICENSE)
|