Reference
Provisioning Sources
How policy chooses approved sources for runtimes and tools.
Recommended next
When to use this page
Use this page when a repo needs a runtime or tool and the organization wants to say where it may come from.
Policy can approve a feed, mirror, bucket, tap, or source URL without changing the repo contract.
- repo contracts declare what they need with
runtimes,tools, andchecks - org policy declares approved source origins and allowed versions
version_policyis the version-governance layer when you want approved versions without turning on provisioning- receipts and doctor output should explain which effective source resolved for this target
Current boundary
policies.env.values
The shipped policy env-value map. Use it to supply approved shared values for env vars the repo contract already declares. This is not the provisioning surface and it should not invent new repo requirements.
policies.provisioning
The policy surface for approved runtime and tool sources.
policies.version_policy
The policy surface for approved runtime and tool versions when governance is needed without install-source selection.
policies.adapter_bootstrap
The policy surface for getting ota's own adapter binaries onto the host or into the container.
Container execution
When ota up runs in container mode, the shipped provisioning adapters run inside that container instead of on the host, and explicit --mode container stops before any host fallback if no supported engine is available.
- Policy should use
source: <adapter>from the shipped set when it wants ota to provision through a built-in backend. sourceselects the adapter family, thensource_configcan narrow approved feed/tap/bucket/mirror details where supported.sdkmananduvare the runtime-oriented adapters in that shipped set.release-assetis the exact standalone-binary lane for tools delivered as direct release artifacts or extractable release archives rather than package-manager installs.- Chocolatey rules may add
source_config.feedfor an approved internal feed or mirror. ota doctor --jsonandota workspace doctor --jsonmay includeprovisioning_request, and workspace repo items may also includeadapter_bootstrapwhen policy declares it.
miseasdfsdkmanuvwingetchocoscoopbrewaptdnfpacmanrelease-assetProvisioning field meaning
Each policies.provisioning entry is a small execution contract and should be read left-to-right:
source (who can install), optional platforms.<os> (which host-specific override applies), then approved_versions (what versions that source may install), then optional package/source_config (how to call that source).
sourceis required and must be a shipped adapter.approved_versionsis required and checked against the contract version expression.platformsselects a whole OS-specific rule; when present for the active OS, itssource,approved_versions,package, andsource_configreplace the base rule rather than merging field-by-field.packagemaps the logical runtime/tool name to backend package identifiers where the selected source expects one.source_configis adapter-specific policy detail (for example choco feed, apt source list, winget source name, brew tap, or release-asset platform URL and archive map).- Validation is strict: any required field missing for the selected source is a hard, deterministic failure.
Release asset shape
Use source: release-asset when one tool should come from an approved direct binary artifact instead of a package manager.
This is the shipped exact-binary path for tools like Mike Farah yq.
release-assetcurrently supports tools, not runtime installation.source_config.asset_by_platformis required and must map one or more supported target keys to either direct asset URLs or objects withurlplus optional archive extraction metadata.- Supported platform keys are
linux_x86_64,linux_aarch64,macos_x86_64,macos_aarch64,windows_x86_64, andwindows_aarch64. - Asset URLs may interpolate
{version}and{name}. archive.formatcurrently supportstar_gzandzip.archive.executable_pathtells ota which extracted file becomes the final executable in the managed tool path.source_config.version_argsis optional and defaults to--version.- Ota materializes the executable into a source-managed workspace path so later task execution can use it without repo-local bootstrap glue.
policies: provisioning: yq: source: release-asset source_config: asset_by_platform: linux_x86_64: https://github.com/mikefarah/yq/releases/download/v{version}/yq_linux_amd64 linux_aarch64: https://github.com/mikefarah/yq/releases/download/v{version}/yq_linux_arm64 macos_x86_64: https://github.com/mikefarah/yq/releases/download/v{version}/yq_darwin_amd64 macos_aarch64: https://github.com/mikefarah/yq/releases/download/v{version}/yq_darwin_arm64 windows_x86_64: https://github.com/mikefarah/yq/releases/download/v{version}/yq_windows_amd64.exe version_args: - --version approved_versions: - "4.52.5" migrate: source: release-asset source_config: asset_by_platform: macos_aarch64: url: https://github.com/golang-migrate/migrate/releases/download/v{version}/migrate.darwin-arm64.tar.gz archive: format: tar_gz executable_path: migrate version_args: - -version approved_versions: - "4.19.1" Source selection is explicit
- policy can never partially combine sources; one prerequisite resolves to exactly one effective source on each target OS.
- when a contract prerequisite is inactive on an OS,
provisioningis not applied on that OS. - even with multiple candidate sources, ota must preserve a single deterministic effective choice and report it in diagnostics/receipts.
Version governance boundary
Contract says what the repo needs
Use runtimes and tools in ota.yaml to declare required versions and optional per-OS overrides with platforms.
Version policy says which versions are allowed
Use policies.version_policy when the org wants to constrain repo-declared versions without also selecting an install source.
Provisioning says where installs may come from
Use policies.provisioning only when ota should also be allowed to install or select the prerequisite through an approved source.
- a repo can be governed by
version_policywithout declaring any provisioning rules - doctor should report version-policy failures as contract-versus-policy mismatches, not as missing provisioning configuration
- use
platforms.<os>in both the contract and version policy when a requirement only applies on some operating systems
How source resolution works
Many rules overall, one source per prerequisite
A policy can approve many sources across the whole pack, but ota resolves one effective source for each runtime or tool on the current target.
Platform overrides are selection, not a race
When platforms is present, ota selects the matching OS rule. It does not try brew, apt, and choco on one machine and then pick a winner.
One OS can still support many adapters
Windows may use choco for one tool and winget for another. Linux may use apt for one tool and uv for Python. The policy chooses per prerequisite.
- the root rule is the default for that prerequisite
- a matching
platforms.<os>rule overrides the root rule for that prerequisite - after resolution, ota should have one effective source for
node, one forjava, one forpython, and so on
Version resolution rules
What policy may approve
Policy can authorize exact versions and semver ranges such as ^24, ~20.10, or >=18 <23.
What ota records
Doctor JSON records the contract requested_version, the semver normalized_requirement, the matched policy_match, and any package mapping when policy-backed provisioning applies.
When ota resolves
ota only emits resolved_version when policy provides an explicit concrete install candidate. Otherwise it keeps the original contract version as the backend input.
What ota will not invent
Range-only policy approval can authorize a request, but it does not give ota a deterministic concrete version to install.
Allowed and installablerequest: node >=18approved_versions: 22.11.0resolved_version: 22.11.0 Allowed but still blockedrequest: node >=18approved_versions: ^22result: authorized, but not deterministic enough to installPackage mapping rules
packagekeeps the contract key stable while mapping to the backend install identifier.- use
packagewhenever the selected source needs an exact package identifier; keep versions inapproved_versions, not inpackage. packageis required forapt,dnf,pacman,winget,choco, andscooppackageis optional forbrew,mise,asdf,sdkman, anduv
When ota will not provision
Rule mismatch
The policy key does not match the contract key, or the contract version does not satisfy any approved exact version or semver range.
No deterministic version
The contract uses a true range while policy authorizes only ranges, or the contract uses * while policy expects pins, so ota still has no concrete version to install.
Incomplete backend rule
The selected backend requires package, but the rule does not declare one.
Wrong target or missing backend
The rule only overrides a different OS, approves an unshipped source adapter, or depends on a manager that is missing and not allowed through policies.adapter_bootstrap.
Example policy
runtimes: java: "22"tools: maven: "3.9" pwsh: version: "7.6.0" only_on: - windowschecks: - name: java-installed kind: precondition severity: error run: java --version - name: maven-installed kind: precondition severity: error run: mvn -versionpolicies: version_policy: tools: pwsh: platforms: windows: approved_versions: - "7.6.0" provisioning: java: source: org-mirror approved_versions: - "22" maven: source: approved-manager approved_versions: - "3.9" node: source: choco package: nodejs source_config: feed: internal-choco approved_versions: - "22"What it does today
- explain which approved source resolved for a requested runtime or tool on the current target, so users see why ota used that source
- enforce
version_policyseparately from provisioning so repos can be version-governed without forcing ota-managed installs - authorize major shorthand and semver ranges without falling back to naive exact-string comparison
- surface requested versus resolved version and the matched policy rule when ota can explain that decision honestly
- reject unapproved source paths
- record the chosen source in receipts and diagnostics
- keep repo intent, org policy, and execution provenance separate
Example output
🦦 POLICY ./ota.yaml Policy source: repo policyPolicy path: ./.ota/org-policy.yaml policies: provisioning: node: source: brew approved_versions: - "22"What it is not
- not a general package manager
- not a hidden workstation manager
- not a raw download URL surface
- not a replacement for env policy