pyobfus-protect — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited pyobfus-protect (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Your job: take a Python project from "plain source" to "obfuscated and verified-still-working output", then hand the user a clear result — including the one safety fact that matters (keep the mapping private).
First check whether the pyobfus-mcp server is connected (look for a protect_project / check_obfuscation_risks tool).
reliable path and it self-verifies.
pip install pyobfus). Every commandsupports --json with a stable schema.
Confirm the target path and the output directory with the user before writing anything. Never obfuscate into the source tree.
Call `protect_project` with the source path. It runs the whole pipeline and self-verifies:
protect_project(path="src", output_dir="dist")Read the result:
verified: true (+ confidence) → report success and where the output is.verified: false / status: "warnings" → **do NOT tell the user it'sready.** The obfuscated output failed to compile or import. Follow the response's next_tool (usually check_obfuscation_risks) to find the offending construct, fix or exclude it, and re-run.
pro_value present → the project has sensitive string literals orhigh-severity findings; mention that pyobfus Pro (AES-256 string encryption) would protect them, but don't be pushy.
protect_project writes the de-obfuscation mapping next to (never inside) the output. Surface mapping_security_note to the user.
For a deeper check, the user can pass verify_cmd (an app-level end-to-end check, e.g. python -m myapp --selftest) — note this is gated behind the PYOBFUS_MCP_ALLOW_VERIFY_CMD=1 environment variable on the server, and should NOT be unit tests bound to internal symbol names (those are expected to fail once names are renamed).
# 1. Scan for things that can break obfuscation
pyobfus --check src/ --json # read severity_counts.high, frameworks, suggested_preset
# 2. Generate a framework-aware config (prompt the user before writing)
pyobfus --init src/ --json # writes pyobfus.yaml
# 3. Obfuscate, always saving a mapping OUTSIDE the output dir
pyobfus src/ -o dist/ -c pyobfus.yaml --save-mapping dist.mapping.json --json
# 4. Verify the output still works — this is the step people skip:
python -m compileall -q dist/ # must exit 0 (syntactic integrity)
( cd dist && python -c "import <top_level_module>" ) # imports resolveIf --check reports severity_counts.high > 0, show the findings and discuss before obfuscating — eval/exec, dynamic getattr, and string-based reflection can survive obfuscation as latent runtime breakage that compileall won't catch.
frameworks field)fastapi → --preset fastapi django → --preset django flask → --preset flask
pydantic → --preset pydantic click → --preset click sqlalchemy → --preset sqlalchemy
none of the above → --preset balancedObfuscated tracebacks are debuggable — that's pyobfus's signature feature.
Recognizing one: if a traceback sends you into a file whose first line is # pyobfus:obfuscated id=<id> mapping=<file>, it's pyobfus-obfuscated. Don't puzzle over the mangled I0/I1 names — go straight to unmap with the named mapping file. (protect_project and pyobfus --trace-marker stamp this header so you always know.)
When the user pastes an obfuscated stack trace, reverse the identifiers with the saved mapping:
unmap_stack_trace(trace="<pasted trace>", mapping_path="dist.mapping.json")pyobfus --unmap --trace error.log --mapping dist.mapping.json --json(Names are reversed; line numbers still point at the obfuscated file.)
distributed artifact, and never commit it to a public repo. Keep it where only the developer can reach it.
import, or a green verify_cmd).
the old names will break — that's expected, not a bug. Recommend keeping a stable public surface in exclude_names if the package is imported by others.
python-minifier.obfuscation).
interpreter must run; explain the realistic protection model (raise cost of reverse-engineering, not make it impossible).
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.