Skip to main content

sficheck

sficheck (SFI-check) finds proprietary software at every level, kernel drivers, the hypervisor, the BIOS/UEFI and devices that need nonfree drivers or firmware.

Origins

sficheck is a fork of absolutely-proprietary by Vasilis Mavromatis and contributors. The original was a single script for Arch-based distros: it checked pacman packages against Parabola's blacklists and printed your Stallman Freedom Index. This fork adds:

  • system package managers beyond pacman (dpkg, rpm, nix, flatpak, snap, brew) and 28 language package managers
  • the kernel, hypervisor, firmware and hardware scans (rings 0 to -3), each selectable on its own
  • opt-in browser and Android scans, anti-feature tags, and --in-use
  • install-time warnings for pacman, apt and dnf
  • the classification chain: user blacklists, ecosystem authorities, curated lists, SPDX parsing and online license lookups
  • JSON output, a config file, caching, and a test suite with Hypothesis property tests

Install

uv tool install sficheck   # or: pipx install sficheck
sficheck

Python 3.11 or newer. Dependencies: msgspec (list files), license-expression (licenses), httpx2 (online lookups), psutil (--in-use), and on Linux pyudev (devices; needs libudev).

  • From a clone, python -m sficheck.
  • On Arch, build the PKGBUILD in this repo with makepkg -si.

Usage

sficheck                          # scan every layer, list what's nonfree
sficheck --full                   # also list semifree and uses-nonfree findings
sficheck --firmware               # scan one layer only
sficheck --in-use                 # only what is running right now
sficheck --sort ring              # deepest findings first
sficheck --browser                # add browser extensions and DRM (opt-in)
sficheck --android                # rate a phone connected over adb (opt-in)
sficheck --format json | jq       # machine-readable report
sficheck --list-sources           # what sficheck can scan on this machine

Output

=============================================
5 ABSOLUTELY PROPRIETARY PACKAGES INSTALLED
=============================================

Your system is infected with 5 proprietary packages out of 1311 found (8 unknown) across 11 sources.
Your Stallman Freedom Index is 99.62
By protection ring: 3 user: 5

+--------+----------+-------------+---------+---------------+
| Source | Packages | Proprietary | Unknown | Freedom index |
+--------+----------+-------------+---------+---------------+
| dpkg   | 1081     | 5           | 0       | 99.54         |
| pip    | 131      | 0           | 4       | 100.00        |
| gem    | 95       | 0           | 2       | 100.00        |
...
+--------+-------+------------+---------+--------+--------------------+--------------------------------------------+
| Source | Name  | Version    | Status  | Ring   | Libre alternatives | Description                                |
+--------+-------+------------+---------+--------+--------------------+--------------------------------------------+
| dpkg   | nikto | 1:2.1.5-3  | nonfree | 3 user |                    | in Debian's non-free archive area          |
+--------+-------+------------+---------+--------+--------------------+--------------------------------------------+

Other formats: --format markdown, csv or json, and -o FILE writes to a file.

System & Language package managers (--software)

  • pacman — Arch and derivatives, checked against Parabola's blacklist and aur-blacklist. --include-privacy adds your-privacy-blacklist.txt. Packages that aren't blacklisted count as free.
  • dpkg — Debian, Ubuntu, Mint… The archive area decides: non-free, non-free-firmware, restricted and multiverse are nonfree, contrib is uses-nonfree. Third-party packages (Chrome, VS Code, Teams…) come from the curated list.
  • rpm — Fedora, RHEL, openSUSE, Mageia… The License tag from the rpm database, as SPDX on current Fedora or as older Callaway names like GPLv2+ and ASL 2.0. Firmware tagged LicenseRef-Fedora-Firmware or Redistributable, no modification permitted is nonfree.
  • nix — nix-env, nix profile and NixOS systemPackages, using nixpkgs meta.license.free.
  • Python — pip (default interpreter), uv tools, pipx
  • JavaScript/TypeScript — npm, pnpm, yarn, bun, deno
  • JVM — sdkman (Oracle JDK and GraalVM builds are nonfree), coursier, and the opt-in caches maven and gradle
  • .NET — dotnet global tools, and the opt-in nuget cache
  • C/C++ — vcpkg, conan
  • Others — Rust cargo · Go go · Ruby gem · PHP composer · Perl cpan · Lua luarocks · R r · Julia julia · Haskell ghc-pkg · Elixir mix · Dart/Flutter pub · Swift mint

Opt-in sources only run when named, e.g. --sources maven,gradle.

Browser (--browser, opt-in)

  • browser — extensions you installed in Firefox and Chromium-based browsers (Chrome, Chromium, Brave, Edge, Vivaldi), and the Widevine DRM module those browsers download to play protected video. Widevine is nonfree and tagged drm.
  • It reads only these local files, never history, cookies or passwords:
    • Firefox: extensions.json and the gmp-widevinecdm folder in each profile, under ~/.mozilla/firefox (plus its flatpak and snap locations).
    • Chromium-based: each extension's manifest.json (and its _locales folder for the display name) under <profile>/Extensions, and the WidevineCdm folder, under ~/.config/<browser>.
  • Firefox's built-in add-ons, themes, dictionaries and language packs are skipped.
  • With --online-licenses, Firefox extensions are looked up on addons.mozilla.org, which publishes the license each developer declares; a custom license stays unknown. Chrome Web Store doesn't publish licenses, so Chromium extensions rely on the curated browser.json and are unknown otherwise.

How a package is classified

  • nonfree — blatantly nonfree software.
  • semifree — mostly free, but contains some nonfree software.
  • uses-nonfree — free, but depends on, recommends or integrates with nonfree software or services.
  • free — free software.
  • unknown — no license information could be found.

Protection rings

Proprietary findings also carry the CPU protection ring the software runs in. A proprietary calendar can only see what you give it. A kernel anticheat sees everything the OS does, and the Intel ME keeps running while the machine is off.

Ring Runs as Examples
-3 ME a coprocessor (ME = Management Engine) or the CPU itself, below the OS Intel ME, AMD PSP, CPU microcode
-2 firmware system firmware BIOS/UEFI
-1 hypervisor underneath every OS on the machine Hyper-V, VMware, Parallels, the VirtualBox Extension Pack
0 kernel the kernel Riot Vanguard, Easy Anti-Cheat, BattlEye, FACEIT AC, nvidia
3 user an ordinary program everything else

Only what runs now: --in-use

--in-use keeps only what is in use right now

  • Running programs come from the process list (psutil).
  • Kernel drivers, firmware and devices always count as in use.

Warnings at install time

sudo sficheck --install-hook pacman (or apt, or dnf) adds a hook that warns before the package manager installs something proprietary:

sficheck: unrar is nonfree (proprietary license); free alternatives: unar

The hook only warns. It never blocks an install, even when sficheck itself is broken or has been uninstalled. It checks new installs only, never upgrades,

The package manager runs the hook as root, so sficheck must be installed where only root can change it: your distro's package, the PKGBUILD, or sudo pipx install --global. --install-hook refuses a copy under your home directory, since anyone who could edit it could then run code as root. The hook runs sficheck by the absolute path it was installed from, so reinstall the hook if you move sficheck.

Package manager File written How it's called
pacman /etc/pacman.d/hooks/sficheck.hook a PreTransaction hook for Operation = Install, given the package names
apt /etc/apt/apt.conf.d/50sficheck DPkg::Pre-Install-Pkgs with protocol version 2, which tells new installs from upgrades; each .deb's section is read with dpkg-deb
dnf5 /etc/dnf/libdnf5-plugins/actions.d/sficheck.actions a pre_transaction action, run per new package with its name and License tag; needs libdnf5-plugin-actions

Options

