Skip to content
PyArmorDEMO

Chapter 11

Security Reality

⏱ 15 minutes · No new tools. You will put everything you saw together and leave with an accurate model of what obfuscation protects, and what it does not.

Four things obfuscation is not

Why not
Obfuscation ≠ encryptionEncryption keeps data from people without the key. Protected code must run, so the means to decode it ships with it, inside the runtime. Everyone who can run your app can, in principle, decode it.
Obfuscation ≠ DRMExpiry and device binding are enforced by the runtime, on a machine the user controls. They stop casual misuse and honest mistakes, not a determined attacker who controls the clock and the hardware.
Obfuscation ≠ absolute secrecyIt raises the effort needed to understand and reuse your logic. Effort is a cost, not a wall: enough time and skill get through.
Obfuscation ≠ a secure serverIt does nothing for open ports, weak passwords, unpatched dependencies, leaked keys, or who can SSH into the machine.

Back to the three scenarios, with evidence

Scenario A: source availableScenario B: protected artifactScenario C: attacker controls execution
Read the logic from filestrivial (ch 02)not found as text (ch 05, 07)not from files...
Read constants and namestrivialnot from the filesyes, from the running process (ch 07, runtime_view.py)
Learn behaviour from inputs/outputsyesyesyes
Read secrets you passed inyesyesyes
Copy-paste your code into a producttrivialhardhard, but they can run your build
Severity🔴 nothing protected🟡 logic protected against casual and moderate effort🔴 obfuscation is not the boundary

In scenario C, you already saw it yourself in this workshop:

  • docker compose exec api sh gave you a shell inside the running app's container (ch 09).
  • runtime_view.py read every weight and threshold from memory with Python's ordinary introspection (ch 07). Private mode (--private) blocks that particular route, but not the ones below.

What an attacker with access can still learn

Here is what remains observable, so you know what to protect by other means. Obfuscation changes none of these rows.

ChannelWhat it revealsWhat actually protects it
Inputs and outputsCall /api/analyze enough times and the scoring curve can be approximated without any code at all.Authentication, rate limiting, monitoring for scraping patterns
LogsWhatever you log. This app logs outcomes, never inputs, on purpose (ch 03).Log less; restrict who reads logs; never log secrets or personal data
Runtime behaviourTiming, errors and which endpoints exist (/docs publishes the whole API schema).Generic error messages; disable /docs in production if the API is private
FilesystemEvery file the app can read: configuration, certificates, data.Least privilege; mount secrets read-only and only where needed
Environment variablesVisible to anyone with a shell in the container, and via docker inspect.A secrets manager; short-lived credentials
DependenciesFastAPI, pydantic and uvicorn are not obfuscated; neither is their behaviour.Keep them patched; scan them (ch 12)
Process accessA process's memory holds decoded code objects, constants and every secret it uses.Keep attackers off the host: access control, isolation, patching
Memory and runtime analysisDebuggers and memory inspection see what the CPU sees. PyArmor's own FAQ says it is "not good at memory protection and anti-debug".The same: protect the environment, not just the code
Container accessImage layers, ENV values, and every file in the image (ch 09).Private registries, signed images, no secrets in images

What the vendor claims, and what to take from it

PyArmor's FAQ states that obfuscated scripts "can't be restored by any way". Read that narrowly: it is about recovering your original source text from the files, which this workshop did not contradict. It is not a claim that your logic, data or secrets stay hidden from someone who runs the code, and the same FAQ notes the limits on memory protection and anti-debugging.

So when is PyArmor worth it?

Good fits (scenario B, where obfuscation is a sensible layer):

  • Software delivered to customers who run it on their machines: on-premises products, desktop tools, SDKs with commercial logic
  • Containers shipped to partners, where you want to discourage casual reading and copying
  • Time-limited trial or evaluation builds (-e), and builds tied to known hardware (-b)

Poor fits (where it adds little):

  • Code that only runs on your own servers. Nobody receives the code, so it is the server's access control that matters, not obfuscation.
  • Protecting secrets. Use a secrets manager.
  • Anything where losing the logic would be catastrophic. Keep that logic on a server you control and expose it as an API, so the code never leaves your hands.