Skip to content

Bootstrap

bootstrap.ensure() provisions a verified ocx binary and returns its path — the Python equivalent of curl -sSL https://setup.ocx.sh | sh, minus any machine mutation. It never touches a shell profile, never runs self setup, and never writes anywhere outside its own cache directory.

# illustrative: needs network access to fetch the dist manifest.
from ocx_sdk import Ocx, bootstrap

exe = bootstrap.ensure()          # latest stable
ocx = Ocx(exe=exe)

It is idempotent and offline-friendly: a cache hit that still hashes correctly needs no network at all, and every knob resolves explicit argument first, then the matching OCX_INSTALL_* variable, then a default.

Those variables are the same ones setup.ocx.sh reads, so a machine already set up for the shell installer needs no code change:

Variable Argument Effect
OCX_INSTALL_VERSION version= Pin an exact release
OCX_INSTALL_DIST_URL dist= Where the manifest comes from (default source only)
OCX_INSTALL_MIRROR_URL mirror_url= Where the artifact bytes come from
OCX_INSTALL_CA_BUNDLE ca_bundle= PEM file trusted for the downloads
OCX_INSTALL_FORCE — Reinstall even on a cache hit

OCX_INSTALL_REPO and OCX_INSTALL_QUIET are accepted and do nothing — artifact URLs come from the manifest rather than a repository guess, and this module prints nothing to quiet. Every variable is in Environment.

Pinning

Pass version= for an exact release, or channel= to follow a channel's latest (Channel.STABLE is the default; Channel.NEXT tracks pre-releases):

# illustrative: needs network access.
from ocx_sdk import Channel, bootstrap

exe = bootstrap.ensure(version="0.6.2")
next_exe = bootstrap.ensure(channel=Channel.NEXT)

min_version= is the operator floor: a resolved version below it raises BootstrapError instead of silently installing something older than the caller allows.

Corporate mirror + auth

A DistSource is where the dist manifest comes from — building one is pure and needs no network, so it is safe to construct (and to unit test) without touching the wire:

from ocx_sdk import BasicAuth, DistSource

source = DistSource.url(
    "https://dist.internal.example.com/ocx/dist.json",
    sha256="c" * 64,  # required off-canonical — see below
    auth=BasicAuth("ci", "hunter2"),
)
# illustrative: feeding the source into ensure() needs network access.
from ocx_sdk import bootstrap

exe = bootstrap.ensure(dist=source, mirror_url="https://artifacts.internal.example.com/ocx")

mirror_url= relocates where the artifact bytes come from — the manifest digest is still enforced, because a mirror moves bytes, it never revalidates them. Setting OCX_INSTALL_MIRROR_URL in the environment does the same thing without touching the call, which is how a CI image points every build at an internal mirror; the explicit argument wins where both are set.

Behind a TLS-intercepting proxy

ca_bundle= (or OCX_INSTALL_CA_BUNDLE) names a PEM file trusted for the manifest and artifact downloads instead of the system store — the case where an interception appliance presents a certificate no default trust store knows:

# illustrative: needs network access.
from ocx_sdk import bootstrap

exe = bootstrap.ensure(ca_bundle="/etc/ssl/corp/root.pem")

This is transport trust only. The manifest pin and the artifact digest are untouched, so a bundle changes who may serve the bytes and never which bytes are accepted. An unreadable or non-PEM file raises DownloadError naming the variable, rather than failing later inside a fetch.

Ambient HTTP_PROXY/HTTPS_PROXY is honored without any SDK configuration: the opener is built with urllib.request.build_opener, whose default handler chain includes ProxyHandler unless explicitly replaced, and this SDK only ever swaps in its own redirect and HTTPS-only handlers — the proxy handler stays in the chain.

The sha256= off-canonical rule

sha256 on DistSource.url/.path/.data is the expected digest of the manifest body itself. It is required, fail-closed, whenever the host is not the canonical setup.ocx.sh or a mirror is in play — constructing a source without it in that situation raises DistManifestError before any network call happens. Talking to setup.ocx.sh directly is the one exception, and even there a dist/<sha256>.json URL derives its own digest automatically.

This is the SDK's trust boundary for the artifact that will eventually run as a subprocess: a mirror can relocate bytes, but it cannot make the SDK trust bytes nobody vouched for.

HostEnv tiers

HostEnv is the environment snapshot a spawned ocx (and, via bootstrap, the setup process) inherits from. Four constructors, from most to least trusting:

from ocx_sdk import HostEnv

ambient = HostEnv.ambient()          # os.environ, verbatim
minimal = HostEnv.minimal()          # PATH, HOME, TMPDIR (+ SYSTEMROOT, TEMP on Windows)
clean = HostEnv.clean()              # empty
narrowed = ambient.only("PATH", "HOME")
without_token = ambient.without("GITHUB_TOKEN")

HostEnv.clean() is hermetic and a documented footgun: a spawned tool loses PATH and fails in ways that read like anything but a missing variable. HostEnv.minimal() is the recovery — the platform-essential variables only, with everything else, including any ambient credentials, left out.

clean_child = HostEnv.clean()
assert clean_child.source == {}

recovered = HostEnv.minimal(windows=False)
assert set(recovered.source) <= {"PATH", "HOME", "TMPDIR"}

Pass a HostEnv to Ocx(host_env=...) (or bootstrap.ensure(env=...)) to change what a handle's children inherit; Ocx() defaults to HostEnv.ambient(). See Hermetic CI for the full threat-model picture this is one lever of.

What ensure() verifies

Every downloaded artifact is checked against the manifest's sha256 before it is ever executed. A mismatch raises ChecksumMismatchError and is never retried — the bytes are wrong, not late. The cache directory itself is hardened: a symlinked, foreign-owned, or group/other-writable root is refused outright, and a cache hit re-hashes by default (trust_cache=True opts out, for callers who have already verified the cache root some other way).