Skip to content
ocx
install

Module extension

The ocx module extension.

Bootstraps the pinned ocx CLI (@ocx_tool) and declares repositories that provision tools through it. The implementation is a pure function of the tags — all host detection and environment access happens inside the repository rules — so the extension is marked reproducible and stays out of MODULE.bazel.lock.

ocx = use_extension("@rules_ocx//ocx:extensions.bzl", "ocx")
ocx.download(dist_manifest, triple, version)
ocx.package(name, bins, config, index, isolated_home, no_config, package, patch_snapshot, pins,
            platform_aliases, platforms)
ocx.policy(allow_unverified, allow_yanked, sigstore_trusted_root)
ocx.project(name, bins, config, groups, isolated_home, no_config, ocx_lock, ocx_toml,
            patch_snapshot, platform)

Provisions tools through the OCX package manager.

Always creates @ocx_tool (the pinned ocx CLI). ocx.project() provisions a workspace toolchain from ocx.toml/ocx.lock; ocx.package() provisions individual OCI packages; ocx.policy() sets the build’s weakening posture (root module only). See the tag class docs for details.

TAG CLASSES

Overrides the ocx CLI bootstrap. Root module only; at most one.

Attributes

Name Description Type Mandatory Default
dist_manifest dist.json release manifest snapshot to resolve the download from. Label optional "@rules_ocx//dist:dist.json"
triple Exact release target triple, overriding host detection. String optional ""
version Exact ocx version (default: the version pinned with this rules_ocx release). Must be 0.6.1 or newer — rules_ocx passes --pinned to ocx env/exec and pins OCX_NO_CONSENT, and the floor is checked before any download. String optional ""

Provisions a single OCX package from an OCI registry.

Attributes

Name Description Type Mandatory Default
name Name of the generated repository (hub name when platforms is set). Name required
bins Lazy provisioning: names of the executables to expose. Nothing is installed at fetch time — each name becomes a launcher re-entering ocx package exec, materializing the package on first execution, and no host config tier is watched because the launcher resolves configuration live on each run. Requires a digest-pinned identity (pins or ‘@sha256:’); //:content is unavailable in lazy mode, and index is incompatible because a snapshot resolves at fetch time only. List of strings optional []
config An ocx site config.toml (mirrors, registries, [patches]) layered over the host’s discovered config — not the project ocx.toml; sets OCX_CONFIG for every invocation, overriding an ambient one, and is watched. Combine with no_config for a hermetic configuration; with bins it is copied into the repo and uploaded with every action — keep credentials out of it. Label optional None
index Committed ocx index snapshot directory (created with ocx --index <dir> index update <package>, refreshed the same way). When set, tag resolution is frozen to the snapshot — floating tags like ‘:latest’ become reproducible until the snapshot is refreshed. Label optional None
isolated_home Reach for it when this build must neither touch nor be touched by the host store: uses a repository-local ocx store instead of the shared user OCX_HOME, at the cost of a full per-repository download (nothing shared with your shell, direnv, other repos or CI) and the $OCX_HOME-rooted config tiers no longer being watched — including ocx’s ~/.ocx/sigstore/trusted-root.json rung, so with a trust policy configured trusted-root resolution falls through to the Rekor trust-root cache and then a live TUF fetch; offline it stops at the cache and fails outright, as ocx ships no embedded root. Incompatible with bins: a lazy launcher must resolve the store on whatever machine executes it. Boolean optional False
no_config Reach for it when a corporate managed config must not reach the build: ignores the host’s discovered tiers (/etc, the user config, $OCX_HOME/config.toml) and the managed-config snapshot, and opts out of the exit-78 gate a required-but-unsynced managed config raises. Sets OCX_NO_CONFIG=1 and additionally blanks an ambient OCX_CONFIG, OCX_PATCHES and OCX_PATCH_SNAPSHOT, which OCX_NO_CONFIG alone does not prune; the config and patch_snapshot attrs still apply. Boolean optional False
package Fully-qualified identifier: ‘registry/repo[:tag][@sha256:…]’. Freeze tag resolution with index, or pin per-platform manifest digests with pins. String required
patch_snapshot A committed patches.snapshot.json (ocx patch freeze, written next to ocx.lock) pinning the digests of the patch companions composed onto this environment; sets OCX_PATCH_SNAPSHOT. ocx lock --check does not cover companions, so without it they resolve at fetch time; with bins it is copied into the repo and uploaded with every action — keep credentials out of it. Label optional None
pins Per-platform manifest pins: ocx platform key -> ‘sha256:…’ digest of that platform’s manifest (as reported by ocx package install -p <platform>). The matching platform installs ‘registry/repo@<digest>’; unpinned platforms fall back to package. Dictionary: String -> String optional {}
platform_aliases Optional declared-platform -> real-platform remap. Each key must appear in platforms; its value is the canonical ocx platform actually sent to -p and used to derive the hub’s Bazel constraints. Everything Bazel-facing — repo suffix, pins lookup, config_setting, use_repo name — still keys on the declared platform; undeclared platforms are sent as-is. Example: {‘linux/arm64’: ‘linux/arm64+libc.musl’} provisions a musl arm64 build under the plain ‘linux/arm64’ target. Dictionary: String -> String optional {}
platforms ocx platform keys (‘linux/amd64’, …) to provision in addition to the host: creates ‘<name>_<slug>’ repos plus a ‘<name>’ hub whose //:content select()s by target platform. Empty = host only. List of strings optional []