what to scan (every layer except the opt-in ones by default)
  --software                 system and language package managers (ring 3)
  --kernel                   kernel modules and third-party drivers (ring 0)
  --hypervisors              the hypervisor this OS runs on, and installed ones (ring -1)
  --firmware                 BIOS/UEFI (ring -2), Intel ME / AMD PSP and microcode (ring -3)
  --hardware                 devices that need a nonfree driver or firmware blobs
  --browser                  browser extensions and DRM modules (opt-in)
  --android                  a phone's apps over adb (opt-in; scored separately)
  --kind system|lang         package managers of this kind only (repeatable)
  --sources A,B / --skip A,B name sources / skip sources
  --list-sources             show every source and whether it's available, then exit

what to show
  --status S                 nonfree|semifree|uses-nonfree|free|unknown|all (repeatable; default: nonfree)
  -f, --full                 nonfree, semifree and uses-nonfree
  --all                      every package, free ones too
  --show-unknown             also packages that couldn't be classified
  --unknown-as-nonfree       count unknown packages against the index
  --in-use                   only what is in use now
  --max-ring N               only ring N or deeper (-3 … 3)
  --sort source|name|status|ring|alternatives   -s (status)  -a (alternatives)  -r (reverse)

output
  --format table|markdown|json|csv   -o, --output FILE   --color auto|always|never
  -q, --quiet   -v, --verbose   --exit-code (exit 1 if anything proprietary is found)

lists and lookups
  --blacklist PATH|https-URL (repeatable)   --ignore PKG (repeatable)   --no-bundled   --include-privacy
  --online-licenses   --offline   --refresh   --cache-ttl HOURS (default 24)   --jobs N (default 8)

install-time hooks (Linux, root)
  --install-hook pacman|apt|dnf   --remove-hook pacman|apt|dnf

Configuration and cache

Defaults for any option can live in ~/.config/sficheck/config.json

{
  "full": true,
  "ignore": ["steam"],
  "blacklist": ["~/my-blacklist.txt"],
  "skip": ["gradle"]
}

User blacklists use either Parabola's text format (name:replacement:ref:id:[status] description) or the bundled JSON format. They're read from a local path or an https:// URL.

Downloads (Parabola lists, registry lookups) are cached for 24 hours in ~/.cache/sficheck. If the network fails, a stale cache is used. --offline never touches the network.

Development

With uv and make:

make sync      # dev environment from uv.lock
make format    # sort imports, reformat
make lint      # ruff, mypy, complexipy, vulture, deptry, zizmor
make test      # pytest, including Hypothesis property tests
make audit     # pip-audit the locked dependencies
make install   # install the command for your user (uv tool install)
make schema    # regenerate the JSON Schemas in docs/
make clean     # caches and build output
uv run tox -p  # the tests on every supported Python
uv run python scripts/check_lists.py --online   # after editing the lists

License

GPL-3.0-or-later, the same as upstream. See LICENSE and NOTICE.

Metadata

Release files for sficheck 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sficheck 0.2.0
File Size Uploaded
sficheck-0.2.0.tar.gz 113.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sficheck 0.2.0
File Interpreter ABI Platform
sficheck-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 216.3 kB

Release files / sficheck-0.2.0.tar.gz

Download URL sficheck-0.2.0.tar.gz
Size 113.8 kB
Tags Source
SHA-256 checksum
How to use checksums
6502a0a87d7eb73622f94fce8c06bf52897e5e23ebe3b71bd42075fa01c6cfe0
BLAKE2b-256 checksum
How to use checksums
350d982fdefe22b95dd102647f533f9ece85604027b7e3341d8dfbf1a0b7f850
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / sficheck-0.2.0-py3-none-any.whl

Download URL sficheck-0.2.0-py3-none-any.whl
Size 102.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bc0c2c54b6037c8db5566f9e83f8d477a277e91a88cca9e5eb8c197a01ed58f9
BLAKE2b-256 checksum
How to use checksums
6d8a32240d57cbb5fa0879fbd9a105ff6c1e143fe619a36401343d08e66ce3d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page