build: package CLI with pinned producer verifier
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
This commit is contained in:
parent
c80a944105
commit
ebca4f5adb
9 changed files with 433 additions and 1 deletions
82
docs/cli-release-bundle.md
Normal file
82
docs/cli-release-bundle.md
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# CLI release bundle with authenticated decision verifier
|
||||
|
||||
The supported packaged CLI path is an explicit wheel-plus-verifier bundle. The
|
||||
existing editable `uv` workflow remains for development. Installing the Python
|
||||
wheel alone omits the Go helper and is incomplete for production authorization;
|
||||
it continues to fail closed. This is a CLI package, not a service or the retired
|
||||
`rapp-secrets-engine` deployment.
|
||||
|
||||
The bundle contains the Secrets wheel, the existing PyYAML runtime wheel pinned
|
||||
by `uv.lock`, the verifier executable, producer license attribution, a narrow CLI
|
||||
entry point and an offline installer. It never contains the test signer, signing
|
||||
seed, caller credential, runtime trust/key config or backend entitlement. Optional
|
||||
`clock` extras are outside this base bundle; configuring clock trust without the
|
||||
separately reviewed extra continues to refuse, rather than fall back.
|
||||
|
||||
## Build
|
||||
|
||||
Use Python >=3.11, uv and the Go toolchain required by `verifier/go.mod` on the
|
||||
intended Linux architecture. Supply a local compatible PyYAML wheel whose exact
|
||||
filename and SHA-256 appear in `uv.lock`. The builder never discovers/downloads a
|
||||
runtime dependency. The existing Hatchling build backend is now version-pinned.
|
||||
|
||||
```bash
|
||||
python3 scripts/build_release_bundle.py \
|
||||
--output /tmp/secrets-cli-reviewed-build \
|
||||
--dependency-wheel /path/to/locked-compatible-pyyaml.whl
|
||||
```
|
||||
|
||||
Builds are offline by default. In a reviewed build environment, the explicit
|
||||
`--allow-build-downloads` flag permits uv to fetch the existing pinned build
|
||||
backend and its build dependencies. It does not change the runtime dependency
|
||||
contract. Set writable uv/Go caches as required by that build environment.
|
||||
|
||||
The builder first verifies the exact producer API/signature source and native
|
||||
fixture hashes, builds only the verifier root package with CGO disabled, explicit
|
||||
host architecture, trimmed paths, disabled VCS stamping and an empty build ID,
|
||||
then builds the wheel with commit-derived `SOURCE_DATE_EPOCH`. Two builds using
|
||||
the same source snapshot/toolchain/dependency wheel produce matching artifacts
|
||||
and manifest. The manifest records exact source-file and artifact SHA-256s, base
|
||||
commit, producer snapshot, platform and tool versions. It contains no observed
|
||||
build timestamp; retain observed execution time in a separate receipt.
|
||||
|
||||
## Review and offline install
|
||||
|
||||
**Checksums prove artifact integrity, not independent package admission.** The
|
||||
owner must review/admit the source, toolchain, complete bundle and manifest hash,
|
||||
and control the bundle/install prefix. A manifest obtained from an untrusted
|
||||
bundle does not establish that admission. Key/trust admission remains a distinct
|
||||
WP14 gate. None of these steps authorizes protected OpenBao work.
|
||||
|
||||
Execute the reviewed installer with the independently retained manifest digest:
|
||||
|
||||
```bash
|
||||
python3 /path/to/reviewed-bundle/install.py \
|
||||
--prefix /path/to/new-owner-controlled-prefix \
|
||||
--manifest-sha256 REVIEWED_MANIFEST_SHA256
|
||||
/path/to/new-owner-controlled-prefix/bin/secrets-engine --help
|
||||
```
|
||||
|
||||
The parent directory must already be owner controlled. The installer validates
|
||||
platform, manifest and the entire artifact set before creating a private new
|
||||
prefix, creates its venv through the existing uv convention, and installs entirely
|
||||
offline from bundled wheels. It never replaces an existing prefix or installs
|
||||
into standard user/system tools. A failed partial prefix is retained and marked;
|
||||
retry with a new prefix after diagnosis. Removing a failed/disposable prefix is
|
||||
an explicit owner operation, not an automatic cleanup of an existing path.
|
||||
|
||||
Use `PREFIX/bin/secrets-engine` as the admitted CLI entry point. It checks the
|
||||
bundled helper's SHA-256 before CLI import or credential access and fixes
|
||||
`SECRETS_ENGINE_PDP_VERIFIER` to that helper; ambient executable overrides do not
|
||||
select another verifier. Missing or changed helpers refuse. There is no runtime
|
||||
compilation or unsigned fallback. The internal venv scripts/programmatic API are
|
||||
not a second admitted entry point and do not create package/trust admission.
|
||||
Catalog/policy and independently reviewed responder trust configuration still
|
||||
belong to the deploying owner. Neither is silently copied from a developer repo.
|
||||
|
||||
For source verification, supply `SECRETS_ENGINE_TEST_DEPENDENCY_WHEEL` and run
|
||||
`pytest tests/test_release_bundle.py`. The disposable proof compares two builds,
|
||||
installs offline, invokes the installed wheel's signed HTTP boundary with public
|
||||
synthetic fixtures, rejects unsigned decisions, checks helper/bundle tampering,
|
||||
source drift and existing-prefix refusal. No native credentials or protected
|
||||
backend are involved.
|
||||
Loading…
Add table
Add a link
Reference in a new issue