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.
Files changed (62) hide show
  1. package/AGENTS.md +189 -0
  2. package/CONTRIBUTING.md +109 -0
  3. package/README.md +272 -224
  4. package/RELEASING.md +338 -0
  5. package/SECURITY.md +25 -3
  6. package/docs/AI-AGENTS.md +458 -0
  7. package/docs/CLI.md +421 -0
  8. package/docs/CONFIGURATION.md +340 -0
  9. package/docs/DEVELOPMENT.md +350 -0
  10. package/docs/GITHUB-ACTION.md +281 -0
  11. package/docs/JAVASCRIPT-API.md +355 -0
  12. package/docs/OUTPUTS.md +409 -0
  13. package/docs/README.md +27 -0
  14. package/examples/org-scan.yml +42 -0
  15. package/examples/upgrade-pr.yml +57 -0
  16. package/llms.txt +38 -0
  17. package/package.json +32 -10
  18. package/skills/actions-warden/SKILL.md +140 -38
  19. package/src/action.js +317 -0
  20. package/src/cli.js +267 -22
  21. package/src/commands/audit.js +189 -36
  22. package/src/commands/org-scan.js +549 -0
  23. package/src/commands/pin.js +59 -56
  24. package/src/commands/report.js +122 -10
  25. package/src/commands/upgrade.js +102 -62
  26. package/src/commands/verify.js +193 -0
  27. package/src/index.js +21 -4
  28. package/src/lib/action-status.js +27 -0
  29. package/src/lib/agent-mode.js +175 -0
  30. package/src/lib/annotations.js +250 -0
  31. package/src/lib/baseline.js +103 -0
  32. package/src/lib/cache.js +47 -10
  33. package/src/lib/concurrency.js +27 -0
  34. package/src/lib/config.js +185 -0
  35. package/src/lib/execution.js +71 -0
  36. package/src/lib/formatter.js +127 -8
  37. package/src/lib/github-org.js +374 -0
  38. package/src/lib/identity.js +62 -0
  39. package/src/lib/ignore.js +7 -6
  40. package/src/lib/org-checkpoint.js +378 -0
  41. package/src/lib/org-progress.js +60 -0
  42. package/src/lib/parser.js +326 -52
  43. package/src/lib/patcher.js +199 -0
  44. package/src/lib/paths.js +35 -12
  45. package/src/lib/redact.js +65 -4
  46. package/src/lib/resolver.js +225 -43
  47. package/src/lib/targets.js +28 -0
  48. package/src/lib/triggers.js +12 -0
  49. package/src/lib/writer.js +45 -8
  50. package/src/rules/excessive-permissions.js +24 -33
  51. package/src/rules/index.js +19 -1
  52. package/src/rules/pull-request-target-checkout.js +149 -18
  53. package/src/rules/reusable-workflow-secrets.js +32 -0
  54. package/src/rules/script-injection.js +77 -12
  55. package/src/rules/secrets-in-env.js +101 -18
  56. package/src/rules/unpinned-action.js +3 -2
  57. package/src/rules/unpinned-container-image.js +39 -0
  58. package/src/rules/unpinned-docker-action.js +30 -0
  59. package/src/rules/untrusted-self-hosted-runner.js +109 -0
  60. package/src/rules/workflow-run-artifact-execution.js +122 -0
  61. package/src/rules/workflow-structure.js +396 -0
  62. package/src/version.js +3 -0
