help Intermediate

Security and Source Privacy

What pyvorin-native 1.0.9 sends off your machine, what never leaves it, the pyvorin-thin warning, and the set_privacy opt-out — verified on the installed build.

Published Aug 3, 2026

Two kinds of data ever leave a machine running pyvorin-native 1.0.9: your licence key bound to a device fingerprint, and a 1%-sampled stream of event metadata. Your source code is not among them, and the reason is structural — the compile path contains no network code at all — rather than a promise about behaviour. This page is the definitive statement of what the package does and does not send, verified against the installed build by source review and by capturing every outbound request at runtime.

It also carries one warning that has to be stated plainly rather than buried in a footnote. A sibling package, pyvorin-thin, submits source code to a server-side compile endpoint. Everything on this page is scoped to pyvorin-native. If your environment has both packages installed, the import statement in your entrypoint is the privacy boundary.

What leaves the machine

The complete outbound surface of pyvorin-native 1.0.9 fits in one short table. This was established two ways: a full URL string sweep of every installed binary, and a runtime capture in which the verifier intercepted the HTTP layer, exercised activation and compilation, and recorded every attempted request. Both methods agree.

EndpointWhen calledPayload
POST https://api.pyvorin.com/api/v1/licenses/checkpyvorin activate, plus periodic revalidation from the hard licence gate{"license_key": …, "device_fingerprint": …} — exactly two fields
POST https://api.pyvorin.com/v1/usage/events/bulkTelemetry flush: 50 events, 300 seconds, or process exitEvent metadata envelope — contents in the table below
POST …/api/auth/token / …/revokeOnly login / logout in the product CLIAccount credentials / token

Three observations that security reviewers usually ask about. There is no update-check call anywhere in the package — nothing phones home to ask whether a newer version exists, so there is no unaccounted background channel to explain away. The client contacts api.pyvorin.com only; the license.pyvorin.com and telemetry.pyvorin.com hosts exist on the infrastructure but are never called by the 1.0.9 native client. And the licence payload carries no filenames, no environment details, no host identifiers beyond the fingerprint — the captured body is one JSON object with two fields, and that is the whole of it.

The device fingerprint deserves a precise description because it is the most privacy-relevant single field in the product. It is computed locally as SHA-256 over hostname:username:/etc/machine-id, truncated to 32 hexadecimal characters, and it exists to bind a licence lease to one machine so the lease cannot be replayed onto a second host. A hash of those inputs is pseudonymous rather than anonymous — a hostname like jsmith-laptop does not resist re-identification by anyone who knows your naming scheme — and the honest position is to treat it as personal data and record it in your processing inventory. It flows only in the licence-check payload and sits in your local licence file at ~/.pyvorin/license.json, mode 0600.

What never leaves: your source

The guarantee that matters most is also the most verifiable. Compilation in pyvorin-native is local and in-process: the compiler lowers Python to LLVM IR through llvmlite and links against runtime libraries that ship inside the wheel. A search of the compiler modules for any HTTP client — urllib, urlopen, requests — finds nothing, and nothing in the installed binaries contradicts that. There is no compile server, no queue, no secondary download stage that could carry your functions away as a side effect.

Consequences follow from that structure. Compilation latency is milliseconds rather than network round-trips. The compiled artefacts land in a disk cache inside the install tree at <site-packages>/.pyvorin_cache/disk_compile, keyed by a SHA-256 of the source, the function name, the options and toolchain timestamps — a derived copy of your code that stays on your disk, checksum-validated on read, bounded by LRU eviction at 500 entries. And confidentiality of source is a property of the code paths, not of a policy that could be revoked or misconfigured. No setting transmits source on the native path, because there is no code path that could.

One correction belongs here explicitly, because earlier documentation got it wrong. A previous draft of this page claimed the product sent a hash of your source to a compile API and offered raw-source upload behind an opt-in flag. Neither is true of pyvorin-native: no source hash is transmitted, and no opt-in exists, because there is nothing to opt into. The claim described a different architecture that does not exist in this package. If you have a printed copy of the old text, dispose of it.

The pyvorin-thin warning

