Getting started¶
Start from a policy the workspace already passes, commit it, and tighten it one change at a time. Each change is then a reviewed pull request that says exactly what is no longer allowed.
1. Write a starting policy¶
init writes pixi-policy.toml beside pixi.toml from what the workspace uses today: the channels and indexes its
packages come from, every license in pixi.lock, and its platforms. It never overwrites an existing file; pass
--policy <file> to write somewhere else.
# pixi-policy.toml, written by `pixi policy init` from what this workspace uses today.
[sources]
allowed-channels = ["conda-forge"]
allowed-indexes = ["https://pypi.org/simple"]
allow-git = false
allow-url = false
allow-path = false
[bans]
deny = [] # e.g. { name = "pycrypto", reason = "unmaintained", use-instead = "pycryptodome" }
[licenses]
# Every license the conda packages declare today (shortened here). pixi.lock records no PyPI licenses.
allow = ["Apache-2.0", "BSD-3-Clause", "MIT", "PSF-2.0"]
unknown = "warn"
[manifest]
required-platforms = ["linux-64", "osx-arm64", "win-64"]
[lock] # present, complete and in-sync are all on
2. Check it¶
warning[licenses.unknown] watchdog 6.0.0: has no license in pixi.lock (it never records PyPI licenses)
--> pixi.lock: environment "docs", win-64
= help: PyPI licenses are read from the package's files in pixi-policy 0.2.0; until then set [licenses] unknown = "allow" to stop these
0 errors, 155 warnings, 0 waived in 1644 packages across 30 environment-platform pairs
Each finding names its rule, the package, where it was found and how to fix it. Errors fail the check (exit code 1);
warnings are reported and do not. Commit pixi-policy.toml once the check passes.
3. Tighten it¶
Add what the workspace must never contain, one rule at a time:
[bans]
deny = [
{ name = "pycrypto", reason = "unmaintained", use-instead = "pycryptodome" },
{ name = "openssl", version = "<3", reason = "EOL" },
]
[licenses]
deny = ["GPL-3.0-*", "AGPL-*"]
pixi policy explain <RULE> says what a rule checks, gives an example and lists each of its keys with the values
it takes and its default:
4. Waive what has to stay, with an end date¶
When a finding cannot be fixed yet, waive that one finding with a reason and an expires date. It is reported as
waived until then and fails again the day after.
[[waivers]]
rule = "licenses.deny"
package = "readline"
reason = "dev only; LEGAL-1234"
expires = 2027-03-31
See Waivers for how a waiver matches a finding.
5. Run it in CI¶
Run the same check on every pull request, so a change to pixi.toml or pixi.lock that breaks the policy fails
before it merges. In development and CI has the setup.