@secureci/cli 0.5.1 → 0.6.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/README.md +68 -11
- package/dist/advisories.js +603 -0
- package/dist/cli.js +255 -33
- package/dist/config.js +23 -1
- package/dist/init.js +12 -5
- package/dist/parser/dangerous-triggers.js +125 -0
- package/dist/parser/injection.js +281 -0
- package/dist/parser/permissions.js +145 -0
- package/dist/parser/pipeline-contract-parser.js +70 -0
- package/dist/parser/pipeline-contract-validator.js +18 -4
- package/dist/parser/validator.js +26 -1
- package/dist/pin.js +311 -0
- package/dist/report.js +7 -1
- package/dist/runner/action-fetcher.js +100 -4
- package/dist/runner/builtin-actions.js +13 -3
- package/dist/runner/dry-run.js +57 -12
- package/dist/runner/executor.js +368 -254
- package/dist/runner/expression.js +106 -8
- package/dist/runner/job-plan.js +58 -1
- package/dist/runner/job-runtime.js +3 -3
- package/dist/runner/node-action.js +11 -3
- package/dist/runner/node-binary.js +108 -0
- package/dist/runner/scheduler.js +207 -0
- package/dist/runner/steps.js +54 -2
- package/dist/utils/env-file.js +185 -0
- package/dist/utils/logger.js +36 -7
- package/dist/version.js +56 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -19,9 +19,11 @@ A single CLI that understands GitHub Actions the way the runner does:
|
|
|
19
19
|
- **Run workflows locally** — jobs in `needs:` order, matrix builds, reusable
|
|
20
20
|
workflows, composite / JavaScript / Docker actions, and the full
|
|
21
21
|
`${{ }}` / `if:` expression language.
|
|
22
|
-
- **Validate** workflow and action files,
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
- **Validate** workflow and action files, flag **template injection**
|
|
23
|
+
(untrusted `${{ }}` input expanded into `run:` scripts) and over-broad
|
|
24
|
+
`GITHUB_TOKEN` permissions, and **check them against a pipeline contract**
|
|
25
|
+
(required/forbidden actions, ordering, minimum versions, SHA-pinning and
|
|
26
|
+
permissions rules).
|
|
25
27
|
- **Inventory** every action a workflow pulls in, resolve each tag to a commit
|
|
26
28
|
SHA, and **catch supply-chain drift** when a tag quietly starts pointing
|
|
27
29
|
somewhere new.
|
|
@@ -41,6 +43,45 @@ npx @secureci/cli --help
|
|
|
41
43
|
Node.js 20+ is required. To build from source instead:
|
|
42
44
|
`npm install && npm run build`.
|
|
43
45
|
|
|
46
|
+
### Standalone binary (no Node.js needed)
|
|
47
|
+
|
|
48
|
+
Each [release](https://github.com/secure-ci/cli/releases) has a single-file
|
|
49
|
+
binary for Linux (x64, arm64), macOS (Intel, Apple silicon) and Windows (x64),
|
|
50
|
+
a `SHA256SUMS` file, and a signed build-provenance attestation. Pick the asset
|
|
51
|
+
for your platform: `secureci-linux-x64`, `secureci-linux-arm64`,
|
|
52
|
+
`secureci-darwin-x64`, `secureci-darwin-arm64` or `secureci-win-x64.exe`.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# macOS / Linux (here: Linux x64)
|
|
56
|
+
asset=secureci-linux-x64
|
|
57
|
+
base=https://github.com/secure-ci/cli/releases/latest/download
|
|
58
|
+
curl -fsSL -O "$base/$asset" -O "$base/SHA256SUMS"
|
|
59
|
+
sha256sum --check --ignore-missing SHA256SUMS # macOS: shasum -a 256 --check --ignore-missing SHA256SUMS
|
|
60
|
+
gh attestation verify "$asset" --repo secure-ci/cli # optional: verify provenance
|
|
61
|
+
chmod +x "$asset" && sudo mv "$asset" /usr/local/bin/secureci
|
|
62
|
+
secureci --version
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```powershell
|
|
66
|
+
# Windows (PowerShell)
|
|
67
|
+
$base = "https://github.com/secure-ci/cli/releases/latest/download"
|
|
68
|
+
Invoke-WebRequest "$base/secureci-win-x64.exe" -OutFile secureci.exe
|
|
69
|
+
Invoke-WebRequest "$base/SHA256SUMS" -OutFile SHA256SUMS
|
|
70
|
+
$expected = (Select-String -Path SHA256SUMS -Pattern "secureci-win-x64.exe").Line.Split(" ")[0]
|
|
71
|
+
if ((Get-FileHash secureci.exe -Algorithm SHA256).Hash -ne $expected) { throw "Checksum mismatch" }
|
|
72
|
+
gh attestation verify secureci.exe --repo secure-ci/cli # optional: verify provenance
|
|
73
|
+
.\secureci.exe --version
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The binary bundles its own Node.js runtime, so it's large (~100 MB). JavaScript
|
|
77
|
+
actions still need a `node` on `PATH` when they run on the host
|
|
78
|
+
(`--container-runtime host`); in a job container they use the image's `node`.
|
|
79
|
+
The macOS binaries are ad-hoc signed and the Windows binary is unsigned, so
|
|
80
|
+
Gatekeeper or SmartScreen may ask you to confirm the first run (on macOS, a
|
|
81
|
+
`curl` download isn't quarantined).
|
|
82
|
+
|
|
83
|
+
Homebrew (coming): a `secure-ci/tap` formula is planned.
|
|
84
|
+
|
|
44
85
|
## First run
|
|
45
86
|
|
|
46
87
|
```bash
|
|
@@ -59,6 +100,9 @@ secureci init workflow
|
|
|
59
100
|
# Lock the actions you use and catch supply-chain drift (commit secureci.lock)
|
|
60
101
|
secureci inventory # bootstraps secureci.lock, then drift-checks
|
|
61
102
|
secureci inventory --check # fail on drift (use in CI)
|
|
103
|
+
|
|
104
|
+
# Pin action tags to commit SHAs in place (keeps `# v4` for Dependabot/Renovate)
|
|
105
|
+
secureci pin
|
|
62
106
|
```
|
|
63
107
|
|
|
64
108
|
## Where it shines
|
|
@@ -72,7 +116,13 @@ secureci inventory --check # fail on drift (use in CI)
|
|
|
72
116
|
- **Supply-chain visibility** — [`secureci inventory`](DOCS.md#action-inventory-and-drift-secureci-inventory)
|
|
73
117
|
with a committed lockfile turns a silently moved action tag into a failing
|
|
74
118
|
check, including tags inside the actions you use, and catches a locked
|
|
75
|
-
repository that was deleted and re-created
|
|
119
|
+
repository that was deleted and re-created, and
|
|
120
|
+
[`secureci pin`](DOCS.md#pin-actions-to-commit-shas-secureci-pin) rewrites
|
|
121
|
+
action tags to commit SHAs in place.
|
|
122
|
+
- **Known vulnerabilities** — `inventory` and `validate` flag actions with
|
|
123
|
+
published [security advisories](DOCS.md#known-security-advisories) (for
|
|
124
|
+
example GHSA-mrrh-fwg8-r2c3 in `tj-actions/changed-files`), using the GitHub
|
|
125
|
+
Advisory Database.
|
|
76
126
|
- **Machine-readable output** — `--format json|sarif` drops straight into CI and
|
|
77
127
|
GitHub code scanning.
|
|
78
128
|
- **Audit evidence** — the contract, `secureci.lock` and reports are plain files
|
|
@@ -111,6 +161,9 @@ secureci run .github/workflows/ci.yml --job build --input ref=main --var ENV=sta
|
|
|
111
161
|
# Pass a secret by name (value read from your environment, not the command line)
|
|
112
162
|
secureci run .github/workflows/deploy.yml --secret TOKEN
|
|
113
163
|
|
|
164
|
+
# Read env vars, secrets, inputs and variables from .env-style files
|
|
165
|
+
secureci run .github/workflows/deploy.yml --env-file .env --secret-file .secrets
|
|
166
|
+
|
|
114
167
|
# Validate against a central pipeline contract, recursing into called workflows
|
|
115
168
|
secureci validate .github/workflows/deploy.yml \
|
|
116
169
|
--contract contracts/platform-standard.yml --contract-recurse all
|
|
@@ -136,8 +189,10 @@ things to know:
|
|
|
136
189
|
|
|
137
190
|
- **Linux containers only.** `windows-*` / `macos-*` jobs run in a Linux image
|
|
138
191
|
with a warning.
|
|
139
|
-
- **
|
|
140
|
-
|
|
192
|
+
- **Jobs running in parallel share your working copy.** Each job has its own
|
|
193
|
+
container, but every job mounts the same directory, so jobs that write the
|
|
194
|
+
same files (e.g. `node_modules`) can collide; use `--parallel 1` to run jobs
|
|
195
|
+
one after another.
|
|
141
196
|
- **`actions/checkout` of the current repo doesn't clone** — it uses your working
|
|
142
197
|
copy as-is (so uncommitted changes are visible); `ref:`/`fetch-depth:` are
|
|
143
198
|
ignored. Other repositories check out for real and need a token.
|
|
@@ -164,10 +219,10 @@ The exact scope of each is documented in
|
|
|
164
219
|
- **No ambient environment or secrets.** On the host, steps get only a minimal
|
|
165
220
|
allowlist plus the runner's `GITHUB_*`/`RUNNER_*` vars and the workflow's own
|
|
166
221
|
`env:`; everything else is passed explicitly.
|
|
167
|
-
- **Secret masking everywhere.** Values from `--secret` or
|
|
168
|
-
redacted in all output, and in container mode never appear
|
|
169
|
-
command line (passed via a `0600` env file). Prefer
|
|
170
|
-
value stays out of your shell history too.
|
|
222
|
+
- **Secret masking everywhere.** Values from `--secret`, `--secret-file` or
|
|
223
|
+
`::add-mask::` are redacted in all output, and in container mode never appear
|
|
224
|
+
on the client command line (passed via a `0600` env file). Prefer
|
|
225
|
+
`--secret NAME` so the value stays out of your shell history too.
|
|
171
226
|
- **Tokens are handled carefully** — sent only to the GitHub host in
|
|
172
227
|
`GITHUB_SERVER_URL` / `GITHUB_API_URL` (github.com by default), never passed
|
|
173
228
|
to actions, and masked in logs.
|
|
@@ -209,7 +264,9 @@ refactor while keeping tests green.
|
|
|
209
264
|
Every pull request and push to `main` runs
|
|
210
265
|
[`ci.yaml`](.github/workflows/ci.yaml): lint, `prettier --check`, tests with the
|
|
211
266
|
coverage thresholds in `vitest.config.mts`, build, and SecureCI
|
|
212
|
-
validating its own workflow.
|
|
267
|
+
validating its own workflow. It also builds the standalone binary on each
|
|
268
|
+
platform and smoke-tests it (`npm run build && npm run build:sea` builds one
|
|
269
|
+
for your machine into `build/sea/`).
|
|
213
270
|
|
|
214
271
|
Opt-in suites:
|
|
215
272
|
|