Manual

The screening proxy

imix proxy serve stands between ansible-galaxy, uv and pip and the real Galaxy and PyPI. It caches what they download and serves only what a list of rules allows.

imix proxy serve stands between ansible-galaxy, uv and pip and the real Galaxy and PyPI. It caches what they download and serves only what a list of rules allows: collections and roles (Galaxy’s v3 and v1 APIs) and pip packages (PyPI’s simple index). Refused versions are left out of version lists, a refused download is a 403, and every refusal is logged (proxy denials). When upstream can’t be reached, the proxy answers from what it kept.

Lists of rules#

Rules come in named lists, and a client picks one by URL: http://proxy:8470/web/. Without a list, a client gets default, which is created empty the first time it’s needed. An empty list denies everything. A list is text, one rule per line, and the first line that matches decides, as in ipfw:

# web servers
allow collection nginxinc.nginx_core <0.8
allow collection community.*        # nginx_core needs community.crypto
deny any *evil*
allow pip requests >=2.30
default allow role                  # without it, a kind is denied

Edit a list in $EDITOR with imix proxy -l web edit, which saves only if every line reads. Tools can work by line number instead:

CommandWhat it does
showthe list (--plain for the raw text)
insert [--at N] LINE...add rules
delete N...remove rules by number
replace N LINEchange one
flush, load FILEempty the list, or read it from a file
check KIND NAME [VERSION]report which line decides
create, drop, listsmanage lists
cachelist the cached files
clean --older-than DAYS | --denied | --allremove them; --denied removes only files that no list allows any more
denialswhat was refused, and the name the client asked for

Fetching through it#

The lists live in ~/.instamix/proxy.db (SQLite) and the files in ~/.cache/instamix/proxy. Set INSTAMIX_PROXY=http://proxy:8470, and env, install and the language server’s installs fetch through it. They use the list the script names with proxy_list("web"), or INSTAMIX_PROXY_LIST at run time, which takes precedence. The proxy.url and proxy.list settings do the same from the config files, below the environment and the script’s own list.

Pinning a script to reviewed versions#

A name that is no list can be mapped to one. That is how a script pins its downloads to reviewed versions: proxy_list(script_sha256()) asks for the list named after the script’s own SHA-256, which gets default (nothing) until you approve that version:

$ imix proxy map $(sha256sum site.py | cut -c1-64) web

Every edit makes a new hash, so develop with INSTAMIX_PROXY_LIST=web, and map each version you approve. maps lists the mappings, unmap removes one, and denials shows the name a refused client asked for (<hash> -> default).

A blacklist from OSV#

tools/osv_blacklist.py keeps a blacklist from OSV in a list: deny rules for malicious PyPI packages (the OpenSSF reports) and, with --vulnerable, for the versions of known vulnerabilities. Run it again to update (from cron, say); it rewrites only its own # BEGIN osv-blacklist … # END osv-blacklist block, which it puts first in the list, and each rule names its advisory. Galaxy has no such public source.

$ tools/osv_blacklist.py -l default --vulnerable
list default: 23200 rules from 11750 malicious packages and 13404 vulnerabilities; 3 unreadable versions left out

--allow-rest ends the list with allow any * (once), for a blacklist rather than a whitelist. tools/install_proxy_units.sh [-l LIST] runs the proxy as a systemd user service, and that update every 6 hours from a timer (--print shows the units, --uninstall removes them).

The source of this page

    Type to search. ↑ ↓ to move, enter to open.