pyvorin-thin is a separate package with a different architecture: it submits source to POST /v1/thin/compile on api.pyvorin.com for server-side compilation. That is a legitimate design with legitimate uses — minimal local footprint, consistent toolchain — but it means any sentence of the form "Pyvorin never sends your code anywhere" is false as scoped across the product family. The true, verifiable statement is the narrower one: pyvorin-native's compile path has zero network code, and no source code leaves the machine running it.

If your GDPR position, your customer contract or your security review depends on source staying on-premises, pin the package name in your requirements file to pyvorin-native and audit imports on shared environments. On a host with both packages installed, whichever one your code imports determines which privacy model you actually have.

Telemetry contents, field by field

"We collect telemetry" spans everything from a heartbeat to a keylogger, so here is the exact payload class, quoted from a captured batch:

FieldContentSource of truth
vEnvelope version string, "1.0"Captured wire format
sessionFirst 16 characters of a UUID, regenerated per processCorrelates events within one run only
privacyThe active privacy level: standard, minimal or disabledServer-side visibility of your setting
abuse_scoreInteger computed locally from counters: validation failures above 10, tamper events, compile counts above 100,000Anti-fraud signal, not content
events[]Each event: t (timestamp), e (event name), p (parameters such as {"time_ms": 1.0}), s (session id)Metadata only

The event vocabulary is fixed: compile, execute and feature_used are sampled at 1%, while activation, validation_failed, tamper_detected and revoked are always recorded. What telemetry never contains: source code, function names from your codebase, file paths, argument values, return values, environment variables, stack traces. The transport is batched and fire-and-forget — a ring buffer capped at 1,000 events, flushed at 50 events, 300 seconds or process exit, over a 5-second timeout, failures silently ignored, no background thread.

The only opt-out: set_privacy

Three privacy levels exist: standard (the default), minimal (security events only) and disabled (nothing recorded). The control is an in-process API call and nothing else:

from pyvorin import _telemetry

_telemetry.set_privacy("minimal")   # security events only
_telemetry.set_privacy("disabled")  # nothing recorded
print(_telemetry.get_privacy())

There is no environment variable and no config-file switch for opting out, and no pyvorin telemetry off command — earlier drafts of this page and of the telemetry page said otherwise, and they were wrong on every count. PYVORIN_TELEMETRY_URL exists, but it overrides the destination, not the collection. If policy requires telemetry off fleet-wide, the supported route is a set_privacy call at application start-up, reviewed in code like any other security-relevant line; blocking the endpoint at your egress proxy is the network backstop. Call it early, before any other pyvorin import does work.

An engineering judgement call sits inside that advice. Because the opt-out is per-process and code-level, a library author cannot set it on behalf of an application without overriding the end user's choice; the defensible pattern is to set it in your application's entrypoint and leave libraries alone. Teams that have tried to be helpful inside libraries have produced the worst of both worlds — telemetry off for some users, silently re-enabled by import order for others.

Verifying these claims yourself

Nothing on this page requires our cooperation to check. The two environment overrides redirect outbound traffic to any URL you control, so pointing them at a local sink shows you the exact payload bytes your installation would send:

# Capture exactly what activation would send — start a sink on :8080 first
PYVORIN_LICENSE_URL=http://localhost:8080 pyvorin activate PYVR-TEST-KEY-0000

# Inspect local licence state — reads the file, no network call
pyvorin status
pyvorin check

The licence body you will capture is {"license_key":"PYVR-TEST-KEY-0000","device_fingerprint":"9ae48003e4f366edcd233d987aa7c91a"} — two fields, nothing more, with a 30-second timeout. The telemetry envelope has the shape quoted in the table above. Running the same capture on your own build is the exercise your assessor will want to perform, and it takes minutes with a logging proxy or a netcat listener.

Where to go next

Last reviewed 3 August 2026 against pyvorin-native 1.0.9 installed at /root/pvfinal. Payloads and endpoints were captured by intercepting the HTTP layer at runtime; the absence of network code in the compile path was established by source review corroborated by a binary string sweep. pyvorin-thin is out of scope except as a named warning, because its source-submission posture differs from everything verified here.