@ciqol/resenv 0.1.0-beta.1 → 0.1.0-beta.2
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/CONTRIBUTING.md +33 -13
- package/README.md +34 -20
- package/SECURITY.md +20 -20
- package/bin/resenv.cjs +21 -23
- package/docs/build.md +14 -15
- package/docs/dependencies.md +57 -501
- package/docs/doppler.md +69 -60
- package/docs/maintainer-handoff.md +29 -102
- package/docs/release-security.md +67 -131
- package/docs/releasing.md +32 -21
- package/doppler/auth.cjs +4 -110
- package/doppler/http.cjs +3 -8
- package/doppler/system.cjs +26 -75
- package/package.json +1 -1
- package/types/src/doppler/auth.d.ts +2 -17
- package/types/src/doppler/http.d.ts +1 -3
- package/types/src/doppler/system.d.ts +3 -8
- package/docs/maturity.md +0 -61
- package/docs/public-readiness.md +0 -138
- package/docs/security-performance-review.md +0 -150
- package/docs/validation.md +0 -700
package/docs/doppler.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Doppler references and
|
|
1
|
+
# Doppler references and CLI authentication
|
|
2
2
|
|
|
3
3
|
Doppler is resenv's only built-in cloud provider. After Nx or another loader
|
|
4
4
|
populates the environment, resenv fetches referenced values through HTTPS and
|
|
@@ -13,40 +13,57 @@ a provider option. `resolve-doppler` and
|
|
|
13
13
|
|
|
14
14
|
## Local setup
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
After [installing resenv](../README.md#install) in your application project,
|
|
17
|
+
install the [official Doppler CLI](https://docs.doppler.com/docs/cli) and run
|
|
18
|
+
this from the application's directory:
|
|
17
19
|
|
|
18
20
|
```sh
|
|
19
|
-
|
|
20
|
-
node dist/bin/resenv.cjs login doppler
|
|
21
|
+
doppler login
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
The
|
|
39
|
-
`
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
24
|
+
Doppler owns browser authorization, token persistence, login scopes and logout.
|
|
25
|
+
Use `doppler logout` to manage the CLI login. resenv never opens a browser,
|
|
26
|
+
prompts for login, issues or revokes tokens, or reads or writes the OS
|
|
27
|
+
credential store directly. There is no separate resenv login.
|
|
28
|
+
|
|
29
|
+
Existing Doppler users can reuse their login. resenv asks the CLI for the token
|
|
30
|
+
selected by its current working directory, so Doppler's directory-scoped
|
|
31
|
+
workplace identities continue to apply. See
|
|
32
|
+
[Doppler's scope guide](https://docs.doppler.com/docs/multiple-workplaces).
|
|
33
|
+
`doppler setup` is not required for resenv references: their project and config
|
|
34
|
+
are already explicit in each `doppler://` value. Nx or the caller remains
|
|
35
|
+
responsible for dotenv file loading.
|
|
36
|
+
|
|
37
|
+
### Platforms and installation locations
|
|
38
|
+
|
|
39
|
+
The CLI handles its own credential storage on macOS, Linux and Windows. resenv
|
|
40
|
+
does not require `secret-tool`, a separate keyring package or native Node addons.
|
|
41
|
+
It discovers the CLI in these standard locations:
|
|
42
|
+
|
|
43
|
+
| Platform | Locations, in lookup order |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| macOS / Linux | `/opt/homebrew/bin/doppler`, `/usr/local/bin/doppler`, `/usr/bin/doppler`, `~/.local/bin/doppler`, `~/bin/doppler` |
|
|
46
|
+
| Windows | `~/AppData/Local/Microsoft/WinGet/Links/doppler.exe`, `~/scoop/apps/doppler/current/doppler.exe` |
|
|
47
|
+
|
|
48
|
+
Here `~` is the OS user's home directory. Windows paths cover default per-user
|
|
49
|
+
WinGet and Scoop installations. Custom and system-wide Windows installations
|
|
50
|
+
outside these locations need an explicit `DOPPLER_TOKEN`. WSL uses the Linux
|
|
51
|
+
installation and login within WSL. The runtime deliberately ignores the
|
|
52
|
+
application's `PATH` so a repository-local executable cannot replace the
|
|
53
|
+
credential helper.
|
|
54
|
+
|
|
55
|
+
Windows discovery is covered with injected process tests; a native Windows
|
|
56
|
+
end-to-end run is not yet verified. Automated checks never use a developer's
|
|
57
|
+
Doppler login or OS credential store.
|
|
58
|
+
|
|
59
|
+
### Migration from resenv-managed login
|
|
60
|
+
|
|
61
|
+
`resenv login` and `resenv logout` have been removed. Run `doppler login` to
|
|
62
|
+
establish the CLI identity, then start the application normally. Earlier resenv
|
|
63
|
+
credentials stored under service `ciqol.envref.doppler`, account `default`, are
|
|
64
|
+
ignored and are not migrated or deleted automatically. If you used that flow,
|
|
65
|
+
remove the obsolete entry through your OS credential manager and revoke the
|
|
66
|
+
obsolete token in Doppler when it is no longer needed.
|
|
50
67
|
|
|
51
68
|
## Declare a reference
|
|
52
69
|
|
|
@@ -73,38 +90,31 @@ For an Nx command target, use `resenv run -- node app.mjs` inside the
|
|
|
73
90
|
target. Preloading the outer Nx process would run before Nx loads target files.
|
|
74
91
|
resenv does not choose, read or rewrite dotenv files.
|
|
75
92
|
|
|
76
|
-
##
|
|
93
|
+
## Runtime credential lookup
|
|
77
94
|
|
|
78
95
|
Resolution checks these sources in order:
|
|
79
96
|
|
|
80
97
|
1. An explicitly supplied `DOPPLER_TOKEN`.
|
|
81
|
-
2. The
|
|
82
|
-
3. The current directory's existing Doppler CLI login, retrieved with the
|
|
98
|
+
2. The current directory's existing Doppler CLI login, retrieved with the
|
|
83
99
|
documented `doppler configure get token --plain` operation.
|
|
84
100
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
101
|
+
resenv captures the token internally and fetches secrets through HTTPS; it does
|
|
102
|
+
not parse the CLI's private config format. The command uses a fixed executable,
|
|
103
|
+
separate arguments, `--no-check-version` and `--no-read-env`, with a restricted
|
|
104
|
+
environment. It inherits the application's working directory to preserve login
|
|
105
|
+
scopes. Lookup has a fifteen-second timeout and a 16 KiB output limit. Captured
|
|
106
|
+
output and helper errors are never forwarded to application logs.
|
|
91
107
|
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
If the CLI is missing, install it in a supported location and run `doppler login`,
|
|
109
|
+
or supply `DOPPLER_TOKEN`. A failed or empty CLI lookup reports that login is
|
|
110
|
+
required. An explicitly supplied invalid token, malformed CLI token, access
|
|
111
|
+
denial or network failure stops the operation without switching identities or
|
|
112
|
+
starting login.
|
|
94
113
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
An explicit invalid token, access denial, login rejection, timeout or network
|
|
100
|
-
error stops the operation. These failures do not silently switch identities.
|
|
101
|
-
Unset `DOPPLER_TOKEN` before interactive login because it overrides saved logins.
|
|
102
|
-
In CI, supply a suitably scoped token through the runner's credential facility.
|
|
103
|
-
|
|
104
|
-
`resenv logout doppler` removes only resenv's local credential. It does not
|
|
105
|
-
revoke the remote token, unset an environment variable or log the Doppler CLI
|
|
106
|
-
out. Those other credential sources can still authenticate. Revoke unwanted
|
|
107
|
-
tokens from Doppler's CLI Tokens page.
|
|
114
|
+
In CI, containers and other unattended environments, supply a suitably scoped
|
|
115
|
+
`DOPPLER_TOKEN` through the runner's secret facility. No CLI installation or
|
|
116
|
+
local credential store is needed in that mode. Changing the CLI login affects
|
|
117
|
+
the next application startup; resenv does not keep a persistent token cache.
|
|
108
118
|
|
|
109
119
|
## Resolution and security boundaries
|
|
110
120
|
|
|
@@ -126,10 +136,9 @@ tokens from Doppler's CLI Tokens page.
|
|
|
126
136
|
- Preloads use a child Node process to wait for asynchronous HTTPS while
|
|
127
137
|
retaining `--require` compatibility. It receives only references and an
|
|
128
138
|
explicit credential through stdin, with results returned through a private
|
|
129
|
-
pipe. No Doppler CLI is required when
|
|
139
|
+
pipe. No Doppler CLI is required when `DOPPLER_TOKEN` is supplied.
|
|
130
140
|
- Diagnostics show variable names and error codes, never tokens, provider
|
|
131
|
-
response bodies or resolved values.
|
|
132
|
-
its temporary human authorization code.
|
|
141
|
+
response bodies, CLI output or resolved values.
|
|
133
142
|
|
|
134
143
|
This removes shell evaluation from Doppler lookups. It does not isolate
|
|
135
144
|
untrusted repository code or agents that can access the same user's credential
|
|
@@ -139,8 +148,8 @@ to a specific config.
|
|
|
139
148
|
|
|
140
149
|
## Sources
|
|
141
150
|
|
|
142
|
-
- [Doppler
|
|
143
|
-
- [
|
|
151
|
+
- [Doppler CLI installation and authentication](https://docs.doppler.com/docs/cli)
|
|
152
|
+
- [Directory-scoped workplace logins](https://docs.doppler.com/docs/multiple-workplaces)
|
|
144
153
|
- [Retrieve a secret](https://docs.doppler.com/reference/secrets-get)
|
|
145
154
|
- [API authentication](https://docs.doppler.com/reference/api)
|
|
146
155
|
- [Retrieve the CLI token](https://docs.doppler.com/docs/cli#fetch-cli-token-from-your-local-environment)
|
|
@@ -1,112 +1,39 @@
|
|
|
1
|
-
# Maintainer
|
|
1
|
+
# Maintainer guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Start with [AGENTS.md](https://github.com/ciqol/resenv/blob/beta/AGENTS.md) for repository policy and
|
|
4
|
+
[CONTRIBUTING.md](../CONTRIBUTING.md) for setup and verification. Work in an
|
|
5
|
+
isolated task worktree on a `titan/*` branch. Authenticate as `titan-ron` for
|
|
6
|
+
[ciqol/resenv](https://github.com/ciqol/resenv); `beta` is the default and sole
|
|
7
|
+
release branch.
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
the push remote and recent commits before changing anything.
|
|
9
|
+
Inspect current Git status, branches, push remote and recent commits before
|
|
10
|
+
editing. Read live GitHub checks, releases and npm metadata before release
|
|
11
|
+
work; old chat messages or check results are not authoritative. Never copy
|
|
12
|
+
credentials between sessions.
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Package: `@ciqol/resenv`; CLI: `resenv`.
|
|
21
|
-
- Node preloads: `--require @ciqol/resenv/resolve` and
|
|
22
|
-
`--import @ciqol/resenv/resolve`.
|
|
23
|
-
- Public API: `resolve(env = process.env, { replace: false })`. Always return a
|
|
24
|
-
copy; update the input only with `replace: true`.
|
|
25
|
-
- Let Nx or the caller load dotenv files. Resolve values already in the
|
|
26
|
-
environment, once before application imports.
|
|
27
|
-
- Doppler is the only cloud provider. Infer it from
|
|
28
|
-
`doppler://project/config/SECRET_NAME`; that syntax belongs to resenv.
|
|
29
|
-
- Commands require explicit opt-in. Fetched values remain literal, and a
|
|
30
|
-
failed pass leaves the caller's environment unchanged.
|
|
31
|
-
- Debug selector: `NODE_DEBUG=ciqol:resenv`. Never log secret values, tokens,
|
|
32
|
-
command text or provider response bodies.
|
|
33
|
-
- Runtime npm dependencies: none. Dotenvx decryption has been removed;
|
|
34
|
-
`encrypted:` values remain literal.
|
|
14
|
+
| Guide | Maintained information |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| [README](../README.md) | Application installation, API and CLI usage |
|
|
17
|
+
| [Doppler](doppler.md) | CLI authentication, lookup, migration and platform limits |
|
|
18
|
+
| [Build](build.md) | Module formats, declarations, archive and CI contract |
|
|
19
|
+
| [Dependencies](dependencies.md) | Tool rationale, installation and update policy |
|
|
20
|
+
| [Releasing](releasing.md) | Candidate checks, npm staging/approval and recovery |
|
|
21
|
+
| [Release security](release-security.md) | Isolation guards, advisory policy and platform review deadline |
|
|
22
|
+
| [Security](../SECURITY.md) | Trust boundaries and private vulnerability reporting |
|
|
35
23
|
|
|
36
24
|
## Code map
|
|
37
25
|
|
|
38
26
|
| Path | Responsibility |
|
|
39
27
|
| --- | --- |
|
|
40
|
-
| `src/index.ts` | Resolution API and atomic replacement |
|
|
28
|
+
| `src/index.ts` | Resolution API and atomic environment replacement |
|
|
41
29
|
| `src/preload.ts`, `src/resolve*.ts` | Startup integration and shared preload state |
|
|
42
|
-
| `src/doppler/` |
|
|
30
|
+
| `src/doppler/` | References, HTTPS, concurrency and CLI credential lookup |
|
|
43
31
|
| `src/commands.ts` | Explicit shell substitution and process limits |
|
|
44
|
-
| `bin/resenv.ts` |
|
|
45
|
-
| `rollup.config.mjs`, `scripts/build.mjs` | CJS implementation,
|
|
46
|
-
| `scripts/release-plan.mjs` | Official
|
|
47
|
-
| `scripts/publish.mjs` |
|
|
48
|
-
| `.github/workflows/ci.yml` | Build once,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Use the exact Node.js version in `.nvmrc` and normal npm lifecycle behavior:
|
|
53
|
-
|
|
54
|
-
```sh
|
|
55
|
-
nvm use
|
|
56
|
-
npm ci
|
|
57
|
-
npm run audit
|
|
58
|
-
npm run verify
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Unit specs live beside source modules and run with Vitest. Process tests live
|
|
62
|
-
in `test/`. Clean-consumer checks exercise CJS, ESM, declarations, CLI and
|
|
63
|
-
preloads against the packed archive. Tests use dummy values and mocked effects;
|
|
64
|
-
do not use a developer's Doppler account or OS credential store as a fixture.
|
|
65
|
-
See CONTRIBUTING for Nx integration checks and benchmarking.
|
|
66
|
-
|
|
67
|
-
## Recover release state before pushing
|
|
68
|
-
|
|
69
|
-
Read current state rather than treating a dated handoff as authoritative:
|
|
70
|
-
|
|
71
|
-
```sh
|
|
72
|
-
gh run list --repo ciqol/resenv --workflow ci.yml --limit 5
|
|
73
|
-
gh release list --repo ciqol/resenv
|
|
74
|
-
npm view @ciqol/resenv versions dist-tags --json
|
|
75
|
-
npm stage list @ciqol/resenv --json
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
The first intended version is `0.1.0-beta.1` on npm's `beta` tag. The planner
|
|
79
|
-
uses semantic-release's official commit-analysis and notes plugins directly;
|
|
80
|
-
it does not run the full semantic-release engine. Real published release tags
|
|
81
|
-
supply later beta counters. Do not fabricate tags to advance a version.
|
|
82
|
-
|
|
83
|
-
Publishing is staged: a trusted manual CI dispatch submits the exact archive
|
|
84
|
-
that passed all consumer checks. The `release` environment accepts only `beta`
|
|
85
|
-
and has no GitHub reviewer gate. npm approval with 2FA makes a stage public.
|
|
86
|
-
After public availability and integrity verification, rerun the original
|
|
87
|
-
release job to record its Git tag and GitHub prerelease. Keep `beta` at that
|
|
88
|
-
candidate's commit until this step finishes, unless the maintainer explicitly
|
|
89
|
-
chooses to reject and replace the pending stage. Do not rerun the whole
|
|
90
|
-
workflow to recover an existing stage.
|
|
91
|
-
|
|
92
|
-
A staged version reserves its version number. To replace an unapproved
|
|
93
|
-
candidate, the maintainer must reject the old stage with npm 2FA before CI
|
|
94
|
-
stages the replacement. Check stage status before retrying an ambiguous result.
|
|
95
|
-
Never publish from a developer machine, add a publishing token, promote a beta
|
|
96
|
-
to `latest`, or delete the whole npm package. The `0.0.0-stage` placeholder must
|
|
97
|
-
remain until a functional beta is public; removing the last published version
|
|
98
|
-
would remove the package and impose npm's publishing cooldown.
|
|
99
|
-
|
|
100
|
-
## Known limits and follow-ups
|
|
101
|
-
|
|
102
|
-
- Native Doppler browser login has unit/mock coverage but has not been verified
|
|
103
|
-
end to end with a fresh account. Linux credential storage has mock coverage;
|
|
104
|
-
Windows native login/storage is not implemented. Explicit tokens and existing
|
|
105
|
-
CLI credentials are supported. See [Doppler details](doppler.md).
|
|
106
|
-
- The development release-tool tree has reviewed advisories. Exceptions expire
|
|
107
|
-
November 9, 2026, and executable guards fail on expiry or drift. Review
|
|
108
|
-
[release security](release-security.md); never broaden or bypass the policy.
|
|
109
|
-
- This beta has not had an independent security audit. Passing tests or the
|
|
110
|
-
static maturity checklist does not establish production readiness.
|
|
111
|
-
- Consumer repositories are separate. Keep local links out of their committed
|
|
112
|
-
package manifests, lockfiles and CI.
|
|
32
|
+
| `bin/resenv.ts` | Child-process CLI |
|
|
33
|
+
| `rollup.config.mjs`, `scripts/build.mjs` | CJS implementation, ESM facades, types and manifest |
|
|
34
|
+
| `scripts/release-plan.mjs` | Official release plugins and beta counter |
|
|
35
|
+
| `scripts/publish.mjs` | Tested-archive staging and verified release recording |
|
|
36
|
+
| `.github/workflows/ci.yml` | Build once, archive matrix tests and manual release |
|
|
37
|
+
|
|
38
|
+
Keep docs focused on current contracts, decisions and procedures. Put per-run
|
|
39
|
+
test results, benchmarks, audit snapshots and session history in PRs or CI.
|
package/docs/release-security.md
CHANGED
|
@@ -1,134 +1,70 @@
|
|
|
1
|
-
# Release-tool security
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
The
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
[commit matching](https://github.com/semantic-release/commit-analyzer/blob/v13.0.1/lib/analyze-commit.js),
|
|
36
|
-
[micromatch matching](https://github.com/micromatch/micromatch/blob/4.0.8/index.js),
|
|
37
|
-
[braces advisory](https://github.com/advisories/GHSA-vfj7-8cjw-p6xm).
|
|
38
|
-
|
|
39
|
-
The guards pin the engine, analyzer, notes generator, micromatch and braces
|
|
40
|
-
versions. Changed versions fail until the control is reviewed. The audit checks
|
|
41
|
-
each advisory URL, exact affected version and development-only lockfile path.
|
|
42
|
-
New findings, runtime occurrences, changed paths and expired reviews fail CI.
|
|
43
|
-
Propagated parent findings do not create additional blanket exemptions.
|
|
44
|
-
`npm audit --omit=dev --audit-level=high` also runs without exceptions.
|
|
45
|
-
|
|
46
|
-
The planner receives no GitHub write token, npm credential or OIDC permission.
|
|
47
|
-
It reads Git history and actual beta tags locally. The official commit-analysis
|
|
48
|
-
and release-notes plugins are fixed in code; the full semantic-release engine
|
|
49
|
-
is not invoked while beta is the sole branch. An explicit 0.1.0 beta line and
|
|
50
|
-
monotonic counter replace its default 1.0.0 initial version. The publisher does
|
|
51
|
-
not install dependencies or import release tools. It verifies candidate hashes
|
|
52
|
-
and source identity, then stages the tested archive through npm OIDC. Maintainer approval through npm publishes it.
|
|
53
|
-
A rerun verifies registry integrity before recording the computed tag/release
|
|
54
|
-
through GitHub's API. Conventional Commit classification remains upstream.
|
|
55
|
-
|
|
56
|
-
## Verification
|
|
57
|
-
|
|
58
|
-
An isolated test blocked direct braces calls and imports of the unselected npm
|
|
59
|
-
and GitHub plugins. Normal and adversarial commit analysis passed with 10,000
|
|
60
|
-
nested brace pairs in subjects and bodies. The planner tests cover
|
|
61
|
-
`0.1.0-beta.1`, unchanged history, and subsequent beta counters using real history in a disposable clone without changing source refs.
|
|
62
|
-
|
|
63
|
-
An isolated attempt to override npm's bundled vulnerable components did not
|
|
64
|
-
replace their distributed copies. No ineffective override was admitted.
|
|
65
|
-
Standalone patched releases do not establish that the bundled copy is fixed.
|
|
66
|
-
Review and remove these exceptions when the upstream distributions are fixed.
|
|
67
|
-
|
|
68
|
-
## Dependency admission
|
|
69
|
-
|
|
70
|
-
- **Need:** automate Conventional Commit analysis and release notes, as selected
|
|
71
|
-
by the user. Platform APIs do not implement that versioning contract.
|
|
72
|
-
- **Fit:** retain the selected engine rather than switch to release-please or
|
|
73
|
-
maintain a custom analyzer. Native publication glue preserves the tested
|
|
74
|
-
archive instead of letting a package-directory plugin repack it.
|
|
75
|
-
- **Health:** registry review recorded monthly downloads of 12,515,497 for the
|
|
76
|
-
engine, 12,542,138 for the analyzer and 12,802,125 for the notes generator,
|
|
77
|
-
with three listed maintainers each. Selected release dates are August 5, 2026;
|
|
78
|
-
January 3, 2025; and May 8, 2026. The older analyzer remains the component
|
|
79
|
-
required by the current engine. Maintenance evidence is not a security guarantee.
|
|
80
|
-
- **Trust:** the canonical semantic-release repositories match the distributed
|
|
81
|
-
modules. The isolated installation verified 447 registry signatures and 121
|
|
82
|
-
provenance attestations; the final merged installation verified 606 signatures
|
|
83
|
-
and 186 attestations. Registry metadata does not expose individual MFA or
|
|
84
|
-
independently prove historical ownership continuity; those limits remain.
|
|
85
|
-
- **License:** the three direct artifacts contain MIT license text. The isolated
|
|
86
|
-
tree's licenses are MIT, ISC, BSD-2-Clause, BSD-3-Clause, Apache-2.0, BlueOak-1.0.0,
|
|
87
|
-
Python-2.0, Artistic-2.0, CC-BY-3.0, CC0-1.0 and permissive alternative sets.
|
|
88
|
-
qrcode-terminal's absent SPDX metadata is resolved by its Apache-2.0 LICENSE.
|
|
89
|
-
Some artifacts express the license in package metadata rather than a separate
|
|
90
|
-
license file. No reciprocal source-disclosure license was identified. These
|
|
91
|
-
development modules are excluded from the consumer package.
|
|
92
|
-
- **Capabilities:** filesystem, subprocess and Git access are required for local
|
|
93
|
-
history analysis. The selected plugin path does not publish, contact npm or
|
|
94
|
-
post GitHub comments. The isolated tree contains no install lifecycle hooks.
|
|
95
|
-
- **Control:** exact direct versions and the lockfile pin the tree; CODEOWNERS
|
|
96
|
-
and Dependabot retain ownership and update visibility. The guards and expiring
|
|
97
|
-
audit policy fail on drift. Removal means deleting the three development
|
|
98
|
-
dependencies and disabling release planning/publication; local build and
|
|
99
|
-
consumer verification remain available.
|
|
100
|
-
|
|
101
|
-
The audit result must remain visible. Do not describe the release-tool tree as
|
|
102
|
-
vulnerability-free, use an audit-wide ignore, or pass it to a privileged job.
|
|
1
|
+
# Release-tool security
|
|
2
|
+
|
|
3
|
+
Maintainer: `titan-ron`. Runtime dependencies have no advisory exceptions.
|
|
4
|
+
The executable development policy is [security-exceptions.json](security-exceptions.json).
|
|
5
|
+
Its review expires **November 9, 2026 at 00:00 UTC**. This is a project review
|
|
6
|
+
deadline, also enforced by the publisher for platform npm; removing unused
|
|
7
|
+
development tools does not extend it.
|
|
8
|
+
|
|
9
|
+
## Release planning
|
|
10
|
+
|
|
11
|
+
The planner calls the official commit-analysis and release-notes plugins
|
|
12
|
+
directly. It reads Git history and published beta tags without GitHub write,
|
|
13
|
+
npm or OIDC credentials. The full `semantic-release` engine and its publishing
|
|
14
|
+
plugins are unnecessary for this beta-only workflow.
|
|
15
|
+
|
|
16
|
+
The committed peer-omission policy keeps the engine, `@semantic-release/npm`,
|
|
17
|
+
`@semantic-release/github` and their npm module off disk. Before auditing or
|
|
18
|
+
planning, `scripts/release-guards.mjs` requires that none resolve from the
|
|
19
|
+
project or either selected plugin. Its planner hook also rejects bare and
|
|
20
|
+
resolved imports of those tools. An audit explicitly including omitted peers
|
|
21
|
+
can still report their locked entries; see [installation policy](dependencies.md).
|
|
22
|
+
|
|
23
|
+
The guard pins both plugins, micromatch and braces. It replaces every callable
|
|
24
|
+
braces export with a throwing guard before loading the plugins. The selected
|
|
25
|
+
micromatch matching calls use picomatch; vulnerable brace expansion must never
|
|
26
|
+
execute. Version drift fails until the guards are reviewed.
|
|
27
|
+
|
|
28
|
+
`npm run audit` checks runtime dependencies without exceptions, then the
|
|
29
|
+
installed development tree. Moderate/high/critical findings must match an exact
|
|
30
|
+
advisory URL, development-only lockfile path, version and unexpired policy
|
|
31
|
+
entry. New advisories, changed paths, runtime occurrences and expired
|
|
32
|
+
exceptions fail. The retained exception entries do not authorize reinstalling
|
|
33
|
+
the excluded tools. Prefer an upstream fix or removing unused dependencies;
|
|
34
|
+
never broaden the policy to make a check pass.
|
|
103
35
|
|
|
104
36
|
## Publishing platform
|
|
105
37
|
|
|
106
|
-
The publisher
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
38
|
+
The privileged publisher installs no release-tool dependencies and accepts only
|
|
39
|
+
the archive described by the verified candidate plan. It checks source identity
|
|
40
|
+
and hashes before invoking npm. Publication follows the [release runbook](releasing.md).
|
|
41
|
+
|
|
42
|
+
The platform is pinned to Node.js 24.19.0 and its npm 11.17.0. Platform npm has
|
|
43
|
+
separately reviewed bundled-component risks; omitting development peers does
|
|
44
|
+
not fix those components. `scripts/publish.mjs` rejects platform version drift
|
|
45
|
+
and an expired review, including on a failed-job retry.
|
|
46
|
+
|
|
47
|
+
The staging command accepts a fixed tarball and HTTPS npm registry, with no
|
|
48
|
+
package lifecycle scripts in the generated manifest. It runs with a fresh home,
|
|
49
|
+
configuration and cache, strips proxy/token/arbitrary npm configuration, and
|
|
50
|
+
uses the protected workflow's OIDC identity. It accepts no login, shell,
|
|
51
|
+
selector or arbitrary URL input. Registry and signing services remain trusted
|
|
52
|
+
inputs. These controls bound exposure; they do not patch the platform CLI.
|
|
53
|
+
|
|
54
|
+
The publisher validates the staging receipt's package name, version and
|
|
55
|
+
integrity. npm approval publishes the stage. A retry verifies the public
|
|
56
|
+
archive's integrity and both npm tags before recording the Git tag/release.
|
|
57
|
+
No tag is created for a pending stage.
|
|
58
|
+
|
|
59
|
+
## Reviewing changes
|
|
60
|
+
|
|
61
|
+
Review the actual published artifacts, including bundled copies; patching a
|
|
62
|
+
standalone package does not establish that npm's bundled copy is fixed.
|
|
63
|
+
Recheck platform npm before the deadline and remove obsolete exception entries
|
|
64
|
+
when upstream fixes or dependency removal make them unnecessary. Do not extend
|
|
65
|
+
the deadline or bypass executable controls to unblock publication.
|
|
66
|
+
|
|
67
|
+
Run `npm run audit`, `npm audit signatures` and `npm run verify`. Release tooling
|
|
68
|
+
specs cover absence/version guards, policy scope and expiry, adversarial commit
|
|
69
|
+
analysis, real Git release history and publisher isolation. Keep review evidence
|
|
70
|
+
in the PR and CI, and maintain this document as the current policy.
|