secrets-engine/docs/cli-release-bundle.md
tegwick ebca4f5adb build: package CLI with pinned producer verifier
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
2026-10-16 09:20:33 +02:00

82 lines
4.5 KiB
Markdown

# 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.