package/README.md CHANGED
@@ -8,309 +8,357 @@
8
8
  [![node](https://img.shields.io/node/v/actions-warden)](https://www.npmjs.com/package/actions-warden)
9
9
  [![license: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
10
10
 
11
- Audit, pin, and upgrade GitHub Actions workflows. Designed for safe, hands-off
12
- invocation by humans **or** LLMs.
11
+ Audit GitHub Actions in one repository or across an entire organization, then
12
+ pin, verify, and safely upgrade workflow dependencies.
13
13
 
14
- - **Audit** - scan workflows for supply-chain/injection risks and composite actions for mutable dependencies
15
- - **Pin** - rewrite tag refs (`@v3`) to immutable commit SHAs
16
- - **Upgrade** - bump pinned actions to the newest permitted version
17
- - **Report** - combined audit + dry-run plan, ideal for LLM context
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
- Inspired by [`actions-up`](https://github.com/azat-io/actions-up). The
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
- ## Why
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
- Tag references in `uses:` are mutable - anyone with write access to the action
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
- ## Install
36
+ Node.js 20 or newer is required.
35
37
 
36
38
  ```sh
37
- npm install -g actions-warden
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
- ```sh
47
- # Audit workflows, reusable workflow calls, and composite actions
48
- actions-warden audit
41
+ # Local and read-only
42
+ actions-warden audit --explain
49
43
 
50
- # Audit a specific file with remediation hints
51
- actions-warden audit -w .github/workflows/release.yml --explain
44
+ # Network-backed, but still read-only
45
+ actions-warden report --format=json
52
46
 
53
- # Plan a SHA-pinning pass (does NOT write)
47
+ # Preview pins; this does not change files
54
48
  actions-warden pin
55
49
 
56
- # Actually write the pins
50
+ # Apply the reviewed pin plan
57
51
  actions-warden pin --write
58
52
 
59
- # Plan upgrades within the same major version
60
- actions-warden upgrade --mode=minor
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
- ## Output formats
67
-
68
- ### TOON (default - `--format=toon`)
57
+ For a one-off run without a global install:
69
58
 
70
- Token-Oriented Object Notation. Each line is a labeled record with `key=value`
71
- fields. Parses cleanly without a schema and ends with a machine-readable
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
- ### JSON (`--format=json`)
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
- Structured payload for programmatic integrations.
68
+ ## Scan a GitHub organization
85
69
 
86
- ### Text (`--format=text`)
70
+ Set a token that can see the repositories you intend to scan, then write a
71
+ versioned JSON report:
87
72
 
88
- Plain human-readable lines - useful when piping through `less`.
89
-
90
- ## Commands
91
-
92
- ### `audit`
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
- Scan workflows for security findings.
84
+ The scanner:
95
85
 
96
- | flag | default | description |
97
- |---|---|---|
98
- | `-w, --workflow <pattern>` | discover workflows and `**/action.yml|yaml` | repeatable path or glob |
99
- | `--severity <level>` | `low` (i.e. include all) | minimum severity to report |
100
- | `--explain` | `false` | include plain-English remediation hint per finding |
101
- | `--format <fmt>` | `toon` | `toon`, `json`, or `text` |
102
- | `--output <dest>` | `stdout` | `stdout` or `file` |
103
- | `--output-path <path>` | - | required when `--output=file` |
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
- Exit codes: `0` if no findings, `1` if any finding reported, `2` on usage error.
95
+ Resume an interrupted scan with the same scope and policy:
107
96
 
108
- ### `pin`
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
- Resolve every tag/branch ref to a 40-char commit SHA. Preserves the original
111
- tag as an inline `# v3` comment so `upgrade` can find it later.
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
- | flag | default | description |
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
- ### `upgrade`
114
+ ```sh
115
+ actions-warden org-scan my-org --agent-mode
116
+ ```
123
117
 
124
- Bump pinned/tagged actions to the newest version allowed by `--mode`.
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
- | flag | default | description |
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
- ### `report`
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
- Runs `audit`, plus dry-run `pin` and `upgrade`. Single combined output.
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
- | flag | default | description |
138
- |---|---|---|
139
- | `--mode <m>` | `minor` | upgrade scope |
140
- | `--offline` | `false` | skip network-dependent stages |
141
+ ## Safe by default
141
142
 
142
- ### `rules`
143
+ The write boundary is deliberately explicit:
143
144
 
144
- Print the rule catalog.
145
+ ```text
146
+ audit/report/pin/upgrade plan → review IDs and diffs → --fix=<id> --write → verify
147
+ ```
145
148
 
146
- ## Use it as a GitHub Action
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
- `actions-warden` ships an `action.yml` at the repo root, so you can drop it
149
- into any workflow.
159
+ See [SECURITY.md](./SECURITY.md) for the threat model and vulnerability
160
+ reporting process.
150
161
 
151
- ```yaml
152
- permissions:
153
- contents: read
162
+ ## Commands
154
163
 
155
- jobs:
156
- audit:
157
- runs-on: ubuntu-latest
158
- steps:
159
- - uses: actions/checkout@v5
160
- with:
161
- persist-credentials: false
162
- - uses: <owner>/actions-warden@<commit-sha> # pin to a SHA
163
- with:
164
- command: audit
165
- severity: high
166
- explain: 'true'
167
- token: ${{ github.token }}
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
- Inputs (all optional unless noted):
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
- **Important:** the audit command exits non-zero when findings are reported,
200
- which fails the job by default. To collect findings without failing the build,
201
- set `continue-on-error: true` on the step.
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
- ## Use it from Claude Code
196
+ Explicit targets that match nothing are errors.
204
197
 
205
- This repo is also a Claude Code plugin. Once installed, Claude will invoke
206
- `actions-warden` automatically whenever a prompt asks to audit, pin, or
207
- upgrade GitHub Actions workflows.
198
+ ## Configuration
208
199
 
209
- **Option A - via the plugin marketplace (recommended):**
200
+ Add `.actions-warden.yml` to make repository policy reviewable:
210
201
 
211
- ```
212
- /plugin marketplace add chiz0me/claude-plugins
213
- /plugin install actions-warden@chiz0me
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
- **Option B - drop the skill in directly (no marketplace):**
223
+ Create a baseline only after reviewing the current findings:
217
224
 
218
225
  ```sh
219
- mkdir -p ~/.claude/skills/actions-warden
220
- curl -fsSL https://raw.githubusercontent.com/chiz0me/actions-warden/main/skills/actions-warden/SKILL.md \
221
- -o ~/.claude/skills/actions-warden/SKILL.md
226
+ actions-warden audit \
227
+ --create-baseline=.actions-warden-baseline.json
222
228
  ```
223
229
 
224
- After installation, prompts like *"audit my workflows"*, *"pin my actions to
225
- SHAs"*, or *"check this workflow for script injection"* will route through the
226
- skill, which runs the CLI via `npx actions-warden` and explains the TOON
227
- output back to you.
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
- Plugin layout (per the Claude Code plugin spec):
235
+ List the current rules instead of relying on a copied table:
230
236
 
231
- ```
232
- .claude-plugin/plugin.json # plugin manifest
233
- skills/actions-warden/SKILL.md # the skill itself
237
+ ```sh
238
+ actions-warden rules --format=json
234
239
  ```
235
240
 
236
- ## Programmatic API
241
+ ## Output built for people and automation
237
242
 
238
- Each command is also exported as an async function, so an LLM agent or
239
- larger Node tool can invoke it without spawning a subprocess.
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
- ```js
242
- import { audit, pin, upgrade, report } from 'actions-warden';
250
+ TOON output is one labeled record per line:
243
251
 
244
- const result = await audit({ cwd: '/path/to/repo', explain: true });
245
- for (const finding of result.findings) {
246
- // result.findings[i].id is stable; pass it to pin({ fix: id })
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
- Available functions: `audit`, `pin`, `upgrade`, `report`, `listRules`,
251
- `discoverWorkflows`, `parseWorkflowFile`, `parseWorkflowSource`, `collectUses`,
252
- `parseActionRef`, `renderAudit`, `renderPin`, `renderUpgrade`, `renderReport`,
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
- | id | severity | catches |
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
- Run `actions-warden rules` for the live list.
265
+ Pin the Action itself to a reviewed full commit SHA:
266
266
 
267
- ## LLM invocation safety
267
+ ```yaml
268
+ name: actions-warden
268
269
 
269
- Every command is designed to be safe to invoke from an autonomous agent:
270
+ on:
271
+ pull_request:
272
+ push:
273
+ branches: [main]
270
274
 
271
- - `pin` and `upgrade` default to `--dry-run=true`. You cannot accidentally
272
- mutate files without explicitly passing `--write`.
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
- ## Authentication
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
- ```sh
284
- export GITHUB_TOKEN=$(gh auth token) # or set GH_TOKEN
285
- actions-warden pin
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 `--token` flag takes precedence. Without a token the GitHub API allows 60
289
- requests/hour, which is enough for small repos but will rate-limit on larger
290
- audits.
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
- ## Caching
297
+ ## AI-assisted use
293
298
 
294
- GitHub API responses are cached in `.actions-warden-cache/` (gitignore it).
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
- ## Exit codes
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
- | code | meaning |
300
- |---|---|
301
- | `0` | success, no findings |
302
- | `1` | findings reported, or errors during pin/upgrade |
303
- | `2` | invalid arguments |
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
- ## Security
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 [SECURITY.md](./SECURITY.md) for the disclosure policy.
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
- ## Maintainers
348
+ ## Documentation
310
349
 
311
- Release process, npm/marketplace setup, and verification commands live in
312
- [RELEASING.md](./RELEASING.md).
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)