Sets the build’s weakening posture — unverified installs, yanked releases, a pinned sigstore trusted root — as a function of MODULE.bazel alone. Root module only; at most one.

Attributes

Name Description Type Mandatory Default
allow_unverified When true, sets OCX_NO_VERIFY=1 for every invocation — ocx’s own documented equivalent of --no-verify, so no verify flag is ever put on an argv. When false, OCX_NO_VERIFY=0 is written anyway, so an ambient value cannot switch verification off. It cannot switch verification on: ocx attaches that only under an operator-configured [[trust.policy]], so this attr can only decline to disable it — and no_config = True prunes the discovered tiers that policy lives in, so there is then nothing to decline and verification is off either way. Boolean optional False
allow_yanked Whether resolution may fall back to a yanked release — sets OCX_ALLOW_YANKED for every invocation. Boolean optional False
sigstore_trusted_root A sigstore trusted-root.json pinned in-tree. Sets OCX_SIGSTORE_TRUSTED_ROOT for every invocation, overriding the ambient <OCX_HOME>/sigstore/trusted-root.json rung, and the file is watched. Under lazy provisioning (bins on ocx.project/ocx.package) it is copied into the repository and uploaded as an input with every action. Label optional None

Provisions the toolchain of a workspace ocx.toml + ocx.lock. Root module only.

Attributes

Name Description Type Mandatory Default
name Name of the generated repository. Name required
bins Lazy provisioning: names of the executables to expose. When set, nothing is pulled at fetch time — each name becomes a launcher re-entering ocx exec, materializing the toolchain on first execution. Actions key on the lockfile, so fully remote-cached builds download no tool content. List of strings optional []
config An ocx site config.toml (mirrors, registries, [patches]) layered over the host’s discovered config — not the project ocx.toml; sets OCX_CONFIG for every invocation, overriding an ambient one, and is watched. Combine with no_config for a hermetic configuration; with bins it is copied into the repo and uploaded with every action — keep credentials out of it. Label optional None
groups ocx.toml groups to provision (scopes both the pull and the composed environment). Reserved names: ‘default’ = the top-level [tools] table, ‘all’ = default + every group. List of strings optional []
isolated_home Reach for it when this build must neither touch nor be touched by the host store: uses a repository-local ocx store instead of the shared user OCX_HOME, at the cost of a full per-repository download (nothing shared with your shell, direnv, other repos or CI) and the $OCX_HOME-rooted config tiers no longer being watched — including ocx’s ~/.ocx/sigstore/trusted-root.json rung, so with a trust policy configured trusted-root resolution falls through to the Rekor trust-root cache and then a live TUF fetch; offline it stops at the cache and fails outright, as ocx ships no embedded root. Incompatible with bins: a lazy launcher must resolve the store on whatever machine executes it. Boolean optional False
no_config Reach for it when a corporate managed config must not reach the build: ignores the host’s discovered tiers (/etc, the user config, $OCX_HOME/config.toml) and the managed-config snapshot, and opts out of the exit-78 gate a required-but-unsynced managed config raises. Sets OCX_NO_CONFIG=1 and additionally blanks an ambient OCX_CONFIG, OCX_PATCHES and OCX_PATCH_SNAPSHOT, which OCX_NO_CONFIG alone does not prune; the config and patch_snapshot attrs still apply. Boolean optional False
ocx_lock The committed ocx.lock next to ocx_toml (watched; edits refetch). Label required
ocx_toml The project ocx.toml. Label required
patch_snapshot A committed patches.snapshot.json (ocx patch freeze, written next to ocx.lock) pinning the digests of the patch companions composed onto this environment; sets OCX_PATCH_SNAPSHOT. ocx lock --check does not cover companions, so without it they resolve at fetch time; with bins it is copied into the repo and uploaded with every action — keep credentials out of it. Label optional None
platform ocx platform key (‘linux/arm64’, …) to compose for; empty = host. A foreign platform pulls that platform’s leaves from the same ocx.lock and exposes env.bzl only (no runnable launchers). Incompatible with bins. String optional ""