- integrations
- Python
- Guides
- Hermetic CI
Hermetic CI
Three defaults, each individually reasonable for a dev library, add up to a specific fact worth stating plainly: the ambient environment is a trusted input unless you turn it off.
OCX_INSTALL_*is honored from the ambient environment bybootstrap.ensure()— it chooses what gets downloaded and from where.OCX_AUTH_*passes through to a spawned ocx untouched — it chooses which credentials attach to a registry call.- Binary discovery walks
PATH— it chooses whichocxactually runs.
None of this is a bug; a CI runner’s ambient environment usually is trustworthy. But a build that wants to say so explicitly, or one running in an environment it does not fully trust, has levers for every one of the three — all opt-in, all composable.
The levers
Section titled “The levers”| Trust boundary | Default | Hardening lever |
|---|---|---|
What bootstrap.ensure() downloads |
Ambient OCX_INSTALL_* honored (which ones) |
Pass version=, dist=, mirror_url=, ca_bundle= explicitly; construct DistSource with an explicit sha256= |
| Which credentials a spawn carries | Ambient OCX_AUTH_* passes through |
Ocx(host_env=HostEnv.clean()) or .without(...); explicit OcxConfig.auth always wins over ambient for the same registry |
| Which binary runs | PATH search |
Ocx(exe=...) — the hardened form: it trusts a location without inspecting how it was reached |
| Registry transport | Whatever insecure_registries the ambient env allows |
OcxConfig(insecure_registries=()) — fail-closed: an explicit value, including the empty tuple, replaces the ambient set entirely rather than merging with it |
| Cache integrity | Re-hashed on every cache hit | Already default-on; trust_cache=True is the (explicit) way to opt back out |
Explicit configuration always wins over the ambient environment — that precedence is uniform across every lever above, not something to remember per field.
from ocx_sdk import OcxConfig
hermetic = OcxConfig(insecure_registries=())assert hermetic.insecure_registries == ()A CI image that exports OCX_INSECURE_REGISTRIES cannot re-enable
plaintext through this config — the empty tuple is the fail-closed answer,
not the same as leaving insecure_registries unset (None, which inherits
whatever the ambient environment allows).
A recipe
Section titled “A recipe”# illustrative: needs a real binary; substitute your discovery/pin strategy.from ocx_sdk import HostEnv, Ocx, OcxConfig, bootstrap
ocx = Ocx( exe=bootstrap.ensure(version="0.6.2"), # pinned, not "latest" host_env=HostEnv.minimal(), # PATH/HOME/TMPDIR only config=OcxConfig( insecure_registries=(), # fail-closed no_config=True, # ignore any discovered config.toml ),)HostEnv.minimal() rather than HostEnv.clean() here: a spawned toolchain
still needs PATH to find its own dependencies, and clean() drops it —
see Bootstrap for the full tier list.
What a spawn leaves behind: the consent stamp
Section titled “What a spawn leaves behind: the consent stamp”One default runs the other way — it is on regardless of the levers above.
ocx stamps state/projects/<key>/consent.json on every add, lock,
pull, exec, update and init, and the stamp is what lets a shell
prompt in that directory activate the project at the developer’s next
cd. A program step should not leave that behind, so the SDK writes
OCX_NO_CONSENT=1 on every spawn (ocx exec forwards it to nested ocx) and
an ambient OCX_NO_CONSENT=0 cannot switch it back. A pipeline that does
want the project live afterwards says so on the handle:
from ocx_sdk import OcxConfig
assert OcxConfig().consent is Falseconsenting = OcxConfig(consent=True) # `handle.with_config(consent=True)` in practiceassert consenting.consent is TrueThat is the per-project stamp only; the shell-activation consent
ocx shell allow records is not wrapped.
Continues on Hermetic CI: The forge identity ladder.