macverify 1.0.0 — macOS 11+, Python 3.9+, zero dependencies, fully offline.
A read-only, offline inventory of a Mac: what is installed, what runs at login, what listens on the network, which protections are on, where credential-shaped values sit in plain files, and how your AI assistants (Claude Code, GitHub Copilot, OpenAI Codex) are configured and what they cost to load. It writes an HTML report, a JSON dataset and a list of remediation commands, then stops.
What this is NOT
macverify is not antivirus. It is not malware detection. It is not real-time protection. It does not scan for known threats. It has no signature database, computes no file hashes, consults no reputation service, and makes no network request, so nothing it sees is ever compared against a threat feed.
It takes a point-in-time, read-only inventory of your toolchain, config hygiene and AI-assistant setup, and flags things worth reviewing yourself. A launchd job that exists, is signed and starts at login looks the same from here whether it is a printer helper or a backdoor.
Run a real scanner alongside it: Malwarebytes, KnockKnock or LuLu. Scan first — removing adware changes what this report is built from.
Installation
pipx install macverify
Or with pip, if you do not use pipx:
pip install --user macverify
No build step, no dependencies. To install nothing at all, clone and run in place:
git clone https://github.com/ShanedixonGit/macverify.git
cd macverify
python3 -m macverify
Verify it before you run it
This tool reads your machine, so do not take its word for it. From a clone, these must all return nothing:
grep -rn "shell=True\|os\.system\|os\.popen" --include='*.py' .
grep -rnE "\b(eval|exec)[[:space:]]*\(|pickle" --include='*.py' .
grep -rn "urllib\|requests\.\|http\.client\|urlopen\|httpx" --include='*.py' .
No shell execution, no dynamic evaluation, no network client. The same claims are enforced as tests, which CI re-runs on every push:
/usr/bin/python3 -m compileall -q macverify
/usr/bin/python3 -m unittest discover -s tests -t .
SECURITY.md lists each claim and how it is checked.
Usage
macverify --check # what this Mac can be audited for, then exit
macverify # the full run
--check collects nothing, and is the safe way to see what a run would cover.
A full run takes 30-60 seconds, writing to ~/.macverify/reports (0700):
-h, --help show this help message and exit
--version print the installed version and exit
--only DOMAIN run only this domain (repeatable)
--skip DOMAIN skip this domain (repeatable)
--json-only write the JSON dataset only
--html-only write the HTML report only
--out DIR output directory (default: ~/.macverify/reports)
--timeout S per-command timeout in seconds (default: 8)
--lang {en,es} report label language (default: en)
--project PATH extra project root to inspect for AI assistant config
(repeatable)
--verbose print per-domain progress to stderr
--list-domains list domain names and exit
--quick-fixes print the quick-fix plan to stdout as well as writing the
reports
--check report what this machine can be audited for, then exit
without collecting
macverify --quick-fixes
macverify --only security --only network
A run writes audit_<timestamp>.html (self-contained), audit_<timestamp>.json
(full dataset), remediation.md and ai_assistant_findings.json. See
examples/ for the JSON shape and how to pull findings out of it.
What it reads, and what it never does
Sixteen domains: toolchain, packages, shell_env, hardware, storage,
services, containers, network, security, identity, secrets,
permissions, claude_code, github_copilot, openai_codex, ai_assistants.
Missing tools are reported as unavailable, never as an error.
It never makes a network request. It never calls sudo — sudo, su, doas,
sudoedit, security and systemsetup are refused by its command runner, so
no code path can elevate. It never modifies system state; fixes are printed,
never executed. It never captures a secret value: the secrets domain records the
file, line, detector and a masked prefix, never the value. It never reads AI
session transcripts, only their file metadata.
Reports are sensitive: an audit_*.json names your host, user, applications,
SSH key paths, privacy grants and anything credential-shaped. Read one before
you send it anywhere.
Let an AI assistant triage the report
SKILL.md is a self-contained skill that runs the audit, reads the
dataset and returns a short ranked list of fixes rather than eighty raw
findings. For Claude Code, copy it to ~/.claude/skills/macverify-review/; for
Codex, append it to your AGENTS.md. It never runs a destructive command
without asking, and never runs sudo on your behalf.
Requirements
macOS 11+ and Python 3.9+; every Mac since macOS 12.3 ships a suitable
python3. No third-party packages, at install time or runtime.
License
MIT. See LICENSE. Also CONTRIBUTING.md, CHANGELOG.md, SECURITY.md and design_notes.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file macverify-1.0.0.tar.gz.
File metadata
- Download URL: macverify-1.0.0.tar.gz
- Upload date:
- Size: 121.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aeeb4058f787c546cd21cce4e567a98deee995ab719b6914b4d96c151052e965
|
|
| MD5 |
140e5961b6179bc614e075fc1ac47037
|
|
| BLAKE2b-256 |
1c257195983f317691f513bcba082b847f631fb1613f3175310564dc02e68311
|
Provenance
The following attestation bundles were made for macverify-1.0.0.tar.gz:
Publisher:
publish.yml on ShanedixonGit/macverify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
macverify-1.0.0.tar.gz -
Subject digest:
aeeb4058f787c546cd21cce4e567a98deee995ab719b6914b4d96c151052e965 - Sigstore transparency entry: 2680524551
- Sigstore integration time:
-
Permalink:
ShanedixonGit/macverify@f363a3b14f58faef57a0f8eaff90e94fd0996127 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/ShanedixonGit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f363a3b14f58faef57a0f8eaff90e94fd0996127 -
Trigger Event:
release
-
Statement type:
File details
Details for the file macverify-1.0.0-py3-none-any.whl.
File metadata
- Download URL: macverify-1.0.0-py3-none-any.whl
- Upload date:
- Size: 126.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98c7450f3e2787d29525f0d16e553ee1b55e01fea0c35110dd630ed497d55c77
|
|
| MD5 |
0416944bf5a7ff36a243316e0bdd4035
|
|
| BLAKE2b-256 |
72ec3d81fb1410568d165a397a58e6c2a65ed60e640010a62c23c1953ec2395f
|
Provenance
The following attestation bundles were made for macverify-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on ShanedixonGit/macverify
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
macverify-1.0.0-py3-none-any.whl -
Subject digest:
98c7450f3e2787d29525f0d16e553ee1b55e01fea0c35110dd630ed497d55c77 - Sigstore transparency entry: 2680524571
- Sigstore integration time:
-
Permalink:
ShanedixonGit/macverify@f363a3b14f58faef57a0f8eaff90e94fd0996127 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/ShanedixonGit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f363a3b14f58faef57a0f8eaff90e94fd0996127 -
Trigger Event:
release
-
Statement type: